diff --git a/data/JetBrains_kotlin_1000.finetuned_pred.csv b/data/JetBrains_kotlin_1000.finetuned_pred.csv index a68e05c..cf5db04 100644 --- a/data/JetBrains_kotlin_1000.finetuned_pred.csv +++ b/data/JetBrains_kotlin_1000.finetuned_pred.csv @@ -1,10 +1,16 @@ ,code,target,prediction 0,"@@ -0,0 +1 @@ -+org.jetbrains.kotlin.idea.inspections.RemoveRedundantBackticksInspection",Please add a test to verify that the quickfix is not offered when an actual keyword is in backticks.,Why is this needed? ++// INSPECTION_CLASS: org.jetbrains.kotlin.idea.inspections.ForEachParameterNotUsed","Here you have to add `// WITH_RUNTIME` line, otherwise all your tests fail. In the future, please re-run your own tests before re-submitting PR.","Would it make sense to move this to somewhere more common, e.g. `org.jetbrains.idea.inspections.ForEachParameterNotUsed`?" 1,"@@ -0,0 +1 @@ ++class Foo (x: Int, y: Int)","Can you please try to remove the space between class name and `(`, otherwise result is not properly formatted.","Just curious, is this a standard numpy style in our code? I don't know if there is a strong reason to do this." +2,"@@ -0,0 +1 @@ ++org.jetbrains.kotlin.idea.inspections.ConvertResourceToUseCallIntention","This line is outdated. Please run `Generate All Tests` shared configuration, and re-run tests. `LocalInspectionTestGenerated.java` file is expected to be modified after this launch, and this change should also be commited.","Same as above, missing from implementation package." +3,"@@ -0,0 +1 @@ ++org.jetbrains.kotlin.idea.inspections.RemoveRedundantBackticksInspection",Please add a test to verify that the quickfix is not offered when an actual keyword is in backticks.,Why is this needed? +4,"@@ -0,0 +1 @@ +throw Exception(""not implemented"") //To change body of created methods use File | Settings | File Templates.","`UnsupportedOperationException` would be a better choice -",Please add a licens -2,"@@ -0,0 +1,10 @@ +",Please add a license header to this error message. +5,"@@ -0,0 +1,10 @@ +// ""Create class object from usage"" ""true"" +// ERROR: Expression 'T' of type '' cannot be invoked as a function +trait T { @@ -12,8 +18,34 @@ + }","Can you come up with better use case for quick fix creating class object? This one from the test doesn't seem useful. Creating class object via intetion could be useful in case of T.foo() call, but in this case foo() function should be created as well (actually, it should be ""create function from usage"" quick fix, not ""create class object from usage""). -",I think this error -3,"@@ -0,0 +1,10 @@ +","I think this error message could be clearer as: ""Create class object from usage"" ""true"" cannot be invoked as a function""" +6,"@@ -0,0 +1,10 @@ ++// PROBLEM: none ++// DISABLE-ERRORS ++ ++enum class E(val value: String) { ++ E1(Companion.foo);","This is a valid warning, `E.Companion.foo` is being referenced as `Companion.foo`, which is redundant since the `companion object` is in scope. This should be `E1(foo)` in `.after.kt`.",Companion.foo should be snake case. +7,"@@ -0,0 +1,10 @@ ++fun test() { ++ use("""")",We can remove `create()` only if it hasn't side effects.,"The `use("""")` is not needed here." +8,"@@ -0,0 +1,10 @@ ++fun test() { ++ if (false) ++ while (true) { ++ foo(1) ++ } ++ //comment about foo(2)","Could you please add similar test with `else` block, like this +``` +if (...) doSmth() +else + while (true) { + foo(1) + } +// comment about call below +``` + +and check how it works now? The code `element.else == null` is a bit suspicious.",This `if` is unnecessary. +9,"@@ -0,0 +1,10 @@ +open class Foo { + open fun arguments(arg1: Int, arg2: Long) { + } @@ -21,54691 +53,3062 @@ Creating class object via intetion could be useful in case of T.foo() call, but + +class Bar : Foo() { + override fun arguments(arg1: Int, arg2: Long) {","I should mention that overridden function is not redundant if it has some other modifiers. For example, sometimes is reasonable to add `final` here, so function itself is not changed, but derived classes are made unable to override it. Also, I think that any annotation here makes the function not redundant. The same for any visibility modifier when you make overridden function more visible then original one. Please consider these cases, fix inspection, and add tests for them.",missing a `;` here. -4,"@@ -0,0 +1,101 @@ +10,"@@ -0,0 +1,107 @@ +/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. ++ * 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.jet.plugin.intentions ++package org.jetbrains.kotlin.utils","Please change package to `org.jetbrains.kotlin.util`, as per the inspection that is reported here","Could you add a license to this file, please?" +11,"@@ -0,0 +1,109 @@ ++/*",Why not merge this stuff with one in tests-common-jvm6?,Please remove this file. +12,"@@ -0,0 +1,11 @@ ++// !DIAGNOSTICS: -INVISIBLE_MEMBER -INVISIBLE_REFERENCE -UNUSED_PARAMETER ++// !LANGUAGE: +CalledInPlaceEffect + -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetParameter -+import org.jetbrains.jet.lexer.JetTokens ++import kotlin.internal.* + -+public class MakeTypeImplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.implicit.in.lambda"", javaClass()) { -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ throw IllegalStateException(""isApplicableTo(JetExpressionImpl, Editor) should be called instead"") -+ } ++inline fun myRun(@CalledInPlace(InvocationCount.EXACTLY_ONCE) block: () -> Unit) = block() + -+ override fun isApplicableTo(element: JetFunctionLiteralExpression, editor: Editor): Boolean { -+ val openBraceOffset = element.getLeftCurlyBrace().getStartOffset() -+ val closeBraceOffset = element.getRightCurlyBrace()?.getStartOffset() -+ val caretLocation = editor.getCaretModel().getOffset() -+ val arrow = element.getFunctionLiteral().getArrowNode() -+ if (arrow != null && !(openBraceOffset < caretLocation && caretLocation < arrow.getStartOffset() + 2) && -+ caretLocation != closeBraceOffset) return false -+ else if (arrow == null && caretLocation != openBraceOffset + 1 && caretLocation != closeBraceOffset) return false -+ -+ //val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext() -+ //val context = AnalyzerFacadeWithCache.getContextForElement(element) -+ //val expectedType = context[BindingContext.EXPECTED_EXPRESSION_TYPE, element.getFunctionLiteral()] -+ //println(""expected type of the function literal is "" + expectedType) -+ //val expectedType2 = context[BindingContext.EXPECTED_EXPRESSION_TYPE, element] -+ //println(""expected type of the function literal exp is "" + expectedType2) -+ -+ if (hasExplicitReturnType(element)) return true -+ if (hasExplicitReceiverType(element)) return true -+ if (hasExplicitParamType(element)) return true -+ return false","A one-liner would be nicer in my opinion: -`return hasExplicitReturnType(element) || hasExplicitReceiverType(element) || hasExplicitParamType(element)` -",Please annotate `@s -5,"@@ -0,0 +1,101 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ ++fun throwInLambda(): Int { ++ val x = myRun { throw java.lang.IllegalArgumentException() } ++ return x","Unclear place. First, why `TYPE_MISMATCH`? In this context, `x` should probably have `Nothing` type. Second, `UNREACHABLE_CODE` is expected here. Third, I don't quite understand why it appears after introduction of language features (the last but one commit).",Shouldn't this be in the same package as `kotlin.internal`? +13,"@@ -0,0 +1,11 @@ ++// ENABLE_MULTIPLATFORM ++// ERROR: Expected declaration must not have a body ++// IS_APPLICABLE: false ++expect class C { ++ val p: Int ++ get() = 1","For multi-platform testing, we have a specific group of tests. In your case, `multiModuleQuickFix` group should work properly (it should work for intentions too). This should also solve your problem with target platform detection.",This file has the main `caret_test.js` file. +14,"@@ -0,0 +1,11 @@ ++// IGNORE_BACKEND: JVM","Please note that you can customize bytecode tests by backend via +..common_templates... +// JVM_TEMPLATES +... +// JVM_IR_TEMPLATES +... +, see for example forInReversedArrayIndices.kt",I think this should be removed. +15,"@@ -0,0 +1,11 @@ ++// IGNORE_BACKEND: JVM ++fun f(): Boolean = ""non-primitive"" == null ++fun g(): Boolean = null == ""non-primitive"" ++fun h(): Boolean = ""non-primitive"".equals(null) ++//fun i(): Boolean = null.equals(""non-primitive"") ++//see nullCompareNonPrimitiveConst ++ ++// 0 ACONST_NULL","Please also check + +// 0 IF",Also this line should be removed. +16,"@@ -0,0 +1,11 @@ ++// WITH_RUNTIME ++// IS_APPLICABLE: FALSE ++import java.util.LinkedList + -+package org.jetbrains.jet.plugin.intentions ++fun Int.withIndices(): List> = LinkedList>() + -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetParameter -+import org.jetbrains.jet.lexer.JetTokens ++fun foo(s: Int) { ++ for ((index, a) in s.withIndices()) { + -+public class MakeTypeImplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.implicit.in.lambda"", javaClass()) { -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ throw IllegalStateException(""isApplicableTo(JetExpressionImpl, Editor) should be called instead"") + } ++}","Also please rename this test +",I don't think this test belongs in this file. +17,"@@ -0,0 +1,11 @@ ++class A(val s: String) { ++ inner class B(val x: Int = 0) ++} ++ ++// @A.class ++// 1 public \(Ljava/lang/String;\)V + -+ override fun isApplicableTo(element: JetFunctionLiteralExpression, editor: Editor): Boolean { -+ val openBraceOffset = element.getLeftCurlyBrace().getStartOffset() -+ val closeBraceOffset = element.getRightCurlyBrace()?.getStartOffset() -+ val caretLocation = editor.getCaretModel().getOffset() -+ val arrow = element.getFunctionLiteral().getArrowNode() -+ if (arrow != null && !(openBraceOffset < caretLocation && caretLocation < arrow.getStartOffset() + 2) && -+ caretLocation != closeBraceOffset) return false -+ else if (arrow == null && caretLocation != openBraceOffset + 1 && caretLocation != closeBraceOffset) return false -+ -+ //val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext() -+ //val context = AnalyzerFacadeWithCache.getContextForElement(element) -+ //val expectedType = context[BindingContext.EXPECTED_EXPRESSION_TYPE, element.getFunctionLiteral()] -+ //println(""expected type of the function literal is "" + expectedType) -+ //val expectedType2 = context[BindingContext.EXPECTED_EXPRESSION_TYPE, element] -+ //println(""expected type of the function literal exp is "" + expectedType2) -+ -+ if (hasExplicitReturnType(element)) return true -+ if (hasExplicitReceiverType(element)) return true -+ if (hasExplicitParamType(element)) return true -+ return false ++// @A$B.class ++// 0 \(\)V","I'll amend your changes with adding `// 0 \(LA;\)V` here. This is needed to check the `irClass.isInner` condition in `JvmDefaultConstructorLowering`, since the lowering is run before `InnerClassesLowering` where an additional parameter for the outer class is added.",Seems like this is missing a test. :) +18,"@@ -0,0 +1,11 @@ ++fun array() = arrayOfNulls(4) ++ ++fun f() { ++ for (i in array()) { ++ }","Please add some foo() call inside to avoid clashing with another optimizations in future: +``` + for (i in array()) { + foo() + } +```",This test (and the equivalent one) should be +19,"@@ -0,0 +1,11 @@ ++import Owner.CompTest",The second caret?,Please remove this. +20,"@@ -0,0 +1,12 @@ ++// Checks that methods 'access$getMy$p', 'access$getMy$cp' and 'getMy' are not generated and","I think this box test is unnecessary since it doesn't really check what's described here, it only checks that private properties in companion objects work, which is done elsewhere, so please delete this test",Would it be better to have `'getMy$p'` and `g +21,"@@ -0,0 +1,12 @@ ++// FILE: 1.kt ++","package test +",Can we just delete this line? +22,"@@ -0,0 +1,12 @@ ++// PROBLEM: none ++// WITH_RUNTIME ++fun test() { ++ with(foo()) { ++ println(""test"") ++ }","I think that we should report a warning in this case, but do not provide a quickfix, because such code looks like user mistake",This appears to be missing test coverage. +23,"@@ -0,0 +1,12 @@ ++// PROBLEM: none ++open class Foo { ++ open fun equals(other: Foo?): Boolean {",I think it should be highlighted.,This file needs to be renamed to something li +24,"@@ -0,0 +1,12 @@ ++// PROBLEM: none ++open class Foo { ++ open fun equals(other: Foo?): Boolean { ++ return true + } ++} + -+ override fun applyTo(element: JetFunctionLiteralExpression, editor: Editor) { -+ val functionLiteral = element.getFunctionLiteral() -+ val oldParameterList = functionLiteral.getValueParameterList() -+ -+ if (hasExplicitReturnType(element)) { -+ val childAfterParamList = oldParameterList?.getNextSibling() -+ val arrow = functionLiteral.getArrowNode()?.getPsi() -+ val childBeforeArrow = arrow?.getPrevSibling() -+ functionLiteral.deleteChildRange(childAfterParamList, childBeforeArrow) -+ val whiteSpaceBeforeArrow = JetPsiFactory.createWhiteSpace(element.getProject()) -+ functionLiteral.addBefore(whiteSpaceBeforeArrow, arrow) -+ } ++class Bar : Foo() { ++ override fun equals(other: Foo?): Boolean {",Same as above.,I'm not 100% sure if this is the right way to +25,"@@ -0,0 +1,12 @@ ++ ++ ++ ++ ++ ++",Not needed,I think the version should be 1.0. What do yo +26,"@@ -0,0 +1,12 @@ ++class A { ++ val a = """" ++ val b = """" ++} + -+ if (hasExplicitReceiverType(element)) { -+ val childAfterBrace = functionLiteral.getOpenBraceNode().getPsi()?.getNextSibling() -+ val childBeforeParamList = oldParameterList?.getPrevSibling() -+ functionLiteral.deleteChildRange(childAfterBrace, childBeforeParamList) -+ } ++fun box(): String { ++ val a = A::a.name ++ if (a != ""a"") return ""Fail $a"" ++ val b = A::`b`.name ++ if (b != ""b"") return ""Fail $b"" ++ return ""OK""","This test doesn't check that no classes were generated for the property reference. I don't think it's possible in a `box` test, please try a bytecode listing test instead (`compiler/testData/codegen/bytecodeListing`). + +Also please test constructors and functions +",This isn't necessary. +27,"@@ -0,0 +1,12 @@ ++name: ""Validate Gradle Wrapper"" ++on: [push]","Without `pull_request`, this won't actually run for external contributors",This file needs `make check` +28,"@@ -0,0 +1,12 @@ ++public class TestingUse { ++ fun test6(funcLitfunc: ((x: Int) -> Int) -> Boolean, innerfunc: (y: Int) -> Int): Unit { ++ val result = funcLitfunc(innerfunc) ++ var num = 0 ++ if (result == true) num = 1 ++ else num = 2","This is a nice test case, but is this code really needed to test your intention? I think it's just confusing... +","How about `TestingUse = (x: Int, y: Int)test6" +29,"@@ -0,0 +1,13 @@","What is this file? Is it for manual testing? +",This file doesn't belong to the PR. +30,"@@ -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.utils ++ ++data class CompletionVariant(","I suspect that this class doesn't use the features provided by the data classes, while the data classes are not free from the overhead. So maybe it makes sense to drop ""data"" here.",Should this be named `CompletionVariant`? +31,"@@ -0,0 +1,13 @@ ++// WITH_COROUTINES","This is really minor, but maybe these tests will succeed even with `WITH_RUNTIME`, now that `Result` in the standard library.",I don't see this being used anywhere. Am I mi +32,"@@ -0,0 +1,13 @@ ++// WITH_COROUTINES ++// FILE: test.kt ++fun test() { ++ val result = Result.success(""yes!"") ++ val other = Result.success(""nope"") ++ if (result == other) println(""=="") ++ if (result != other) println(""!="") ++ if (result.equals(other)) println(""equals"") ++ if (!result.equals(other)) println(""!equals"")","Judging by [KT-33722](https://youtrack.jetbrains.com/issue/KT-33722), these two lines should fail. Probably they don't because we only call `Result.equals-impl0` if API version >= 1.4. So let's add `!API_VERSION: LATEST` to this test, so that it tests something useful. :) + +But also, I don't really think the explicit `equals` call is such critical behavior that we should check it at this point in a codegen test. Having it reported as KT-33722 is probably enough. So I'd probably just remove these two lines from the test.",Please rename this file to `test.kt`. +33,"@@ -0,0 +1,13 @@ ++import Platform.JvmPlatform + -+ val oldParameters = oldParameterList?.getParameters() -+ if (oldParameterList != null && oldParameters != null && hasExplicitParamType(element)) { -+ val parameterString = oldParameters.map({(parameter: JetParameter): String -> parameter.getNameIdentifier()?.getText() ?: parameter.getText() ?: """"","Are all three sub-expressions of this elvis expression tested? -",Please annotate `@s -6,"@@ -0,0 +1,101 @@ ++sealed class Platform { ++ object JvmPlatform : Platform() ++ class Another(val name: String) : Platform() ++} ++ ++class ModuleInfo(val platform: Platform) ++ ++fun foo(moduleInfo: ModuleInfo) = when { ++ moduleInfo.platform == JvmPlatform -> 1",Please check how it works if the condition is flipped: `JvmPlatform == moduleInfo.platform`.,This test is not really testing this +34,"@@ -0,0 +1,138 @@ +/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. ++ * 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.jet.plugin.intentions ++package samples.collections + -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetParameter -+import org.jetbrains.jet.lexer.JetTokens -+ -+public class MakeTypeImplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.implicit.in.lambda"", javaClass()) { -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ throw IllegalStateException(""isApplicableTo(JetExpressionImpl, Editor) should be called instead"") -+ } ++import samples.* ++import java.time.LocalDateTime + -+ override fun isApplicableTo(element: JetFunctionLiteralExpression, editor: Editor): Boolean { -+ val openBraceOffset = element.getLeftCurlyBrace().getStartOffset() -+ val closeBraceOffset = element.getRightCurlyBrace()?.getStartOffset() -+ val caretLocation = editor.getCaretModel().getOffset() -+ val arrow = element.getFunctionLiteral().getArrowNode() -+ if (arrow != null && !(openBraceOffset < caretLocation && caretLocation < arrow.getStartOffset() + 2) && -+ caretLocation != closeBraceOffset) return false -+ else if (arrow == null && caretLocation != openBraceOffset + 1 && caretLocation != closeBraceOffset) return false -+ -+ //val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext() -+ //val context = AnalyzerFacadeWithCache.getContextForElement(element) -+ //val expectedType = context[BindingContext.EXPECTED_EXPRESSION_TYPE, element.getFunctionLiteral()] -+ //println(""expected type of the function literal is "" + expectedType) -+ //val expectedType2 = context[BindingContext.EXPECTED_EXPRESSION_TYPE, element] -+ //println(""expected type of the function literal exp is "" + expectedType2) -+ -+ if (hasExplicitReturnType(element)) return true -+ if (hasExplicitReceiverType(element)) return true -+ if (hasExplicitParamType(element)) return true -+ return false -+ } ++@RunWith(Enclosed::class) ++class Sort {","Please use another placement schema, similar to other collection and array samples. +Collection and List samples should go into `collections.kt`, and `Sorting` nested class can be created there, so its full name would be `samples.collections.Collections.Sorting`. Ditto for the array sorting samples.",Could you remove this `@RunWith(Enclo +35,"@@ -0,0 +1,14 @@ ++##---------------Begin: Kotlin-reflect ----------","Are these Begin/End tags required? + +Also, please consider renaming the file itself to `kotlin-reflect.pro`",why is this necessary? +36,"@@ -0,0 +1,14 @@ ++##---------------Begin: Kotlin-reflect ---------- ++# Keep Metadata annotations so they can be parsed at runtime. ++-keep class kotlin.Metadata { *; }","I wonder this is not actually needed. Recently, I started working on synthesizing metadata from scratch (for R8-processed Kotlin library), and kept adding more tests. During that, I found that, even without this rule, R8 will still keep metadata (annotation) associated to classes. + +More conversion/details are here: https://r8-review.googlesource.com/c/r8/+/46240/1/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRenameInParametertypeTest.java#70",I don't think this is the correct fil +37,"@@ -0,0 +1,14 @@ ++##---------------Begin: Kotlin-reflect ---------- ++# Keep Metadata annotations so they can be parsed at runtime. ++-keep class kotlin.Metadata { *; } + -+ override fun applyTo(element: JetFunctionLiteralExpression, editor: Editor) { -+ val functionLiteral = element.getFunctionLiteral() -+ val oldParameterList = functionLiteral.getValueParameterList() -+ -+ if (hasExplicitReturnType(element)) { -+ val childAfterParamList = oldParameterList?.getNextSibling() -+ val arrow = functionLiteral.getArrowNode()?.getPsi() -+ val childBeforeArrow = arrow?.getPrevSibling() -+ functionLiteral.deleteChildRange(childAfterParamList, childBeforeArrow) -+ val whiteSpaceBeforeArrow = JetPsiFactory.createWhiteSpace(element.getProject()) -+ functionLiteral.addBefore(whiteSpaceBeforeArrow, arrow) -+ } ++# Keep kotlin-reflect internals. ++-keep class kotlin.reflect.jvm.** { *; }","This seems way too broad. At least, we can try _public_ APIs only.",Shouldn't this be `kotlin.reflect.JVM +38,"@@ -0,0 +1,14 @@ ++##---------------Begin: Kotlin-reflect ---------- ++# Keep Metadata annotations so they can be parsed at runtime. ++-keep class kotlin.Metadata { *; } + -+ if (hasExplicitReceiverType(element)) { -+ val childAfterBrace = functionLiteral.getOpenBraceNode().getPsi()?.getNextSibling() -+ val childBeforeParamList = oldParameterList?.getPrevSibling() -+ functionLiteral.deleteChildRange(childAfterBrace, childBeforeParamList) -+ } ++# Keep kotlin-reflect internals. ++-keep class kotlin.reflect.jvm.** { *; } + -+ val oldParameters = oldParameterList?.getParameters() -+ if (oldParameterList != null && oldParameters != null && hasExplicitParamType(element)) { -+ val parameterString = oldParameters.map({(parameter: JetParameter): String -> parameter.getNameIdentifier()?.getText() ?: parameter.getText() ?: """" -+ }).makeString("", "", ""("", "")"") -+ println(""parameterString is "" + parameterString)","Don't forget to delete all debug output from your changeset -",Please annotate `@s -7,"@@ -0,0 +1,101 @@ ++# Keep generic signatures and annotations at runtime. ++# R8 requires InnerClasses and EnclosingMethod if you keepattributes Signature. ++-keepattributes InnerClasses,Signature,*Annotation*,EnclosingMethod",Do we need broad \*Annotation\* or just RuntimeVisibleAnnotation (because metadata is runtime visible) ?,Shouldn't this be `R8 requires InnerC +39,"@@ -0,0 +1,14 @@ +/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. ++ * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license ++ * that can be found in the license/LICENSE.txt file. + */ + -+package org.jetbrains.jet.plugin.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetParameter -+import org.jetbrains.jet.lexer.JetTokens -+ -+public class MakeTypeImplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.implicit.in.lambda"", javaClass()) { -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ throw IllegalStateException(""isApplicableTo(JetExpressionImpl, Editor) should be called instead"") -+ } -+ -+ override fun isApplicableTo(element: JetFunctionLiteralExpression, editor: Editor): Boolean { -+ val openBraceOffset = element.getLeftCurlyBrace().getStartOffset() -+ val closeBraceOffset = element.getRightCurlyBrace()?.getStartOffset() -+ val caretLocation = editor.getCaretModel().getOffset() -+ val arrow = element.getFunctionLiteral().getArrowNode() -+ if (arrow != null && !(openBraceOffset < caretLocation && caretLocation < arrow.getStartOffset() + 2) && -+ caretLocation != closeBraceOffset) return false -+ else if (arrow == null && caretLocation != openBraceOffset + 1 && caretLocation != closeBraceOffset) return false -+ -+ //val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext() -+ //val context = AnalyzerFacadeWithCache.getContextForElement(element) -+ //val expectedType = context[BindingContext.EXPECTED_EXPRESSION_TYPE, element.getFunctionLiteral()] -+ //println(""expected type of the function literal is "" + expectedType) -+ //val expectedType2 = context[BindingContext.EXPECTED_EXPRESSION_TYPE, element] -+ //println(""expected type of the function literal exp is "" + expectedType2) -+ -+ if (hasExplicitReturnType(element)) return true -+ if (hasExplicitReceiverType(element)) return true -+ if (hasExplicitParamType(element)) return true -+ return false -+ } + -+ override fun applyTo(element: JetFunctionLiteralExpression, editor: Editor) { -+ val functionLiteral = element.getFunctionLiteral() -+ val oldParameterList = functionLiteral.getValueParameterList() -+ -+ if (hasExplicitReturnType(element)) { -+ val childAfterParamList = oldParameterList?.getNextSibling() -+ val arrow = functionLiteral.getArrowNode()?.getPsi() -+ val childBeforeArrow = arrow?.getPrevSibling() -+ functionLiteral.deleteChildRange(childAfterParamList, childBeforeArrow) -+ val whiteSpaceBeforeArrow = JetPsiFactory.createWhiteSpace(element.getProject()) -+ functionLiteral.addBefore(whiteSpaceBeforeArrow, arrow) -+ } ++@file:Suppress(""INVISIBLE_MEMBER"", ""INVISIBLE_REFERENCE"") ++@file:JvmPackageName(""kotlin.test.annotations"") ++package kotlin.test + -+ if (hasExplicitReceiverType(element)) { -+ val childAfterBrace = functionLiteral.getOpenBraceNode().getPsi()?.getNextSibling() -+ val childBeforeParamList = oldParameterList?.getPrevSibling() -+ functionLiteral.deleteChildRange(childAfterBrace, childBeforeParamList) -+ } ++public actual typealias Test = org.testng.annotations.Test ++public actual typealias Ignore = org.testng.annotations.Ignore","Interesting, I hadn't noticed this annotation in javadoc of testng before, seems that it's rather new. What is the testng version it's available from?",Is this necessary? I don't see any re +40,"@@ -0,0 +1,14 @@ ++/* ++ * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license ++ * that can be found in the license/LICENSE.txt file. ++ */ + -+ val oldParameters = oldParameterList?.getParameters() -+ if (oldParameterList != null && oldParameters != null && hasExplicitParamType(element)) { -+ val parameterString = oldParameters.map({(parameter: JetParameter): String -> parameter.getNameIdentifier()?.getText() ?: parameter.getText() ?: """" -+ }).makeString("", "", ""("", "")"") -+ println(""parameterString is "" + parameterString) -+ val newParameterList = JetPsiFactory.createParameterList(element.getProject(), parameterString) -+ oldParameterList.replace(newParameterList) -+ } ++package org.jetbrains.kotlin.js.test.interop + -+ if (!hasExplicitParamType(element)) { -+ val currentParamList = element.getFunctionLiteral().getValueParameterList() -+ val firstChild = currentParamList?.getFirstChild() -+ if (firstChild?.getText() == ""("") firstChild!!.delete()","It's not very acceptable to compare text of nodes, especially when you can do the same structurally: -`firstChild.getElementType() == JetTokens.LPAR` -",Please annotate `@s -8,"@@ -0,0 +1,101 @@ ++interface InteropEngine {",JDK uses `ScriptEngine` for such things. I'd rather keep this name,missing new line at the end of file +41,"@@ -0,0 +1,14 @@ +/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. ++ * 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.gradle.utils + -+package org.jetbrains.jet.plugin.intentions ++import org.gradle.api.logging.Logger + -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetParameter -+import org.jetbrains.jet.lexer.JetTokens ++const val deprecatedBecauseNoConfigAvoidanceUseProvider = ""Using this brings performance issues. "" + ++ ""Use the provider instead to benefit from configuration avoidance.""",Use the equivalent provider method to benefit from gradle task configuration avoidance.,I think we don't need to refer to `va +42,"@@ -0,0 +1,14 @@ ++// KJS_WITH_FULL_RUNTIME ++// WITH_RUNTIME ++import kotlin.test.* + -+public class MakeTypeImplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.implicit.in.lambda"", javaClass()) { -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ throw IllegalStateException(""isApplicableTo(JetExpressionImpl, Editor) should be called instead"") -+ } ++fun box(): String { ++ val arr = intArrayOf(1, 2, 3, 4) ++ var sum = 0 ++ for (i in arr.reversed()) {","@punzki reversed/reversedArray() is totatlly unsafe optimization: +``` +fun box(): String { + val arr = intArrayOf(1, 2, 3, 4) + var sum = 0 + var index = 0 + //for (i in arr.reversedArray()) { + for (i in arr.reversed()) { + arr[index++] = 0 + sum = sum * 10 + i + } + assertEquals(4321, sum) + + return ""OK"" +} +```",I'm not sure how this works. `intArra +43,"@@ -0,0 +1,14 @@ ++// WITH_RUNTIME","Does this box test check something which is not covered by current tests in `codegen/box/dataClasses`? If no, I propose to delete it",Can we delete this file? +44,"@@ -0,0 +1,14 @@ ++const val M = Char.MIN_VALUE + -+ override fun isApplicableTo(element: JetFunctionLiteralExpression, editor: Editor): Boolean { -+ val openBraceOffset = element.getLeftCurlyBrace().getStartOffset() -+ val closeBraceOffset = element.getRightCurlyBrace()?.getStartOffset() -+ val caretLocation = editor.getCaretModel().getOffset() -+ val arrow = element.getFunctionLiteral().getArrowNode() -+ if (arrow != null && !(openBraceOffset < caretLocation && caretLocation < arrow.getStartOffset() + 2) && -+ caretLocation != closeBraceOffset) return false -+ else if (arrow == null && caretLocation != openBraceOffset + 1 && caretLocation != closeBraceOffset) return false -+ -+ //val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext() -+ //val context = AnalyzerFacadeWithCache.getContextForElement(element) -+ //val expectedType = context[BindingContext.EXPECTED_EXPRESSION_TYPE, element.getFunctionLiteral()] -+ //println(""expected type of the function literal is "" + expectedType) -+ //val expectedType2 = context[BindingContext.EXPECTED_EXPRESSION_TYPE, element] -+ //println(""expected type of the function literal exp is "" + expectedType2) -+ -+ if (hasExplicitReturnType(element)) return true -+ if (hasExplicitReceiverType(element)) return true -+ if (hasExplicitParamType(element)) return true -+ return false -+ } ++fun f(a: Char) { ++ for (i in a downTo M) {",....Please add some call inside loops here and below,I am not sure why this is needed +45,"@@ -0,0 +1,14 @@ ++fun cond() = false + -+ override fun applyTo(element: JetFunctionLiteralExpression, editor: Editor) { -+ val functionLiteral = element.getFunctionLiteral() -+ val oldParameterList = functionLiteral.getValueParameterList() -+ -+ if (hasExplicitReturnType(element)) { -+ val childAfterParamList = oldParameterList?.getNextSibling() -+ val arrow = functionLiteral.getArrowNode()?.getPsi() -+ val childBeforeArrow = arrow?.getPrevSibling() -+ functionLiteral.deleteChildRange(childAfterParamList, childBeforeArrow) -+ val whiteSpaceBeforeArrow = JetPsiFactory.createWhiteSpace(element.getProject()) -+ functionLiteral.addBefore(whiteSpaceBeforeArrow, arrow) -+ } ++fun box() { ++ if (cond()) ++ cond() ++ else ++ false ++} + -+ if (hasExplicitReceiverType(element)) { -+ val childAfterBrace = functionLiteral.getOpenBraceNode().getPsi()?.getNextSibling() -+ val childBeforeParamList = oldParameterList?.getPrevSibling() -+ functionLiteral.deleteChildRange(childAfterBrace, childBeforeParamList) -+ } ++fun main(args: Array) {","Idea: Similar to `LowLevelDebuggerTestBase`, maybe you can generate and write your own ""main class"" that simply calls `box()`? This way we can easily re-use existing box tests to create stepping tests.",The `else` is unnecessary. +46,"@@ -0,0 +1,14 @@ ++fun cond() = false + -+ val oldParameters = oldParameterList?.getParameters() -+ if (oldParameterList != null && oldParameters != null && hasExplicitParamType(element)) { -+ val parameterString = oldParameters.map({(parameter: JetParameter): String -> parameter.getNameIdentifier()?.getText() ?: parameter.getText() ?: """" -+ }).makeString("", "", ""("", "")"") -+ println(""parameterString is "" + parameterString) -+ val newParameterList = JetPsiFactory.createParameterList(element.getProject(), parameterString) -+ oldParameterList.replace(newParameterList) -+ } ++fun box() { ++ if (cond()) ++ cond() ++ else ++ false ++} + -+ if (!hasExplicitParamType(element)) { -+ val currentParamList = element.getFunctionLiteral().getValueParameterList() -+ val firstChild = currentParamList?.getFirstChild() -+ if (firstChild?.getText() == ""("") firstChild!!.delete() -+ val lastChild = currentParamList?.getLastChild() -+ if (lastChild?.getText() == "")"") lastChild!!.delete()","Ditto (`JetTokens.RPAR`) -",Please annotate `@s -9,"@@ -0,0 +1,102 @@ -+/* -+ * 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. -+ */ ++fun main(args: Array) { ++ box() ++} + -+package org.jetbrains.kotlin.effectsystem.adapters ++// 4 1 4 7 8","Consider also recording the method name and maybe we can do something like: +``` +// box(): 4 +// cond(): 1 +// box(): 4 7 8 +```",missing semicolon at the end of this +47,"@@ -0,0 +1,143 @@ ++// WITH_RUNTIME + -+import org.jetbrains.kotlin.effectsystem.impls.* -+import org.jetbrains.kotlin.effectsystem.structure.ESClause -+import org.jetbrains.kotlin.effectsystem.structure.ESEffect -+import org.jetbrains.kotlin.effectsystem.structure.EffectSchema -+import org.jetbrains.kotlin.effectsystem.factories.lift -+import org.jetbrains.kotlin.effectsystem.structure.ESExpressionVisitor ++fun checkByteArray():Boolean {","here and in other functions below, add space before Boolean return type (`fun checkByteArray(): Boolean`)",Let's annotate this as `@experimental +48,"@@ -0,0 +1,147 @@ ++/* ++ * 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. ++ */ + -+class InfoCollector(private val observedEffect: ESEffect) : ESExpressionVisitor { -+ private var isInverted: Boolean = false ++package org.jetbrains.kotlin.utils + -+ fun collectFromSchema(schema: EffectSchema): MutableContextInfo = -+ schema.clauses.mapNotNull { collectFromClause(it) }.fold(MutableContextInfo.EMPTY, { resultingInfo, clauseInfo -> resultingInfo.and(clauseInfo) }) ++import java.util.IdentityHashMap + -+ private fun collectFromClause(clause: ESClause): MutableContextInfo? { -+ val premise = clause.condition",This name contradicts with real semantics,Why not just use `n -10,"@@ -0,0 +1,102 @@ -+/* -+ * 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. -+ */ ++const val ARRAY_UNTIL_SIZE = 10",I'd probably make it private or even put within a companion for `SmartHashMap` to avoid its appearing in other scopes,I'm not sure if this file should be in this PR +49,"@@ -0,0 +1,15 @@ ++// ""Replace with safe (?.) call"" ""false"" ++// ACTION: Add non-null asserted (!!) call ++// ACTION: Convert to expression body ++// ACTION: Replace with safe (this?.) call ++// ACTION: Wrap with '?.let { ... }' call ++// ERROR: Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type A? + -+package org.jetbrains.kotlin.effectsystem.adapters ++class A { ++ fun foo() { ++ } ++} + -+import org.jetbrains.kotlin.effectsystem.impls.* -+import org.jetbrains.kotlin.effectsystem.structure.ESClause -+import org.jetbrains.kotlin.effectsystem.structure.ESEffect -+import org.jetbrains.kotlin.effectsystem.structure.EffectSchema -+import org.jetbrains.kotlin.effectsystem.factories.lift -+import org.jetbrains.kotlin.effectsystem.structure.ESExpressionVisitor ++fun A?.bar() { ++ foo() ++}","Why does this test have so strange name? I see no `invoke` here, either safe or unsafe",Not sure what is going on here. +50,"@@ -0,0 +1,15 @@ ++// SKIP_TXT","Maybe we could skip txt generation for all these tests automatically by adding an abstract method into `AbstractDiagnosticsTest` and overriding it in this test, instead of adding `SKIP_TXT` to each file?",The name `SKIP_TXT` is not very descriptive. H +51,"@@ -0,0 +1,15 @@ ++// WITH_RUNTIME + -+class InfoCollector(private val observedEffect: ESEffect) : ESExpressionVisitor { -+ private var isInverted: Boolean = false ++fun contains(set: Set, x: Int): Boolean = when { ++ set.size == 0 -> false ++ else -> x in set as Set ++} + -+ fun collectFromSchema(schema: EffectSchema): MutableContextInfo = -+ schema.clauses.mapNotNull { collectFromClause(it) }.fold(MutableContextInfo.EMPTY, { resultingInfo, clauseInfo -> resultingInfo.and(clauseInfo) }) ++fun box(): String { ++ val set = setOf(1) ++ if (contains(set, 1)) { ++ return ""OK"" ++ } + -+ private fun collectFromClause(clause: ESClause): MutableContextInfo? { -+ val premise = clause.condition ++ return ""Fail"" ++}","This test in not related to Range#contains, but at some point I had implementation which passed all tests (without this one), but ant build was failed. +",Not sure if the compiler is smart enough to op +52,"@@ -0,0 +1,15 @@ ++class TestingUse { ++ fun test(sum: Int.(a: Int) -> Int, b: Int): Int { ++ return b.sum(b) ++ } ++ fun test2(sum: (a: Int, b: Int) -> Int, c: Int): Int {","Basically you've used the same test data file in all tests on `makeTypeExplicitInLambda`, altering the calling function in each case. This is not a good idea, because once one of such tests fails, the investigating person might think that the fact that there are several functions in this file is relevant to the test case, while in reality it's not. + +Please try to make your tests as minimal as possible, i.e. only include relevant data in each test. +",nit: how about `test1` instead of `test2`? +53,"@@ -0,0 +1,15 @@ ++data class Foo(val a: String) { ++ fun copy(i: Int) {} ++} + -+ // Check for non-conditional effects -+ if (premise is ESBooleanConstant && premise.value) { -+ return MutableContextInfo.EMPTY.fire(clause.effect)","As we have discussed, logically this conclusion is erroneous. I strongly recommend to fix this, because you can create true clause condition in some other context thus getting really wrong conclusion",Why not `isNull`? -11,"@@ -0,0 +1,102 @@ ++class Foo2() { ++ fun copy(i: Int) {} ++} ++","I'd add an example that clearly shows all should be named, like this: +``` +data class SomeName(a: Int, b: Int, c: String) +f.copy(2, c = """") +```",This class does not need to have `a: String` a +54,"@@ -0,0 +1,151 @@ +/* -+ * 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. ++ * 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.effectsystem.adapters ++package org.jetbrains.kotlin.utils + -+import org.jetbrains.kotlin.effectsystem.impls.* -+import org.jetbrains.kotlin.effectsystem.structure.ESClause -+import org.jetbrains.kotlin.effectsystem.structure.ESEffect -+import org.jetbrains.kotlin.effectsystem.structure.EffectSchema -+import org.jetbrains.kotlin.effectsystem.factories.lift -+import org.jetbrains.kotlin.effectsystem.structure.ESExpressionVisitor ++const val ARRAY_UNTIL_SIZE = 10 + -+class InfoCollector(private val observedEffect: ESEffect) : ESExpressionVisitor { -+ private var isInverted: Boolean = false ++/** ++ * [SmartHashMap] is a Map implementation that uses reference identity for keys.",Also add a note that this class is not thread-safe,Is this a public API? I don't see it reference +55,"@@ -0,0 +1,16 @@ ++// IGNORE_BACKEND: JS, JS_IR + -+ fun collectFromSchema(schema: EffectSchema): MutableContextInfo = -+ schema.clauses.mapNotNull { collectFromClause(it) }.fold(MutableContextInfo.EMPTY, { resultingInfo, clauseInfo -> resultingInfo.and(clauseInfo) }) ++fun f( ++ f1: () -> String = { f2() }, ++ f2: () -> String = { ""OK"" }","Please use here non-""OK"" value cause it clashes with result value in ```f { result (""OK"") }``` call",can we have a test for the same thing as we ha +56,"@@ -0,0 +1,16 @@ ++// IGNORE_BACKEND: JS, JS_IR + -+ private fun collectFromClause(clause: ESClause): MutableContextInfo? { -+ val premise = clause.condition ++fun f( ++ f1: () -> String = { f2() }, ++ f2: () -> String = { ""OK"" } ++): String = f1() + -+ // Check for non-conditional effects -+ if (premise is ESBooleanConstant && premise.value) { -+ return MutableContextInfo.EMPTY.fire(clause.effect) -+ } ++fun box(): String { ++ var result = ""fail"" ++ try { ++ f() ++ } catch (e : Exception) { ++ result = ""OK"" ++ } ++ return f { result }",This looks like it does `f(f1 = { result })` while you also probably want to test `f(f2 = { result })`.,do we need this `catch` block? +57,"@@ -0,0 +1,16 @@ ++// IGNORE_BACKEND: JVM ++// KOTLIN_CONFIGURATION_FLAGS: ASSERTIONS_MODE=jvm ++ ++class Outer { ++ class Inner { ++ fun f() { assert(true) } ++ } ++} ++ ++// We set the assertion status based on top-level classes. ++// 0 LDC LOuter\$Inner;.class ++// Outer\$Inner.: ++// 1 LDC LOuter;.class\s*INVOKEVIRTUAL java/lang/Class.desiredAssertionStatus \(\)Z ++// 1 PUTSTATIC Outer\$Inner.\$assertionsDisabled : Z ++// Outer\$Inner.f: ++// 1 GETSTATIC Outer\$Inner.\$assertionsDisabled","Please also add: +// 1 desiredAssertionStatus + // 1 public final static Z $assertionsDisabled",Is there a reason why this doesn't go in `src/ +58,"@@ -0,0 +1,16 @@ ++// TARGET_BACKEND: JVM ++// IGNORE_BACKEND: JVM ++// JVM_TARGET: 1.8 ++ ++open class A(val x: String) { ++ inline fun f() = if (this is C) this else A(x)",Could you also add test with inline getter?,This is the exact same code as in `Object.defi +59,"@@ -0,0 +1,16 @@ ++fun f() : Int {","pls, don't use println in tests +it would be best to rewrite it via +```var result = ""fail"" + +fun withSideEffect() : Int { + result = ""OK"" + return 42 +} + +fun box(): String { + if (withSideEffect() == null) { + return ""fail 1"" + } + + if (result != ""OK"") return ""fail 2"" + result = ""fail3"" + + if (withSideEffect() != null) { + return result + } + + return ""fail4"" +} + +``` +And add same test to box ones. ",Can you add the docstring here? (I know it's a +60,"@@ -0,0 +1,16 @@ ++fun intArray() = intArrayOf(0, 0, 0, 0) ++fun longArray() = longArrayOf(0, 0, 0, 0) + -+ // Check for information from conditional effects -+ return when (observedEffect.isImplies(clause.effect)) { -+ // observed effect implies clause's effect => clause's effect was fired => clause's condition is true -+ true -> clause.condition.accept(this) ++fun f() { ++ for (i in intArray()) {",...and here too,"Should this be `intArrayOf(1, 0, 0, 0)`?" +61,"@@ -0,0 +1,16 @@ ++fun testIsNullOrBlank(x: String?) {","This test has no annotation of some language feature on. Looks strange. I'd check all new tests, and most probably all of them should have some annotation. Otherwise backward compatibility can be broken",What does it mean for a null value to be treat +62,"@@ -0,0 +1,16 @@ ++interface A { ++ fun f(x: T): T ++} + -+ // Observed effect *may* or *doesn't* implies clause's - no useful information -+ null, false -> null -+ } ++open class B { ++ open fun f(x: String): String = x ++} ++ ++open class C : B(), A ++ ++// class D should not have an additional bridge",Check this using reflection or bytecode test?,I am not sure how I feel about this A +63,"@@ -0,0 +1,169 @@ ++# Annotation Options ++ ++Goals: ++* Support annotation options, such as retention policy and trageting","Typo: trageting -> targeting +",I think we should add a note that these option +64,"@@ -0,0 +1,17 @@ ++// !DIAGNOSTICS: -UNUSED_PARAMETER ++class C { ++ [kotlin.jvm.overloads] private fun foo(s: String = ""OK"") { + } ++} + -+ override fun visitIs(isOperator: ESIs): MutableContextInfo = with(isOperator) { -+ if (isNegated != isInverted) MutableContextInfo.EMPTY.notSubtype(left, type) else MutableContextInfo.EMPTY.subtype(left, type) ++fun foo() { ++ class D { ++ [kotlin.jvm.overloads] fun foo(s: String = ""OK"") { ++ } + } + -+ override fun visitEqual(equal: ESEqual): MutableContextInfo = with(equal) { -+ if (isNegated != isInverted) MutableContextInfo.EMPTY.notEqual(left, right) else MutableContextInfo.EMPTY.equal(left, right) ++ val x = object { ++ [kotlin.jvm.overloads] fun foo(s: String = ""OK"") { ++ } + } ++}","Please also add an `internal` member with `overloads` here, to ensure the warning is not reported on it +",Shouldn't this be `-UNUSED_PARAMETER`? +65,"@@ -0,0 +1,17 @@ ++// IGNORE_BACKEND: JVM ++import kotlin.test.assertEquals + -+ override fun visitAnd(and: ESAnd): MutableContextInfo { -+ val leftInfo = and.left.accept(this) -+ val rightInfo = and.right.accept(this) ++fun foo(x : String) : String { ++ assert(""abz]"".hashCode() == ""aby|"".hashCode()) + -+ return if (isInverted) leftInfo.or(rightInfo) else leftInfo.and(rightInfo) ++ when (x) { ++ ""abz]"" -> return ""abz"" ++ ""ghi"" -> return ""ghi"" ++ ""aby|"" -> return ""aby"" ++ ""abz]"" -> return ""fail"" + } + -+ override fun visitNot(not: ESNot): MutableContextInfo = inverted { not.arg.accept(this) } ++ return ""other"" ++} + -+ override fun visitOr(or: ESOr): MutableContextInfo { -+ val leftInfo = or.left.accept(this) -+ val rightInfo = or.right.accept(this) -+ return if (isInverted) leftInfo.and(rightInfo) else leftInfo.or(rightInfo) -+ } ++// 0 LOOKUPSWITCH",Is LOOKUPSWITCH is absent cause of hashAndSwitchLabels.size <= 2 condition?,Is this line needed? +66,"@@ -0,0 +1,17 @@ ++// TARGET_BACKEND: JVM","If I understood correctly, this test and the following one are just smoke tests to check, that there is no internal compiler error. Could you, please, turn them into assertion checks, like other ones from the same directory? ",This seems unrelated to the rest of th +67,"@@ -0,0 +1,17 @@ ++package test ++open class Foo() { ++open fun execute() : Unit { ++} ++} ++open class Bar() { ++var fooNotNull : Foo = Foo() ++var fooNullable : Foo? = null ++} ++open class Test() { ++public open fun test(barNotNull : Bar, barNullable : Bar?) : Unit { ++barNotNull.fooNotNull.execute() ++barNotNull.fooNullable?.execute() ++barNullable?.fooNotNull?.execute() ++barNullable?.fooNullable?.execute() ++} ++} +\ No newline at end of file","Please fix code formatting in this test +",missing new line at the end of file +68,"@@ -0,0 +1,18 @@ ++// Checks that accessor are not used because property can be accessed directly. + -+ override fun visitVariable(esVariable: ESVariable): MutableContextInfo { -+ throw IllegalStateException(""InfoCollector shouldn't visit non-boolean values"") -+ } ++interface I { ++ companion object { ++ private val bar = ""Companion Field from I""",Let's make this a `var` as well,Companion Field -> Companion Field +69,"@@ -0,0 +1,18 @@ ++// KJS_WITH_FULL_RUNTIME ++// WITH_RUNTIME ++import kotlin.test.* + -+ override fun visitBooleanVariable(esBooleanVariable: ESBooleanVariable): MutableContextInfo = -+ if (isInverted) -+ MutableContextInfo.EMPTY.equal(esBooleanVariable, false.lift()) -+ else -+ MutableContextInfo.EMPTY.equal(esBooleanVariable, true.lift()) ++fun box(): String { ++ val arr = intArrayOf(1, 2, 3, 4) ++ var sum = 0 ++ var index = 0 ++ for (i in arr.reversed()) {",reversed -> reversedArray?,`for (var i in arr.reversed())` +70,"@@ -0,0 +1,18 @@ ++fun f(s: String?, t: String): String { ++ return s.plus(t) ++} + -+ override fun visitBooleanConstant(esBooleanConstant: ESBooleanConstant): MutableContextInfo { -+ throw IllegalStateException(""InfoCollector shouldn't visit constants"") -+ } ++fun g(s: String, t: Any?): String { ++ return ""$s$t"" ++} + -+ override fun visitConstant(esConstant: ESConstant): MutableContextInfo { -+ throw IllegalStateException(""InfoCollector shouldn't visit constants"") -+ } ++fun h(s: String, t: Any?): String { ++ return s + t ++} + -+ override fun visitLambda(esLambda: ESLambda): MutableContextInfo { -+ throw IllegalStateException(""InfoCollector shouldn't visit non-boolean values"") -+ } ++fun box(): String { ++ if (f(""O"", ""K"") != ""OK"") return ""Fail""",Fail 1,Just a style preference: I think we te +71,"@@ -0,0 +1,18 @@ ++fun f(s: String?, t: String): String { ++ return s.plus(t) ++} + -+ private fun inverted(block: () -> R): R { -+ isInverted = isInverted.not() -+ val result = block() -+ isInverted = isInverted.not()",Ugly construction. Are you sure it's really needed?,Why not `isNull`? -12,"@@ -0,0 +1,102 @@ -+/* -+ * 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. -+ */ ++fun g(s: String, t: Any?): String { ++ return ""$s$t"" ++} + -+package org.jetbrains.kotlin.idea.inspections -+ -+import com.intellij.codeInspection.* -+import com.intellij.openapi.project.Project -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.* -+import org.jetbrains.kotlin.psi.psiUtil.getCallNameExpression -+ -+class KotlinRedundantOverrideInspection : AbstractKotlinInspection(), CleanupLocalInspectionTool { -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession) = -+ object : KtVisitorVoid() { -+ override fun visitNamedFunction(function: KtNamedFunction) { -+ super.visitNamedFunction(function) -+ if (!function.hasModifier(KtTokens.OVERRIDE_KEYWORD)) return -+ if (function.containsOtherModifier()) return",I'd inline this function,What do you think a -13,"@@ -0,0 +1,102 @@ -+/* -+ * 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.inspections -+ -+import com.intellij.codeInspection.* -+import com.intellij.openapi.project.Project -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.* -+import org.jetbrains.kotlin.psi.psiUtil.getCallNameExpression -+ -+class KotlinRedundantOverrideInspection : AbstractKotlinInspection(), CleanupLocalInspectionTool { -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession) = -+ object : KtVisitorVoid() { -+ override fun visitNamedFunction(function: KtNamedFunction) { -+ super.visitNamedFunction(function) -+ if (!function.hasModifier(KtTokens.OVERRIDE_KEYWORD)) return -+ if (function.containsOtherModifier()) return -+ if (function.annotationEntries.size != 0) return -+ -+ val bodyExpression = function.bodyExpression -+ bodyExpression ?: return",This and previous can be written in one line,What do you think a -14,"@@ -0,0 +1,103 @@ -+/* -+ * Copyright 2010-2015 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.kotlin.resolve -+ -+import org.jetbrains.kotlin.builtins.KotlinBuiltIns -+import org.jetbrains.kotlin.descriptors.* -+import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor -+import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget -+import org.jetbrains.kotlin.descriptors.annotations.Annotations -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.resolve.annotations.argumentValue -+ -+private val JAVA_DEPRECATED = FqName(Deprecated::class.java.name)","This was corrupted by the refactoring and is now in fact ""kotlin.Deprecated"". Let's use a hard-coded string instead. -",Why not just use `o -15,"@@ -0,0 +1,103 @@ -+/* -+ * 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.effectsystem.visitors -+ -+import org.jetbrains.kotlin.effectsystem.factories.boundSchemaFromClauses -+import org.jetbrains.kotlin.effectsystem.factories.lift -+import org.jetbrains.kotlin.effectsystem.factories.negated -+import org.jetbrains.kotlin.effectsystem.impls.* -+import org.jetbrains.kotlin.effectsystem.structure.* -+import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf -+ -+/** -+ * Reduces given effect schema by evaluating constant expressions, -+ * throwing away senseless checks and infeasible clauses, etc. -+ */ -+class Reducer : ESExpressionVisitor { -+ fun reduceSchema(schema: EffectSchema): EffectSchema = -+ boundSchemaFromClauses(schema.clauses.mapNotNull { reduceClause(it) }) -+ -+ private fun reduceClause(clause: org.jetbrains.kotlin.effectsystem.structure.ESClause): org.jetbrains.kotlin.effectsystem.structure.ESClause? {",Fully qualified names for some reason,"So, it looks like t" -16,"@@ -0,0 +1,103 @@ -+/* -+ * 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. -+ */ ++fun h(s: String, t: Any?): String { ++ return s + t ++} + -+package org.jetbrains.kotlin.effectsystem.visitors ++fun box(): String { ++ if (f(""O"", ""K"") != ""OK"") return ""Fail"" ++ if (g(""O"", ""K"") != ""OK"") return ""Fail""",'Fail 2' and so on,Just for my own education: What's the +72,"@@ -0,0 +1,18 @@ ++sealed class Parent + -+import org.jetbrains.kotlin.effectsystem.factories.boundSchemaFromClauses -+import org.jetbrains.kotlin.effectsystem.factories.lift -+import org.jetbrains.kotlin.effectsystem.factories.negated -+import org.jetbrains.kotlin.effectsystem.impls.* -+import org.jetbrains.kotlin.effectsystem.structure.* -+import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf ++class Child1(val field1: Int): Parent() + -+/** -+ * Reduces given effect schema by evaluating constant expressions, -+ * throwing away senseless checks and infeasible clauses, etc. -+ */ -+class Reducer : ESExpressionVisitor { -+ fun reduceSchema(schema: EffectSchema): EffectSchema = -+ boundSchemaFromClauses(schema.clauses.mapNotNull { reduceClause(it) }) ++class Child2(val field2: Int): Parent() + -+ private fun reduceClause(clause: org.jetbrains.kotlin.effectsystem.structure.ESClause): org.jetbrains.kotlin.effectsystem.structure.ESClause? { -+ val reducedPremise = clause.condition.accept(this) as ESBooleanExpression + -+ // Filter never executed premises -+ return if (reducedPremise is ESBooleanConstant && !reducedPremise.value) null else ESClause(reducedPremise, clause.effect)",I don't like this `null` because its meaning is unclear. It's better to introduce thing like `ESFalseClause`.,This file needs to be renamed. -17,"@@ -0,0 +1,103 @@ ++fun foo(parent: Parent) = when(parent) { ++ is val child: Child1 -> parent.field1 + parent.field2 ++ !is val _ : Child2 -> 10",What's the difference between this syntax and just `!is Child2`?,I don't understand what is this test t +73,"@@ -0,0 +1,19 @@ +/* -+ * 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.effectsystem.visitors -+ -+import org.jetbrains.kotlin.effectsystem.factories.boundSchemaFromClauses -+import org.jetbrains.kotlin.effectsystem.factories.lift -+import org.jetbrains.kotlin.effectsystem.factories.negated -+import org.jetbrains.kotlin.effectsystem.impls.* -+import org.jetbrains.kotlin.effectsystem.structure.* -+import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf -+ -+/** -+ * Reduces given effect schema by evaluating constant expressions, -+ * throwing away senseless checks and infeasible clauses, etc. ++ * 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. + */ -+class Reducer : ESExpressionVisitor { -+ fun reduceSchema(schema: EffectSchema): EffectSchema = -+ boundSchemaFromClauses(schema.clauses.mapNotNull { reduceClause(it) }) -+ -+ private fun reduceClause(clause: org.jetbrains.kotlin.effectsystem.structure.ESClause): org.jetbrains.kotlin.effectsystem.structure.ESClause? { -+ val reducedPremise = clause.condition.accept(this) as ESBooleanExpression -+ -+ // Filter never executed premises -+ return if (reducedPremise is ESBooleanConstant && !reducedPremise.value) null else ESClause(reducedPremise, clause.effect) -+ } -+ -+ override fun visitIs(isOperator: ESIs): ESBooleanExpression { -+ val reducedArg = isOperator.left.accept(this) as ESValue + -+ val result = when (reducedArg) { -+ is ESConstant -> reducedArg.type.isSubtypeOf(isOperator.functor.type) -+ is ESVariable -> if (reducedArg.type.isSubtypeOf(isOperator.functor.type)) true else null -+ else -> throw IllegalStateException(""Unknown subtype of ESValue: $reducedArg"") -+ } ++package org.jetbrains.kotlin.utils; + -+ // Result is unknown, do not evaluate -+ result ?: return ESIs(reducedArg, isOperator.functor) ++data class KotlinReplError(val loc: Location?, val message: String = """", val severity: Severity) {",It seems that it could be substituted with ScriptDiagnostic. But the problem is that scripting-common is not accessible from compiler-cli. So it is one more reason to base completion on a new API and relocate it completely to a plugin similar to scripting plugin.,Shouldn't we also have a test to verif +74,"@@ -0,0 +1,19 @@ ++// Checks that methods 'access$getMy$p', 'access$getMy$cp' and 'getMy' are not generated and","Why have you deleted the `kt-14258.kt` test from your earlier commits where a lot more cases were covered? If you think that test was getting too big to understand, you can always split it into several independent tests, e.g. `kt14258_1.kt`, `kt14258_2.kt`, ...",Would it be better to have `'getMy$p'` +75,"@@ -0,0 +1,19 @@ ++// Checks that methods 'access$getMy$p', 'access$getMy$cp' and 'getMy' are not generated and ++// that backed field 'my' is directly used through a 'getstatic' + -+ return result.xor(isOperator.functor.isNegated).lift() ++class My { ++ companion object { ++ private val my: String = ""OK"" + } + -+ override fun visitEqual(equal: ESEqual): ESBooleanExpression { -+ val reducedLeft = equal.left.accept(this) as ESValue -+ val reducedRight = equal.right -+ -+ if (reducedLeft is ESConstant) return (reducedLeft.value == reducedRight.value).xor(equal.functor.isNegated).lift()","Just to ask: how does it work with different kinds of comparisons (`==`, `===`)?",This file needs to be renamed. -18,"@@ -0,0 +1,104 @@ -+/* -+ * 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.wrappers.symbols -+ -+import com.intellij.psi.CommonClassNames -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.load.java.structure.* -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.Name -+import org.jetbrains.kotlin.name.SpecialNames -+import javax.lang.model.element.ElementKind -+import javax.lang.model.element.ExecutableElement -+import javax.lang.model.element.TypeElement -+import javax.lang.model.element.VariableElement -+import javax.lang.model.type.NoType -+import javax.lang.model.type.TypeKind -+ -+class JavacClass(element: T, -+ javac: Javac) : JavacClassifier(element, javac), JavaClass { ++ fun getMyValue() = my ++} + -+ override val name -+ get() = SpecialNames.safeIdentifier(element.simpleName.toString()) ++fun box() = My().getMyValue()",`fun box()` is not needed in bytecode text tests,The test is failing because `getMyValu +76,"@@ -0,0 +1,19 @@ ++// FILE: protectedPack/J.java + -+ override val isAbstract -+ get() = element.isAbstract ++package protectedPack; + -+ override val isStatic -+ get() = element.isStatic ++public class J { ++ protected String foo = ""OK""; ++} + -+ override val isFinal -+ get() = element.isFinal ++// FILE: 1.kt + -+ override val visibility -+ get() = element.getVisibility() ++package protectedPack + -+ override val typeParameters: List -+ get() = element.typeParameters.map { JavacTypeParameter(it, javac) } ++inline fun foo(crossinline bar: () -> String) = object { ++ fun baz() = bar() ++}.baz() + -+ override val fqName -+ get() = FqName(element.qualifiedName.toString()) ++fun box(): String {","Could you add more test with protected, e.g. when protected methods are called from crossinline lambda, but in case when it's inlined again in inline function, e.g.: +class A { + protected fun smth() {} +} + +class B: A() { + inline fun test(l: () -> ?) = inlineCrossInlineCall{ foo(); l() } +} + +and test call from another package",I think we can skip this test altogeth +77,"@@ -0,0 +1,19 @@ ++// IGNORE_BACKEND: JVM ++import kotlin.test.assertEquals + -+ override val supertypes -+ get() = element.interfaces.toMutableList().apply { -+ if (element.superclass !is NoType) add(element.superclass) ++fun foo(x : String) : String { ++ assert(""abz]"".hashCode() == ""aby|"".hashCode()) + -+ val hasObject = !none { it.toString() == CommonClassNames.JAVA_LANG_OBJECT } -+ if (!hasObject && element.toString() != CommonClassNames.JAVA_LANG_OBJECT) { -+ javac.JAVA_LANG_OBJECT?.let { add(it.element.asType()) }",Should we do it if a class already has a super class?,Please add a license header he -19,"@@ -0,0 +1,104 @@ ++ when (x) { ++ ""abz]"" -> return ""abz"" ++ ""ghi"" -> return ""ghi"" ++ ""aby|"" -> return ""aby"" ++ ""abz]"" -> return ""fail"" ++ ""xyz"" -> return ""xyz""",Please add box test for this case similar to original one in compiler/testData/codegen/box/when/stringOptimization/duplicatingItemsSameHashCode.kt,Would it be possible to add `import ko +78,"@@ -0,0 +1,2 @@ ++// ""Change type argument list to <*>"" ""true"" ++fun isStringList(list : Any?) = list is (List<String>)","At first, I've added the parentheses because this way it's more readable to me. But as I was trying to implement the quickfix I realised that it would be possible to make mistake in this case: change ""(List)"" to ""List<*>"". That's why I left the parentheses in one test case. +",This should be `list : Any` +79,"@@ -0,0 +1,2 @@ ++// WITH_RUNTIME ++val s = ""\n foo\n bar\n"".trimIndent()","Why not `""foo\nbar""` here without `trimIndent`?",Please use spaces instead of tabs for +80,"@@ -0,0 +1,2 @@ ++fun box(): String =",Please also add bytecode test or convert this one to it: use as example compiler/testData/codegen/bytecodeText/conditions/ tests,what is the type of `String`? is it `Function`? +81,"@@ -0,0 +1,20 @@ ++// Checks that accessor 'I$Companion.access$getBar\$p' is always used because the property is kept ++// into the companion object. ++ ++interface I { ++ companion object { ++ private val bar = ""Companion Field from I""","Let's make this a `var` in this test, call the setter and test that there are 2 `PUTSTATIC`s",Companion Field from I$Companion.access$getBar\ +82,"@@ -0,0 +1,202 @@ ++ /*",Nit: Formatting is off,Please remove this file. +83,"@@ -0,0 +1,203 @@ ++/*","As far as I understand these functions are copies of functions at KotlinBuilder. Why not to reuse them at KotlinBuilder? I mean, these functions are in build common, so their originals from KotlinBuilder can be removed. +",Please remove this file. +84,"@@ -0,0 +1,21 @@ +/* -+ * 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. ++ * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license ++ * that can be found in the license/LICENSE.txt file. + */ + -+package org.jetbrains.kotlin.wrappers.symbols -+ -+import com.intellij.psi.CommonClassNames -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.load.java.structure.* -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.Name -+import org.jetbrains.kotlin.name.SpecialNames -+import javax.lang.model.element.ElementKind -+import javax.lang.model.element.ExecutableElement -+import javax.lang.model.element.TypeElement -+import javax.lang.model.element.VariableElement -+import javax.lang.model.type.NoType -+import javax.lang.model.type.TypeKind -+ -+class JavacClass(element: T, -+ javac: Javac) : JavacClassifier(element, javac), JavaClass { -+ -+ override val name -+ get() = SpecialNames.safeIdentifier(element.simpleName.toString()) -+ -+ override val isAbstract -+ get() = element.isAbstract -+ -+ override val isStatic -+ get() = element.isStatic ++package test.js + -+ override val isFinal -+ get() = element.isFinal ++import kotlin.test.* + -+ override val visibility -+ get() = element.getVisibility() ++class StringsJsTest {",Better to move common tests into `libraries/stdlib/test/text/StringTest.kt` instead of duplicating them for each platform.,"Perhaps we should just delete this file, it doe" +85,"@@ -0,0 +1,21 @@ ++// Checks that methods 'access$getMy$p' and 'getMy' are not generated and ++// that backed field 'my' is accessed through 'access$getMy$cp' + -+ override val typeParameters: List -+ get() = element.typeParameters.map { JavacTypeParameter(it, javac) } -+ -+ override val fqName -+ get() = FqName(element.qualifiedName.toString()) -+ -+ override val supertypes -+ get() = element.interfaces.toMutableList().apply { -+ if (element.superclass !is NoType) add(element.superclass) -+ -+ val hasObject = !none { it.toString() == CommonClassNames.JAVA_LANG_OBJECT } -+ if (!hasObject && element.toString() != CommonClassNames.JAVA_LANG_OBJECT) { -+ javac.JAVA_LANG_OBJECT?.let { add(it.element.asType()) } -+ } -+ }.map { JavacClassifierType(it, javac) } -+ -+ override val innerClasses -+ get() = element.enclosedElements -+ .filter { it.asType().kind == TypeKind.DECLARED } -+ .filterIsInstance(TypeElement::class.java) -+ .map { JavacClass(it, javac) } ++class My { ++ companion object { ++ private val my: String = ""OK"" + -+ override val outerClass: JavaClass? -+ get() = element.enclosingElement?.let { -+ if (it.asType().kind != TypeKind.DECLARED) null else JavacClass(it as TypeElement, javac) ++ fun test(): String { ++ // accessor is required because field is move to Foo ++ return my + } ++ } + -+ override val isInterface -+ get() = element.kind == ElementKind.INTERFACE ++ fun getMyValue() = test() ++} + -+ override val isAnnotationType -+ get() = element.kind == ElementKind.ANNOTATION_TYPE ++// 1 GETSTATIC My.my ++// 1 PUTSTATIC My.my",Let's remove this line since it's irrelevant to what we're testing here,This test case depends on how `getMy$p` and `ge +86,"@@ -0,0 +1,21 @@ ++//method","You need to include the generated test class into your commit. +",This file has nothing to do with this PR. +87,"@@ -0,0 +1,21 @@ ++//method ++void foo() {","Please try to ensure that testdata files are valid Java code. This file does not compile ('status' is undefined, the types do not match, etc.) +",missing new line at the end of file +88,"@@ -0,0 +1,21 @@ ++//method ++void foo() { ++ switch (status) { ++ case ""init"": ++ case ""dial"": ++ case ""transmit"": ++ return Color.BLACK; + -+ override val isEnum -+ get() = element.kind == ElementKind.ENUM ++ case ""ok"": ++ return 0xFF006600; + -+ override val lightClassOriginKind = null ++ case ""cancel"": ++ return 0xFF666666; + -+ override val methods: Collection -+ get() = element.enclosedElements","Here (and for many other properties) getters are in use. Are you sure this property is read just a few times and we do not spend too much time here? As a possible alternative, you can use `by lazy`.",Please add a license header he -20,"@@ -0,0 +1,105 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ ++ case ""fail"": ++ case ""busy"": ++ case ""error"":","Please add a test for the case when 'default' is in the middle of the list of other cases (`case ""error"": default: case ""busy:""`) and make sure that this test passes. +",Rather than using the enum values for the statu +89,"@@ -0,0 +1,22 @@ ++// TARGET_BACKEND: JVM_IR","@ting-yuan Please add box tests for comparisonFalse/comparisonTrue +",This seems unrelated to the rest of the PR. +90,"@@ -0,0 +1,22 @@ ++package demo + -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.codeInsight.template.TemplateBuilder; -+import com.intellij.codeInsight.template.TemplateBuilderFactory; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.project.Project; -+import com.intellij.psi.PsiDocumentManager; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.refactoring.rename.inplace.MyLookupExpression; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.descriptors.ClassDescriptor; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1; -+import org.jetbrains.jet.lang.psi.*; -+import org.jetbrains.jet.plugin.JetBundle; ++import com.google.common.primitives.Ints ++import com.google.common.base.Joiner ++import java.util.ArrayList + -+import java.util.Collection; -+import java.util.LinkedHashSet; ++class KotlinGreetingJoiner(val greeter : Greeter) { + -+public class MapPlatformClassToKotlinFix extends JetIntentionAction { -+ LinkedHashSet possibleTypes; ++ val names = ArrayList() + -+ public MapPlatformClassToKotlinFix(@NotNull JetUserType element, LinkedHashSet possibleTypes) { -+ super(element); -+ this.possibleTypes = possibleTypes; ++ fun addName(name : String?): Unit{ ++ names.add(name) + } + -+ @NotNull -+ @Override -+ public String getText() { -+ return possibleTypes.size() == 1 -+ ? JetBundle.message(""map.platform.class.to.kotlin"", element.getText(), possibleTypes.iterator().next()) -+ : JetBundle.message(""map.platform.class.to.kotlin.multiple"", element.getText()); ++ fun getJoinedGreeting() : String? { ++ val joiner = Joiner.on("" and "").skipNulls();","why do we need guava in such simple example? we can replace ugly `Joiner.on("" and "").skipNulls().join(names)` with `names.filterNotNull().joinToString("" and "")`. We also don't need `com.google.common.primitives.Ints` at all... +",You can remove this and use `new ArrayList 1) { -+ PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument()); -+ TemplateBuilder builder = TemplateBuilderFactory.getInstance().createTemplateBuilder(replacedElement); -+ builder.replaceElement(replacedElement, new MyLookupExpression(replacedElement.getText(), possibleTypes, null, false, getText())); -+ builder.run(editor, true); -+ } -+ } ++fun getB() = true + -+ public static JetIntentionActionFactory createFactory() { -+ return new JetIntentionActionFactory() { -+ @Nullable -+ @Override -+ public IntentionAction createAction(Diagnostic diagnostic) { -+ JetUserType type = QuickFixUtil.getParentElementOfType(diagnostic, JetUserType.class); -+ if (type == null) return null; -+ -+ if (!(diagnostic instanceof DiagnosticWithParameters1)) return null;","It would be better to assert type of diagnostic.getFactory() at the begining, and cast diagnostic to DiagnosticWithParameters1>. See AddStarProjectionsFix. Don't forget to supress unchecked warning in this case. -",Add a license to the top of al -21,"@@ -0,0 +1,105 @@ -+ -+ -+ 4.0.0 -+ -+ org.jetbrains.kotlin.it -+ test-helloworld -+ 1.0 -+ Test Hello World project -+ -+ -+ Test the kotlin-maven-plugin:compile goal on HelloWorld project. -+ -+ -+ -+ 0.1-SNAPSHOT -+ -+ -+ -+ -+ junit -+ junit -+ 4.9 -+ -+ -+ -+ -+ -+ ${project.basedir}/src/main/kotlin -+ -+ -+ -+ -+ kotlin-maven-plugin -+ org.jetbrains.kotlin -+ ${kotlin.version} -+ -+ -+ compile -+ process-sources -+ -+ compile -+ -+ -+ -+ test-compile -+ process-test-sources -+ -+ test-compile -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ jetbrains-release -+ http://repository.jetbrains.com/releases -+ -+ true -+ -+ -+ false -+ -+ -+ -+ jetbrains-snapshots -+ http://repository.jetbrains.com/kotlin-snapshots -+ -+ false -+ -+ -+ true -+ -+ -+ -+ -+ -+ ","Do we need all those repositories here? -",Could you remove this file fro -22,"@@ -0,0 +1,107 @@ -+/* -+ * Copyright 2010-2015 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ ++fun getC() = false + -+package org.jetbrains.kotlin.idea.findUsages.handlers ++fun getD() = true + -+import com.intellij.find.findUsages.FindUsagesHandler -+import com.intellij.find.findUsages.FindUsagesOptions -+import com.intellij.openapi.util.TextRange -+import com.intellij.psi.PsiElement -+import com.intellij.psi.PsiReference -+import com.intellij.psi.search.GlobalSearchScope -+import com.intellij.psi.search.SearchScope -+import com.intellij.usageView.UsageInfo -+import com.intellij.util.Processor -+import org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesHandlerFactory -+import org.jetbrains.kotlin.idea.util.application.runReadAction ++// LINENUMBER: TestKt.box():3 TestKt.getA():13 TestKt.box():3 TestKt.box():4 TestKt.getB():15 TestKt.box():4 TestKt.box():5","Sorry for delay. +I would prefer to have tests in next format: +// LINENUMBERS +// TestKt.box():3 +// TestKt.getA():13 +// TestKt.box():3 +// TestKt.box():4 +// TestKt.getB():15 +// TestKt.box():4 +// TestKt.box():5 +...",This test case depends on the presence of the ` +95,"@@ -0,0 +1,25 @@ ++// TARGET_BACKEND: JVM ++// The non-IR backend attempts to call a non-existent accessor in class Test.",@pyos Could you file an issue for this? With test name note,The test is failing because of the missing `;` +96,"@@ -0,0 +1,26 @@ ++import kotlin.test.assertEquals + -+import java.util.ArrayList -+import java.util.Collections ++fun test1() { ++ val u = when (true) { ++ true -> 42 ++ else -> 1.0 ++ } + -+public abstract class KotlinFindUsagesHandler(psiElement: T, -+ private val elementsToSearch: Collection, -+ public val factory: KotlinFindUsagesHandlerFactory) -+ : FindUsagesHandler(psiElement) { ++ assertEquals(42, u) ++} + -+ @suppress(""UNCHECKED_CAST"") -+ public fun getElement(): T { -+ return getPsiElement() as T ++fun test2() { ++ val u = 1L.let { ++ when (it) { ++ is Long -> if (it.toLong() == 2L) it.toLong() else it * 2 // CompilationException ++ else -> it.toDouble() ++ } + } + -+ public constructor(psiElement: T, factory: KotlinFindUsagesHandlerFactory) : this(psiElement, emptyList(), factory) { -+ } ++ assertEquals(1L, u) ++} + -+ override fun getPrimaryElements(): Array { -+ return if (elementsToSearch.isEmpty()) -+ arrayOf(getPsiElement()) -+ else -+ elementsToSearch.toTypedArray() -+ } ++fun box(): String { ++ return ""OK""","what about test1, test2 call? +",This test doesn't seem to test anything related to kotlin. +97,"@@ -0,0 +1,27 @@ ++// Checks that accessor methods are always used due to the overriding of the default setter of 'my' property. + -+ protected fun searchTextOccurrences(element: PsiElement, processor: Processor, options: FindUsagesOptions): Boolean { -+ val scope = options.searchScope ++class My { ++ companion object { ++ private var my: String = ""OK"" ++ set(value) { field = value } ++ } + -+ val searchText = options.isSearchForTextOccurrences && scope is GlobalSearchScope","If you inline this variable, you can get rid of `as` operators below. -",Please annotate with `@Functio -23,"@@ -0,0 +1,107 @@ ++ fun getMyValue(): String { ++ // GETSTATIC for the companion object",What do you mean by this comment?,missing semicolon at the end of the line +98,"@@ -0,0 +1,28 @@ ++// TARGET_BACKEND: JVM","Looks like this test doesn't check what was tested previously in `testNoAssertionsForKotlinFromBinary`: that there are no assertions on calls to Kotlin declarations from dependencies. I'm afraid we'll have to keep that test until we have the necessary infrastructure to migrate it, namely multi-module bytecode text tests.",This seems unrelated to the rest of the PR. +99,"@@ -0,0 +1,29 @@ +/* -+ * Copyright 2010-2015 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. ++ * Copyright 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.findUsages.handlers -+ -+import com.intellij.find.findUsages.FindUsagesHandler -+import com.intellij.find.findUsages.FindUsagesOptions -+import com.intellij.openapi.util.TextRange -+import com.intellij.psi.PsiElement -+import com.intellij.psi.PsiReference -+import com.intellij.psi.search.GlobalSearchScope -+import com.intellij.psi.search.SearchScope -+import com.intellij.usageView.UsageInfo -+import com.intellij.util.Processor -+import org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesHandlerFactory -+import org.jetbrains.kotlin.idea.util.application.runReadAction ++package org.jetbrains.kotlin.idea.actions + -+import java.util.ArrayList -+import java.util.Collections ++import com.intellij.ide.fileTemplates.FileTemplate ++import com.intellij.psi.PsiDirectory ++import com.intellij.psi.PsiFile + -+public abstract class KotlinFindUsagesHandler(psiElement: T, -+ private val elementsToSearch: Collection, -+ public val factory: KotlinFindUsagesHandlerFactory) -+ : FindUsagesHandler(psiElement) { ++const val KOTLIN_WORKSHEET_EXTENSION: String = ""ws.kts"" ++const val KOTLIN_SCRIPT_EXTENSION = ""kts""",There is KotlinParserDefinition.STD_SCRIPT_SUFFIX property,Perhaps we should call it `KOTLIN_WORKSHEET_EXTENSIONS` in +100,"@@ -0,0 +1,29 @@ ++package org.jetbrains.kotlin.library","@alexander-gorshenev Please add copyright to all new files (use ""Update Copyright"" IntelliJ action on the module)",Do we really need this package? I thought we were moving a +101,"@@ -0,0 +1,3 @@ ++// INTENTION_TEXT: ""Convert to sealed class""","Since you aren't changing the intention text dynamically, there's no need to include INTENTION_TEXT in testdata files.",The `intention-text` constant is already defined in the `e +102,"@@ -0,0 +1,3 @@ ++@JvmStatic","The template shows a top-level method, not a method inside an `object`. Please update it to show what the intention action actually does.",This will need to be added to the `JvmBUILD` file so that +103,"@@ -0,0 +1,3 @@ ++[3] + -+ @suppress(""UNCHECKED_CAST"") -+ public fun getElement(): T { -+ return getPsiElement() as T -+ } ++[3, 5]","Please update this file to be exactly the result of your intention on `before.kt.template`. Also you can use `` tag to highlight the place where the user should put his attention +",Can you add a trailing comma to avoid issues later on when +104,"@@ -0,0 +1,3 @@ ++for ((i,x) in foo.withIndices()) {","Please add a whitespace after the comma +","E302 expected 2 blank lines, found 1" +105,"@@ -0,0 +1,3 @@ ++fun foo(a: String?, b: String?) { ++ a?.equals(b) ?: b.identityEquals(null) ++}","Please, add test for the case of non-nullable receiver +",does this test fail on windows because the string is `null +106,"@@ -0,0 +1,3 @@ ++fun foo(s: String) { ++ (s)",Have you investigated why caret position is not before `()`?,This is a syntax error. The parenthesis should be on the n +107,"@@ -0,0 +1,3 @@ ++fun foo(x: Boolean) : Boolean { ++ return x || x || x","This behavior is objectionable: order of predicates evaluation can change program behavior, when evaluated expressions have side effects. I'll disable intention in this case. +",This is a regression I am introducing for the `Boolean` ty +108,"@@ -0,0 +1,3 @@ ++fun test1() { ++ val s = ""foobar""","should the caret maybe placed to the same place, i.e. +```kotlin +""foobar"" +```",This should be `val s = ();` +109,"@@ -0,0 +1,30 @@ ++/*","Consider merging small and relevant declarations together into one file, e.g. `JavaType` implementations into `symbolBasedTypes.kt`, `JavaAnnotationArgument` implementations into `symbolBasedAnnotationArguments.kt` and so on. I think it'd be more readable in the end",Please remove this file. +110,"@@ -0,0 +1,30 @@ ++package a + -+ public constructor(psiElement: T, factory: KotlinFindUsagesHandlerFactory) : this(psiElement, emptyList(), factory) { -+ } ++class A { ++ companion object { ++ const val constInt: Int = 0",I'm not sure but maybe we need also tests non const vals?,missing new line. +111,"@@ -0,0 +1,304 @@ ++# Function Types in Kotlin on JVM + -+ override fun getPrimaryElements(): Array { -+ return if (elementsToSearch.isEmpty()) -+ arrayOf(getPsiElement()) -+ else -+ elementsToSearch.toTypedArray() -+ } ++## Goals + -+ protected fun searchTextOccurrences(element: PsiElement, processor: Processor, options: FindUsagesOptions): Boolean { -+ val scope = options.searchScope ++* Get rid of 23 hardwired physical function classes. One of the problems with them is that they should be effectively duplicated in reflection which means a lot of physical classes in the runtime.","""in the runtime"" -> ""at runtime""? +Имеется в виду ""во время выполнения программы""? +",Is there a way to mark these as deprecated? I don't think +112,"@@ -0,0 +1,304 @@ ++# Function Types in Kotlin on JVM + -+ val searchText = options.isSearchForTextOccurrences && scope is GlobalSearchScope ++## Goals + -+ if (searchText) { -+ if (options.fastTrack != null) {","If you revert this condition, you can get rid of `else`. -",Please annotate with `@Functio -24,"@@ -0,0 +1,108 @@ ++* Get rid of 23 hardwired physical function classes. One of the problems with them is that they should be effectively duplicated in reflection which means a lot of physical classes in the runtime. ++* Make extension functions coercible to normal functions (with an extra parameter), so that it's possible to do `listOfStrings.map(String::length)`","""coercible"" usually assumes some transformation of the value representation to fit to a new type. If it's exactly the same object, just viewed as an instance of a new type, then maybe it would be better to say ""implicitly convertible"" or ""assignable""? +",Does it mean that they are now duplicated? Is that what we want? +113,"@@ -0,0 +1,33 @@ +/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. ++ * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license ++ * that can be found in the license/LICENSE.txt file. + */ + -+package org.jetbrains.jet.plugin.quickfix; ++package samples.misc + -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.project.Project; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.descriptors.ClassDescriptor; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.psi.JetClass; -+import org.jetbrains.jet.lang.resolve.BindingContext; -+import org.jetbrains.jet.lang.resolve.BindingContextUtils; -+import org.jetbrains.jet.lang.types.JetType; -+import org.jetbrains.jet.lexer.JetKeywordToken; -+import org.jetbrains.jet.lexer.JetToken; -+import org.jetbrains.jet.plugin.JetBundle; -+import org.jetbrains.jet.plugin.caches.resolve.KotlinCacheManager; -+ -+import static org.jetbrains.jet.lexer.JetTokens.FINAL_KEYWORD; -+import static org.jetbrains.jet.lexer.JetTokens.OPEN_KEYWORD; -+ -+public class FinalSupertypeFix extends JetIntentionAction { -+ private final JetClass childClass; -+ private JetClass superClass; -+ -+ public FinalSupertypeFix(@NotNull JetClass childClass) { -+ super(childClass); -+ this.childClass = childClass; -+ } ++import samples.Sample ++import samples.assertPrints + -+ @Override -+ public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { -+ if (!super.isAvailable(project, editor, file)) { -+ return false; -+ } ++class Repeat { + -+ BindingContext context = KotlinCacheManager.getInstance(project).getDeclarationsFromProject(project).getBindingContext(); -+ ClassDescriptor childClassDescriptor = context.get(BindingContext.CLASS, childClass); -+ if (childClassDescriptor == null) { -+ return false; -+ } -+ for (JetType supertype: childClassDescriptor.getTypeConstructor().getSupertypes()) { -+ ClassDescriptor superClassDescriptor = (ClassDescriptor) supertype.getConstructor().getDeclarationDescriptor(); -+ if (superClassDescriptor == null) { -+ continue; -+ } -+ PsiElement boundElement = BindingContextUtils.descriptorToDeclaration(context, superClassDescriptor); -+ if (boundElement instanceof JetClass) {","Why do you call it ""bound element""? -",Rather than use a package-priv -25,"@@ -0,0 +1,108 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ ++ @Sample ++ fun repeatAnyTimes() {","It would be nice to start with a sample where `it` is not used, as it's the most common use of `repeat`",this sample doesn't appear to be used +114,"@@ -0,0 +1,33 @@ ++// DONT_RUN_GENERATED_CODE: JS",Seems this and next one tests are redundant,This file should be removed. +115,"@@ -0,0 +1,33 @@ ++// DONT_RUN_GENERATED_CODE: JS + -+package org.jetbrains.jet.plugin.quickfix; ++var counter = 0 ++fun inc() = counter++ + -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.project.Project; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.descriptors.ClassDescriptor; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.psi.JetClass; -+import org.jetbrains.jet.lang.resolve.BindingContext; -+import org.jetbrains.jet.lang.resolve.BindingContextUtils; -+import org.jetbrains.jet.lang.types.JetType; -+import org.jetbrains.jet.lexer.JetKeywordToken; -+import org.jetbrains.jet.lexer.JetToken; -+import org.jetbrains.jet.plugin.JetBundle; -+import org.jetbrains.jet.plugin.caches.resolve.KotlinCacheManager; -+ -+import static org.jetbrains.jet.lexer.JetTokens.FINAL_KEYWORD; -+import static org.jetbrains.jet.lexer.JetTokens.OPEN_KEYWORD; -+ -+public class FinalSupertypeFix extends JetIntentionAction { -+ private final JetClass childClass; -+ private JetClass superClass; -+ -+ public FinalSupertypeFix(@NotNull JetClass childClass) { -+ super(childClass); -+ this.childClass = childClass; -+ } ++tailrec fun test(x: Int = 0, y: Int = inc(), z: Int = inc()) { ++ if (x * 2 != y || z - y != 1) ++ throw IllegalArgumentException() + -+ @Override -+ public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { -+ if (!super.isAvailable(project, editor, file)) { -+ return false; -+ } ++ if (x < 100000) ++ test(x + 1, y + 2, z + 2)","Please switch this one to ~test(x + 1, z = counter + 1)~",what's the purpose of this block? +116,"@@ -0,0 +1,33 @@ ++// WITH_REFLECT ++// IGNORE_BACKEND: JVM_IR ++// TARGET_BACKEND: JVM + -+ BindingContext context = KotlinCacheManager.getInstance(project).getDeclarationsFromProject(project).getBindingContext(); -+ ClassDescriptor childClassDescriptor = context.get(BindingContext.CLASS, childClass); -+ if (childClassDescriptor == null) { -+ return false; -+ } -+ for (JetType supertype: childClassDescriptor.getTypeConstructor().getSupertypes()) { -+ ClassDescriptor superClassDescriptor = (ClassDescriptor) supertype.getConstructor().getDeclarationDescriptor(); -+ if (superClassDescriptor == null) { -+ continue; -+ } -+ PsiElement boundElement = BindingContextUtils.descriptorToDeclaration(context, superClassDescriptor); -+ if (boundElement instanceof JetClass) { -+ superClass = (JetClass) boundElement; -+ if (!superClass.isTrait() && !superClass.isEnum() && superClass.getContainingFile().isWritable()) { -+ return true; -+ } -+ } -+ } -+ return false; -+ } ++// Please make sure that this test is consistent with the diagnostic test ""annotationsTargetingLateinitAccessor.kt"" + -+ @NotNull -+ @Override -+ public String getText() { -+ return JetBundle.message(""add.supertype.modifier"", ""open""); -+ } ++import kotlin.reflect.KAnnotatedElement ++import kotlin.reflect.KProperty",This import is unused,How is this different from what we have in `annotationsTargeting +117,"@@ -0,0 +1,33 @@ ++// WITH_REFLECT ++// IGNORE_BACKEND: JVM_IR ++// TARGET_BACKEND: JVM + -+ @NotNull -+ @Override -+ public String getFamilyName() { -+ return JetBundle.message(""add.supertype.modifier.family""); -+ } ++// Please make sure that this test is consistent with the diagnostic test ""annotationsTargetingLateinitAccessor.kt"" + -+ @Override -+ public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { -+ assert superClass != null; -+ JetToken[] modifiersThanCanBeReplaced = new JetKeywordToken[] { FINAL_KEYWORD }; -+ superClass.replace(AddModifierFix.addModifier(superClass, OPEN_KEYWORD, modifiersThanCanBeReplaced, project, false)); -+ } ++import kotlin.reflect.KAnnotatedElement ++import kotlin.reflect.KProperty + -+ @Nullable","Why is this method nullable? -",Rather than use a package-priv -26,"@@ -0,0 +1,108 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ ++annotation class Ann ++annotation class AnnRepeat","Looks like this annotation is not used here and in the corresponding diagnostic test, let's remove it",Nit: update copyright year in header +118,"@@ -0,0 +1,34 @@ ++// DONT_RUN_GENERATED_CODE: JS ++// IGNORE_BACKEND: JVM + -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.psi.JetFile -+import org.jetbrains.jet.lang.resolve.BindingContext -+import com.intellij.openapi.util.text.StringUtil -+import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor -+import org.jetbrains.jet.renderer.DescriptorRenderer -+import org.jetbrains.jet.lang.types.ErrorUtils -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import com.intellij.psi.PsiWhiteSpace -+import org.jetbrains.jet.plugin.codeInsight.ShortenReferences -+ -+public class MakeTypeExplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.explicit.in.lambda"", javaClass()) { -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ val params = element.getValueParameters() -+ val hasDeclaredParamsType = params.any { it.getTypeReference() != null } -+ val hasDeclaredReturnType = element.hasDeclaredReturnType() -+ val hasDeclaredReceiverType = element.getFunctionLiteral().getReceiverTypeRef() != null -+","Please declare all variables exactly before they are needed. It's usually a bad idea to declare all variables at once and then write the whole logic. A reader might think that the following behavior somehow depends on values of all these variables, while in reality your code should look more like: if doesn't have declared param types, return true; **else** if doesn't have declared return type, return true; **else** and so on. That's a lot easier to grasp, since you don't have to carry a lot of context while reading the code -",Add a license header here. -27,"@@ -0,0 +1,108 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ ++var counter = 0 ++fun inc() = counter++ + -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.psi.JetFile -+import org.jetbrains.jet.lang.resolve.BindingContext -+import com.intellij.openapi.util.text.StringUtil -+import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor -+import org.jetbrains.jet.renderer.DescriptorRenderer -+import org.jetbrains.jet.lang.types.ErrorUtils -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import com.intellij.psi.PsiWhiteSpace -+import org.jetbrains.jet.plugin.codeInsight.ShortenReferences -+ -+public class MakeTypeExplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.explicit.in.lambda"", javaClass()) { -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ val params = element.getValueParameters() -+ val hasDeclaredParamsType = params.any { it.getTypeReference() != null } -+ val hasDeclaredReturnType = element.hasDeclaredReturnType() -+ val hasDeclaredReceiverType = element.getFunctionLiteral().getReceiverTypeRef() != null -+ -+ val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext() -+ val func = context.get(BindingContext.FUNCTION, element.getFunctionLiteral())","There's an inspection here saying that you should use `[]` instead of `get` -",Add a license header here. -28,"@@ -0,0 +1,108 @@ ++tailrec fun test(x: Int = 0, y: Int = inc(), z: Int = inc()) { ++ if (x * 2 != y || z - y != 1) ++ throw IllegalArgumentException()","Please add something like `""x=$x y=$y z=$z""` to the exception message here and in other tests",I think this should be `if (x % 2 != y % 1) throw ...` +119,"@@ -0,0 +1,347 @@ +/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.psi.JetFile -+import org.jetbrains.jet.lang.resolve.BindingContext -+import com.intellij.openapi.util.text.StringUtil -+import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor -+import org.jetbrains.jet.renderer.DescriptorRenderer -+import org.jetbrains.jet.lang.types.ErrorUtils -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import com.intellij.psi.PsiWhiteSpace -+import org.jetbrains.jet.plugin.codeInsight.ShortenReferences -+ -+public class MakeTypeExplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.explicit.in.lambda"", javaClass()) { -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ val params = element.getValueParameters() -+ val hasDeclaredParamsType = params.any { it.getTypeReference() != null } -+ val hasDeclaredReturnType = element.hasDeclaredReturnType() -+ val hasDeclaredReceiverType = element.getFunctionLiteral().getReceiverTypeRef() != null -+ -+ val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext() -+ val func = context.get(BindingContext.FUNCTION, element.getFunctionLiteral()) -+ if (func == null || ErrorUtils.containsErrorType(func)) return false -+ -+ val expectedReturnType = func!!.getReturnType() -+ val expectedReceiverType = func!!.getReceiverParameter()?.getType()","There are warnings saying that `!!` is useless on `func`, since it's been already checked to be non-null. ++ * Copyright 2019 Google LLC. Use of this source code is governed by the Apache 2.0 license","According to our [license](https://github.com/JetBrains/kotlin/tree/master/license), all code in this repository is copyright by JetBrains. Therefore we need our default copyright on all sources. Is there any particular reason why you've changed this to Google LLC?",I don't think there is any reason to create a new file for this. +120,"@@ -0,0 +1,37 @@ ++// WITH_RUNTIME","I see only codegen tests here, and this is quite bad. You should add, at least, some new parsing tests, because you modified the parser (ParsingTestGenerated), and some front-end diagnostics test, because you modified front-end analysis (DiagnosticsTestGenerated).",Can we delete this file? +121,"@@ -0,0 +1,4 @@ ++// ""Add non-null asserted (!!) call"" ""true"" ++fun test(a: Array?): String { ++ return a[0]",This test can be removed,Do we need to have this test for `Array`? +122,"@@ -0,0 +1,4 @@ ++// ERROR: Too many arguments for public final fun get(index: kotlin.Int): kotlin.Int defined in kotlin.Array","I can't seem to fix the source of this error, so I declared it. +",Do we have a test case for this? +123,"@@ -0,0 +1,4 @@ ++// ERROR: Too many arguments for public final fun get(index: kotlin.Int): kotlin.Int defined in kotlin.Array ++fun foo(a: Array, i: Int) { ++ a[i, { }]","This wouldn't work unless the second argument was a function. Is it still possible to give multiple indices to this construct (i.e, `a[i, 2]`)? +","The problem with this is that `foo(a: Array, i: Int)` trans" +124,"@@ -0,0 +1,4 @@ ++// ERROR: Unresolved reference: !in","I don't understand this error. +",Why did you add this error? There's nothing to do with this PR. +125,"@@ -0,0 +1,4 @@ ++// IS_APPLICABLE: false ++fun foo(x: Foo?) { ++ x!!.get(1) ++}","Why not applicable here? `x!![1]` looks pretty okay +",Is this test case going to be affected by the changes in this PR +126,"@@ -0,0 +1,4 @@ ++// PROBLEM: none ++// DISABLE-ERRORS",Looks like switching to `RESTRICTED_RETENTION_FOR_EXPRESSION_ANNOTATION_WARNING` should fix this.,"I think we can remove this error handler now, since the error ha" +127,"@@ -0,0 +1,4 @@ ++OUT: ++OK","This line is not printed in both CI when I run locally. The same happens in `helloAppSuspendMainInMultifileIr`. `helloAppSuspendMainIR`, however, runs OK when I run as a test, but does not print ""${args[0]$args[1]}"" when I compile the file and run it from CLI.",Changes to this file are all unrelated to the PR. +128,"@@ -0,0 +1,4 @@ ++fun foo() {","This test does not test your change yet. You should add comment above (to both this file and after file): -Also these variables don't add much to the readability, it may be a good idea to inline them -",Add a license header here. -29,"@@ -0,0 +1,108 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. +``` +// FIX: expected fix text +``` + +to check that fix text is correct.","Not familiar with this code, but do we need this?" +129,"@@ -0,0 +1,4 @@ ++fun test1() {","Some questions: +* does this work for more than 2 lines, e.g. +```kotlin +val s = ""one"" ++ "", two"" ++ "", three"" +``` +* does it work for non-strings, e.g. +```java +val s = ""x="" + +0 +```",does this belong in this PR? +130,"@@ -0,0 +1,4 @@ ++fun test2() { ++ val foo = ""1"" ++ val s = ""${foo}bar""",I think this is surprising behavior. Lines should be joined into a single expression only if both the left hand side and the right hand side of the concatenation are constants.,missing new line at the end of file. +131,"@@ -0,0 +1,41 @@ ++// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. ++package org.jetbrains.kotlin.idea.debugger.sequence.psi.java ++ ++/** ++ * @author Vitaliy.Bibaev + */ ++class LocationPositiveChainTest : PositiveJavaStreamTest(""location"") {",Why can't we generate this test (and also others) from the test data?,Please add a license to this file +132,"@@ -0,0 +1,41 @@ ++buildscript { ++ ext.antlr4_version = '4.7.1' ++} ++ ++apply plugin: ""antlr"" ++apply plugin: ""kotlin"" + -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.psi.JetFile -+import org.jetbrains.jet.lang.resolve.BindingContext -+import com.intellij.openapi.util.text.StringUtil -+import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor -+import org.jetbrains.jet.renderer.DescriptorRenderer -+import org.jetbrains.jet.lang.types.ErrorUtils -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import com.intellij.psi.PsiWhiteSpace -+import org.jetbrains.jet.plugin.codeInsight.ShortenReferences -+ -+public class MakeTypeExplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.explicit.in.lambda"", javaClass()) { -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ val params = element.getValueParameters() -+ val hasDeclaredParamsType = params.any { it.getTypeReference() != null } -+ val hasDeclaredReturnType = element.hasDeclaredReturnType() -+ val hasDeclaredReceiverType = element.getFunctionLiteral().getReceiverTypeRef() != null -+ -+ val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext() -+ val func = context.get(BindingContext.FUNCTION, element.getFunctionLiteral()) -+ if (func == null || ErrorUtils.containsErrorType(func)) return false -+ -+ val expectedReturnType = func!!.getReturnType() -+ val expectedReceiverType = func!!.getReceiverParameter()?.getType() -+ -+ if (!hasDeclaredReturnType && expectedReturnType != null) return true -+ if (!hasDeclaredReceiverType && expectedReceiverType != null) return true -+ if (!hasDeclaredParamsType && func!!.getValueParameters() != null) return true","There's a warning saying that `getValueParameters` never returns null. Maybe you meant to check if it's non-empty? -",Add a license header here. -30,"@@ -0,0 +1,108 @@ ++configurePublishing(project)",Please preserve the old behavior: the artifact was published only when `idl2k.deploy.skip` property is `false`,"This is not related to this PR, but why do we pat" +133,"@@ -0,0 +1,48 @@ +/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ ++ * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license",2019,I don't think we need to change this file at all. +134,"@@ -0,0 +1,5 @@ ++// ERROR: Unresolved reference: array","I don't understand this error. +",This error shouldn't be reported. +135,"@@ -0,0 +1,5 @@ ++// FILE: 1.kt ++inline fun runReturning(f: () -> Nothing): Nothing = f() ++ ++// FILE: 2.kt ++fun box() = Array(1) { runReturning { return@Array ""OK"" } }[0]","@pyos Could you also add test with several nested inline calls? +e.g.: +` fun box() = Array(1) { run { runReturning { return@Array ""OK"" } }}[0] ` + +and nested calls with capturing +` fun box() { +val result = ""OK"" +Array(1) { run { run { runReturning { return@Array result } }}}[0] +}`","Ah, this is what I was thinking about doing somet" +136,"@@ -0,0 +1,5 @@ ++// MOVE: up ++// IS_APPLICABLE: false ++import foo.Bar ++ ++class A",Add a test for script too,I think this is missing the `// IS_APPLICABLE: fa +137,"@@ -0,0 +1,5 @@ ++// PROBLEM: none ++ ++fun test(a: Any, b: Any) =","Please add also test with explicitly given `Float` or `Double` types, like this: `fun test(a: Double, b: Double) = ...`, and another test with `Double` or `Float` literals, like `fun checkPi(x: Double) = x.equals(3.14) // or 3.14.equals(x)`",Let's add a short docstring here. +138,"@@ -0,0 +1,5 @@ ++// WITH_RUNTIME","Some test when inspection isn't applicable might be useful, I suggest to do one with invalid code `Integer.toString()`, as `isToString()` implicitly suggests that this case won't be resolved to a needed qualified name.",Can we delete this file? +139,"@@ -0,0 +1,5 @@ ++","File name should be `ReplaceJavaIntegerToStringWithMember.html` without ""Inspection"" suffix.","Same here, let's not include this file." +140,"@@ -0,0 +1,5 @@ ++ ++ ++ This intention detects 'Math.max' calls that can be safely replaced with 'coerceAtLeast'","This intention replaces 'Math.max' calls with safe 'coerceAtLeast' ... or something like. Inspection detects, but inspection does some change. +",CoerceAtLeast calls should be wrapped in the `i18 +141,"@@ -0,0 +1,5 @@ ++ ++ ++Reports unnecessary java usage.","This is not clear. A better description would be ""Use of Java API that has a Kotlin equivalent"" or something like that. +",The `html` tag should be removed. +142,"@@ -0,0 +1,5 @@ ++ ++ ++This inspection remove an empty class body","reports and offers to remove +",I think it would be better to use `` instea +143,"@@ -0,0 +1,5 @@ ++ ++ ++This inspection reports a main function should return Unit type.","I'd rephrase this a little bit, like ""a main function with incorrect return type (should be Unit)"" or something like.",I think the problem is with this sentence. I thin +144,"@@ -0,0 +1,5 @@ ++ ++ ++This inspection reports annotation with target 'EXPRESSION' will not be store at retention 'BINARY' or 'RUNTIME'.","Broken English. IMO, `This inspection reports 'EXPRESSION'-targeted annotations with a non-'SOURCE' retention.` (or something like this) would be better.",I think it's better to say: `This inspection reports annotation with target 'BINARY' or 'RUNTIME' will not be stored at retention 'BINARY'`. +145,"@@ -0,0 +1,5 @@ ++ ++ ++This inspection reports explicit calls of Collection constructor calls which can be replaced by function calls from the stdlib.","It's an intention, not an inspection. ",Could you add a period at the end of the sentence? +146,"@@ -0,0 +1,5 @@ ++ ++ ++This inspection reports suspicious collection reassignment by augmented assignment.",I think we need more detailed explanation here.,This inspection report seems to be lacking context (collection reassignment). Maybe that's more relevant? +147,"@@ -0,0 +1,5 @@ ++ ++ ++This inspection reports the redundant backticks in references",the `the` is actually redundant 😆 ,I think it's better to use `` instead of ``. +148,"@@ -0,0 +1,5 @@ ++ ++ ++This inspection reports unused equals expression.",expression**s**,I think it's better to say: This inspection reports unused equals expressions. +149,"@@ -0,0 +1,5 @@ ++ ++ ++This inspection reports unused unary operators.",I'd prefer `This inspection reports unary operators that are not used.`,I think this error message could be clearer about _why_ this inspection is unstable. +150,"@@ -0,0 +1,5 @@ ++ ++ ++This intention adds @Throws annotation.","The message sounds unclear to me. +Can you add some more context, like `This intention adds a @Throws annotation for an exception under the caret`?",It's not clear what this annotation is for. +151,"@@ -0,0 +1,5 @@ ++ ++ ++This intention converts an array parameter to a vararg parameter.","Here and below, please select `vararg` with bold.","It's unclear to me what this means. What do you think about something like ""This intention converts an array parameter to a vararg parameter" +152,"@@ -0,0 +1,5 @@ ++ ++ ++This intention detects 'Math.max' calls that can be safely replaced with 'coerceAtLeast'","inspection +",CoerceAtLeast calls should be wrapped in the `i18n` tag. +153,"@@ -0,0 +1,5 @@ ++ ++ ++This intention detects 'Math.min' calls that can be safely replaced with 'coerceAtMost'","inspection +",Couple of things: 1. The name of this file is a bit misleading. Maybe something like `Math.min` could be changed to `Math.max` to avoid conf +154,"@@ -0,0 +1,5 @@ ++ ++ ++This intention detects an empty class body.","removes +",It's `` instead of `` +155,"@@ -0,0 +1,5 @@ ++ ++ ++This intention makes types explicit in a lambda expression.","A little elaboration won't hurt: `types of parameters, receiver and return type` +",typo: `in a lambda expression` +156,"@@ -0,0 +1,5 @@ ++ ++ ++This intention makes types implicit in a lambda expression","Ditto +",There's a typo in this sentence. +157,"@@ -0,0 +1,5 @@ ++ ++ ++This intention removes labeled return to last expression in a lambda.",from last expression,"I think this text could be improved. Maybe something like ""This intention removes the labeled return value from a lambda.""?" +158,"@@ -0,0 +1,5 @@ ++ ++ ++This intention replaces count() function calls with size.",It should be a description of the inspection. Example: [ReplaceCallWithBinaryOperator](https://github.com/JetBrains/kotlin/blob/master/idea/resources/inspectionDescriptions/ReplaceCallWithBinaryOperator.html) ,"""This intention replaces count() function calls with size() functions.""" +159,"@@ -0,0 +1,5 @@ ++ ++ ++This intention take a qualified call to any function ""get"" which has some arguments and converts it to square brackets.","""takes"" +",There's no `` in this HTML file. +160,"@@ -0,0 +1,5 @@ ++fun box(): String { ++ val sub = Box(-1) ++ println(sub.value == 1L)","replace 'println' with if check +",Don't use `println`. Use `assert` instead. +161,"@@ -0,0 +1,5 @@ ++if (foo()) { ++ bar() ++} else { ++ baz() ++}","The branches aren't swapped in the after-template +",I'm pretty sure this file will need a lice +162,"@@ -0,0 +1,5 @@ ++package org.junit + -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.psi.JetFile -+import org.jetbrains.jet.lang.resolve.BindingContext -+import com.intellij.openapi.util.text.StringUtil -+import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor -+import org.jetbrains.jet.renderer.DescriptorRenderer -+import org.jetbrains.jet.lang.types.ErrorUtils -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import com.intellij.psi.PsiWhiteSpace -+import org.jetbrains.jet.plugin.codeInsight.ShortenReferences -+ -+public class MakeTypeExplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.explicit.in.lambda"", javaClass()) { -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ val params = element.getValueParameters() -+ val hasDeclaredParamsType = params.any { it.getTypeReference() != null } -+ val hasDeclaredReturnType = element.hasDeclaredReturnType() -+ val hasDeclaredReceiverType = element.getFunctionLiteral().getReceiverTypeRef() != null -+ -+ val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext() -+ val func = context.get(BindingContext.FUNCTION, element.getFunctionLiteral()) -+ if (func == null || ErrorUtils.containsErrorType(func)) return false -+ -+ val expectedReturnType = func!!.getReturnType() -+ val expectedReceiverType = func!!.getReceiverParameter()?.getType() -+ -+ if (!hasDeclaredReturnType && expectedReturnType != null) return true -+ if (!hasDeclaredReceiverType && expectedReceiverType != null) return true -+ if (!hasDeclaredParamsType && func!!.getValueParameters() != null) return true -+ -+ return false -+ } ++@Deprecated(""Use 'Ignore' from kotlin.test package"", replaceWith = ReplaceWith(""Ignore"", imports = ""kotlin.test.Ignore"")) ++@Suppress(""HEADER_WITHOUT_IMPLEMENTATION"") ++header annotation class Ignore",I'm working on not needing this...,Why not `import static org.junit.Ignore.*` +163,"@@ -0,0 +1,5 @@ ++val s = ""1"" + ""2"" + 3 + 4L + 5.0 + 6F + '7'","@pyos Please add similar test with const vals instead of const literals + +val c = ""${strConst}...${intConst}.... +",This doesn't seem to be used. +164,"@@ -0,0 +1,50 @@ ++// TARGET_BACKEND: JVM",..and here,This seems unrelated to the rest of the PR +165,"@@ -0,0 +1,53 @@ ++// TARGET_BACKEND: JVM","@sfs Could you also add 'initializerAssertionsDisable.kt' test by 'interfaceAssertionsDisabled.kt/interfaceAssertionsEnabled.kt' analogue? + +Actually compiler also moves all initializer from class companion to outer class. And here is an interesting corner case with assertions. @ilmirus Seems this code is not supported in current backend: +``` +open class Bar { + companion object { + val barAssertionThrown = try { + assert(false) + false + } catch(error: java.lang.AssertionError) { + true + } + } +} +``` + +I don't see any $assertionsDisabled neither in companion nor in Bar. If understand correctly this assertion should be linked with 'Companion.$assertionsDisabled' field and it's initialization should be performed only in companion clinit (that require some trick at least in IR backend cause all initialization is poped up in outer class) or assertions should be linked with 'Bar.$assertionsDisabled' field?",This seems unrelated to the rest of the PR +166,"@@ -0,0 +1,6 @@ ++# ++# Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license ++# that can be found in the license/LICENSE.txt file. ++# ++ ++kotlin.test.junit.TestNGContributor",Package name seems incorrect,Could you remove this file from the PR? +167,"@@ -0,0 +1,6 @@ ++// ""Add 'run' before the lambda expression"" ""true"" ++// ERROR: Unresolved reference: run","You can add WITH_RUNTIME directive so that the `run` function will be resolved correctly. +",The error should be resolved before the la +168,"@@ -0,0 +1,6 @@ ++// ""Remove useless is check"" ""false"" ++fun foo(a: String) { ++ when (1) { ++ is Int -> { }","Well, it's an exceptional case but here we can also do something :). If a condition in when branch is definitely true, we can replace the condition with `else` and delete all subsequent branches because they are unreachable anyway. If the condition is definitely false (add test for this case), we can delete this when branch.",Not sure what the purpose of this test is +169,"@@ -0,0 +1,6 @@ ++// PROBLEM: none","Just to be sure, could you please also add original example from the issue?",Is this intended to be part of this PR? +170,"@@ -0,0 +1,6 @@ ++// PROBLEM: none ++class Test { ++ init { ++ // comment",Seems we can report the warning in this case because block is still redundant (comment can be moved to class body),This looks like it can be deleted. +171,"@@ -0,0 +1,6 @@ ++// PROBLEM: none ++object F { ++ fun equals(other: F?): Boolean {","I think it should be highlighted. +",Nit: the `?` is not needed here +172,"@@ -0,0 +1,6 @@ ++// WITH_RUNTIME ++// IS_APPLICABLE: true + -+ override fun applyTo(element: JetFunctionLiteralExpression, editor: Editor) { -+ val params = element.getFunctionLiteral().getValueParameterList()","You call `element.getFunctionLiteral()` **a lot** in this function. Why not extract it to a named variable? -",Add a license header here. -31,"@@ -0,0 +1,108 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ ++fun Int.foo() { ++ +1","This transformation does not look correct for me. I would expect `this + 1` as a result here, +",I think this file can be removed. +173,"@@ -0,0 +1,6 @@ ++// WITH_RUNTIME ++fun test(list: List) { ++ list.forEach { item -> ++ /* aaa */ println(item); println(item) /* bbb */",Let's move every statement inside lambda to its own line in such cases as we already have multi-line lambda,The `list` argument is not used and can be +174,"@@ -0,0 +1,6 @@ ++//ERROR: Unresolved reference: SortedMap ++fun a(b: SortedMap) { ++ for ((index, c) in b.withIndices()) {","I'm not sure what's happening here because `SortedMap` is not an iterable/stream/array, so it doesn't have `withIndices` extension and the intention should not be applicable on it as well as on `Map` +",nit: this should probably have a `.withInd +175,"@@ -0,0 +1,6 @@ ++class Test {",I think origin test with `this` should also be added.,"Can you remove this file, it doesn't do an" +176,"@@ -0,0 +1,6 @@ ++public class Foo { ++ private native final void nativeMethod()","Please avoid irrelevant syntax errors in testdata. Java does require semicolons :) +",Could you make this `@nativeApi` please? +177,"@@ -0,0 +1,64 @@ ++// WITH_RUNTIME",I'd name this test file `javaObjectType.kt`,Can we delete this file? +178,"@@ -0,0 +1,64 @@ ++// http://jonisalonen.com/2012/from-utf-16-to-utf-8-in-javascript/ ++String.prototype.toUTF8Array = function() {",It's not good practice to hack builtin classes.,Shouldn't this be in the TS file? I don' +179,"@@ -0,0 +1,65 @@ ++// WITH_RUNTIME",I'd name this test file `javaPrimitiveType.kt`,Can we delete this file? +180,"@@ -0,0 +1,66 @@ ++/*",Please fix inspections and reformat this file and `KClassJavaPrimitiveTypeProperty.kt`,Please remove this file. +181,"@@ -0,0 +1,7 @@ ++// ""Replace initializer with getter"" ""true"" + -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.psi.JetFile -+import org.jetbrains.jet.lang.resolve.BindingContext -+import com.intellij.openapi.util.text.StringUtil -+import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor -+import org.jetbrains.jet.renderer.DescriptorRenderer -+import org.jetbrains.jet.lang.types.ErrorUtils -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import com.intellij.psi.PsiWhiteSpace -+import org.jetbrains.jet.plugin.codeInsight.ShortenReferences -+ -+public class MakeTypeExplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.explicit.in.lambda"", javaClass()) { -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ val params = element.getValueParameters() -+ val hasDeclaredParamsType = params.any { it.getTypeReference() != null } -+ val hasDeclaredReturnType = element.hasDeclaredReturnType() -+ val hasDeclaredReceiverType = element.getFunctionLiteral().getReceiverTypeRef() != null -+ -+ val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext() -+ val func = context.get(BindingContext.FUNCTION, element.getFunctionLiteral()) -+ if (func == null || ErrorUtils.containsErrorType(func)) return false -+ -+ val expectedReturnType = func!!.getReturnType() -+ val expectedReceiverType = func!!.getReceiverParameter()?.getType() -+ -+ if (!hasDeclaredReturnType && expectedReturnType != null) return true -+ if (!hasDeclaredReceiverType && expectedReceiverType != null) return true -+ if (!hasDeclaredParamsType && func!!.getValueParameters() != null) return true -+ -+ return false -+ } ++fun String.foo() = ""bar"" + -+ override fun applyTo(element: JetFunctionLiteralExpression, editor: Editor) { -+ val params = element.getFunctionLiteral().getValueParameterList() -+ val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext() -+ val func = context.get(BindingContext.FUNCTION, element.getFunctionLiteral())!!","Ditto (`[]` instead of `get`) -",Add a license header here. -32,"@@ -0,0 +1,108 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ ++interface A { ++ val name = ""The quick brown fox jumps over the lazy dog"".foo()",Neither the existing intention action nor your suggested quickfix handle `var` properties correctly. They should create a stub for the setter with no implementation.,missing new line +182,"@@ -0,0 +1,7 @@ ++// COMPILER_ARGUMENTS: -XXLanguage:+MixedNamedArgumentsInTheirOwnPosition + -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.psi.JetFile -+import org.jetbrains.jet.lang.resolve.BindingContext -+import com.intellij.openapi.util.text.StringUtil -+import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor -+import org.jetbrains.jet.renderer.DescriptorRenderer -+import org.jetbrains.jet.lang.types.ErrorUtils -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import com.intellij.psi.PsiWhiteSpace -+import org.jetbrains.jet.plugin.codeInsight.ShortenReferences -+ -+public class MakeTypeExplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.explicit.in.lambda"", javaClass()) { -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ val params = element.getValueParameters() -+ val hasDeclaredParamsType = params.any { it.getTypeReference() != null } -+ val hasDeclaredReturnType = element.hasDeclaredReturnType() -+ val hasDeclaredReceiverType = element.getFunctionLiteral().getReceiverTypeRef() != null -+ -+ val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext() -+ val func = context.get(BindingContext.FUNCTION, element.getFunctionLiteral()) -+ if (func == null || ErrorUtils.containsErrorType(func)) return false -+ -+ val expectedReturnType = func!!.getReturnType() -+ val expectedReceiverType = func!!.getReceiverParameter()?.getType() -+ -+ if (!hasDeclaredReturnType && expectedReturnType != null) return true -+ if (!hasDeclaredReceiverType && expectedReceiverType != null) return true -+ if (!hasDeclaredParamsType && func!!.getValueParameters() != null) return true -+ -+ return false -+ } ++fun foo(name1: Int, name2: Int, name3: Int) {}","There are also test `namedArgumentsBefore.kt` which might fail now, because by default `MixedNamedArgumentsInTheirOwnPosition` will be enabled in kotlin 1.4 + +Can you please explicitly specify there that `MixedNamedArgumentsInTheirOwnPosition` is disabled in this test (by adding `// COMPILER_ARGUMENTS: -XXLanguage:-MixedNamedArgumentsInTheirOwnPosition`), and add additional test with `MixedNamedArgumentsInTheirOwnPosition` enabled (in which the intention should now work for this case)?","I am just curious, is this file going to" +183,"@@ -0,0 +1,7 @@ ++// COMPILER_ARGUMENTS: -XXLanguage:+MixedNamedArgumentsInTheirOwnPosition + -+ override fun applyTo(element: JetFunctionLiteralExpression, editor: Editor) { -+ val params = element.getFunctionLiteral().getValueParameterList() -+ val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext() -+ val func = context.get(BindingContext.FUNCTION, element.getFunctionLiteral())!! -+ val valueParameters = func!!.getValueParameters() -+ val expectedReturnType = func!!.getReturnType() -+ val expectedReceiverType = func!!.getReceiverParameter()?.getType()","Again, please declare all variables exactly before they are needed. In this function, `expectedReturnType` is only needed in Step 2, so declare it there. `expectedReceiverType` is only needed in Step 3, and so on -",Add a license header here. -33,"@@ -0,0 +1,108 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ ++fun foo(name1: Int, name2: Int, name3: Int) {} + -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.psi.JetFile -+import org.jetbrains.jet.lang.resolve.BindingContext -+import com.intellij.openapi.util.text.StringUtil -+import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor -+import org.jetbrains.jet.renderer.DescriptorRenderer -+import org.jetbrains.jet.lang.types.ErrorUtils -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import com.intellij.psi.PsiWhiteSpace -+import org.jetbrains.jet.plugin.codeInsight.ShortenReferences -+ -+public class MakeTypeExplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.explicit.in.lambda"", javaClass()) { -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ val params = element.getValueParameters() -+ val hasDeclaredParamsType = params.any { it.getTypeReference() != null } -+ val hasDeclaredReturnType = element.hasDeclaredReturnType() -+ val hasDeclaredReceiverType = element.getFunctionLiteral().getReceiverTypeRef() != null -+ -+ val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext() -+ val func = context.get(BindingContext.FUNCTION, element.getFunctionLiteral()) -+ if (func == null || ErrorUtils.containsErrorType(func)) return false -+ -+ val expectedReturnType = func!!.getReturnType() -+ val expectedReceiverType = func!!.getReceiverParameter()?.getType() -+ -+ if (!hasDeclaredReturnType && expectedReturnType != null) return true -+ if (!hasDeclaredReceiverType && expectedReceiverType != null) return true -+ if (!hasDeclaredParamsType && func!!.getValueParameters() != null) return true -+ -+ return false -+ } ++fun usage() {","It seems like there are missing test when `MixedNamedArgumentsInTheirOwnPosition` is enabled, but the arguments are not in their own positions, and the intention should be disabled + +With your code, this case will look like `foo(1, name3 = 3, name2 = 2)` +","I am just curious, why is this test diff" +184,"@@ -0,0 +1,7 @@ ++// ERROR: Unresolved reference: listOf ++fun a() { ++ val b = listOf(1,2,3,4,5)","You should use `// WITH_RUNTIME` directive in this and all other tests where you use standard library functions to avoid errors +",This is an example of a change that shou +185,"@@ -0,0 +1,7 @@ ++// FILE: 1.kt ++// File names are important! This file should come before the other one","There are also other tests that fail with a specific file order, e.g. + +``` +// FILE: 1.kt +fun box() = A.f() +// FILE: 2.kt +object A { + @JvmStatic + fun f(x: String = ""OK"") = x +} +``` + +If having all lowerings do the right thing on both lowered and unlowered inputs is still a goal, perhaps all multi-file tests should run twice (once with the original file names, and once with files renamed to be in reverse order)?","Let's remove this file, it doesn't make " +186,"@@ -0,0 +1,7 @@ ++// IS_APPLICABLE: false ++fun foo() { ++ if (true) { ++ println(""test"") ++ println(""test2"") ++ } ++}","Typo in file name. +",I think you can drop the `is_APPLICABLE` +187,"@@ -0,0 +1,7 @@ ++// LANGUAGE_VERSION: 1.2 ++// PROBLEM: none + -+ override fun applyTo(element: JetFunctionLiteralExpression, editor: Editor) { -+ val params = element.getFunctionLiteral().getValueParameterList() -+ val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext() -+ val func = context.get(BindingContext.FUNCTION, element.getFunctionLiteral())!! -+ val valueParameters = func!!.getValueParameters() -+ val expectedReturnType = func!!.getReturnType() -+ val expectedReceiverType = func!!.getReceiverParameter()?.getType() -+ val parameterString = StringUtil.join(valueParameters, -+ {(descriptor: ValueParameterDescriptor?): String -> -+ """" + descriptor!!.getName() + -+ "": "" + DescriptorRenderer.TEXT.renderType(descriptor!!.getType())","There's a warning here about a useless `!!`: you've already asserted that `descriptor` is non-null on the previous line -",Add a license header here. -34,"@@ -0,0 +1,108 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ ++annotation class Some(vararg val strings: String) + -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.psi.JetFile -+import org.jetbrains.jet.lang.resolve.BindingContext -+import com.intellij.openapi.util.text.StringUtil -+import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor -+import org.jetbrains.jet.renderer.DescriptorRenderer -+import org.jetbrains.jet.lang.types.ErrorUtils -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import com.intellij.psi.PsiWhiteSpace -+import org.jetbrains.jet.plugin.codeInsight.ShortenReferences -+ -+public class MakeTypeExplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.explicit.in.lambda"", javaClass()) { -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ val params = element.getValueParameters() -+ val hasDeclaredParamsType = params.any { it.getTypeReference() != null } -+ val hasDeclaredReturnType = element.hasDeclaredReturnType() -+ val hasDeclaredReceiverType = element.getFunctionLiteral().getReceiverTypeRef() != null -+ -+ val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext() -+ val func = context.get(BindingContext.FUNCTION, element.getFunctionLiteral()) -+ if (func == null || ErrorUtils.containsErrorType(func)) return false -+ -+ val expectedReturnType = func!!.getReturnType() -+ val expectedReceiverType = func!!.getReceiverParameter()?.getType() -+ -+ if (!hasDeclaredReturnType && expectedReturnType != null) return true -+ if (!hasDeclaredReceiverType && expectedReceiverType != null) return true -+ if (!hasDeclaredParamsType && func!!.getValueParameters() != null) return true -+ -+ return false -+ } ++@Some(*arrayOf(""alpha"", ""beta"", ""omega""))","This can be converted into `@Some(*[""alpha"", ""beta"", ""omega""])`",Now that we have `arrayOf` in our test s +188,"@@ -0,0 +1,7 @@ ++// PROBLEM: none ++// ERROR: Assignment operators ambiguity:
public operator fun Collection.plus(element: Int): List defined in kotlin.collections
@InlineOnly public inline operator fun MutableCollection.plusAssign(element: Int): Unit defined in kotlin.collections ++// WITH_RUNTIME ++fun test() { ++ var list = mutableListOf(1) ++ list += 2",Just as an idea: why don't fix it by changing `var` to `val`?,"The two instances of ``, `" +189,"@@ -0,0 +1,7 @@ ++// WITH_RUNTIME + -+ override fun applyTo(element: JetFunctionLiteralExpression, editor: Editor) { -+ val params = element.getFunctionLiteral().getValueParameterList() -+ val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext() -+ val func = context.get(BindingContext.FUNCTION, element.getFunctionLiteral())!! -+ val valueParameters = func!!.getValueParameters() -+ val expectedReturnType = func!!.getReturnType() -+ val expectedReceiverType = func!!.getReceiverParameter()?.getType() -+ val parameterString = StringUtil.join(valueParameters, -+ {(descriptor: ValueParameterDescriptor?): String -> -+ """" + descriptor!!.getName() + -+ "": "" + DescriptorRenderer.TEXT.renderType(descriptor!!.getType()) -+ }, -+ "", ""); -+ -+ // Step 1: make the parameters types explicit -+ val newParameterList = JetPsiFactory.createParameterList(element.getProject(), ""("" + parameterString + "")"")","A nicer way would be to use `makeString`, which allows to pass a prefix and a postfix: -`val parameterString = valueParameters.map { ... }.makeString("", "", ""("", "")"")` -",Add a license header here. -35,"@@ -0,0 +1,108 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ ++var a: String? = ""A"" ++fun main(args: Array) { ++ val a1 = a ++ if (a1 != null) a1.length + 1 ++}","I'd add at least one test with regular (non-redundant) `let` and more tests with redundant `let`, e.g. `a?.let { foo(it) }` and may be something else.",`a1` doesn't need to be defined. +190,"@@ -0,0 +1,7 @@ ++class A (val result: T)",...and test is redundant. there is more correct innerGenericConstuctor.kt with inners,What's the type of `result`? Is this typ +191,"@@ -0,0 +1,7 @@ ++class KotlinClass(): JavaClass({}) {","Please make function literal here non-trivial. +",Can this be deleted? I don't see any cha +192,"@@ -0,0 +1,7 @@ ++fun box(): String {","This test is redundant: lateinit logic exists in localLateinit.kt, non lateinit in exactlyOnceCrossinline.kt and definiteValInitialization.kt",does this type need to be public? +193,"@@ -0,0 +1,8 @@ ++// ""Add parameter to constructor 'Foo'"" ""true"" ++// DISABLE-ERRORS ++enum class Foo(n: Int) { ++ A(1, 2), ++ B(3), ++ C(),","What if we write `C(3, 4)` here? Suppose this `C(3, 4)` will be changed to `C(3, 2)`, which is not correct.",I am not sure this error message +194,"@@ -0,0 +1,8 @@ ++// ""Create method 'get' from usage"" ""true"" ++import java.util.ArrayList + -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.psi.JetFile -+import org.jetbrains.jet.lang.resolve.BindingContext -+import com.intellij.openapi.util.text.StringUtil -+import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor -+import org.jetbrains.jet.renderer.DescriptorRenderer -+import org.jetbrains.jet.lang.types.ErrorUtils -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import com.intellij.psi.PsiWhiteSpace -+import org.jetbrains.jet.plugin.codeInsight.ShortenReferences -+ -+public class MakeTypeExplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.explicit.in.lambda"", javaClass()) { -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ val params = element.getValueParameters() -+ val hasDeclaredParamsType = params.any { it.getTypeReference() != null } -+ val hasDeclaredReturnType = element.hasDeclaredReturnType() -+ val hasDeclaredReceiverType = element.getFunctionLiteral().getReceiverTypeRef() != null -+ -+ val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext() -+ val func = context.get(BindingContext.FUNCTION, element.getFunctionLiteral()) -+ if (func == null || ErrorUtils.containsErrorType(func)) return false -+ -+ val expectedReturnType = func!!.getReturnType() -+ val expectedReceiverType = func!!.getReceiverParameter()?.getType() -+ -+ if (!hasDeclaredReturnType && expectedReturnType != null) return true -+ if (!hasDeclaredReceiverType && expectedReceiverType != null) return true -+ if (!hasDeclaredParamsType && func!!.getValueParameters() != null) return true -+ -+ return false ++class Foo {","Isn't it better to remove type parameter of class to avoid confusing when reading test? Or is it intentional? +",Could you add a license header he +195,"@@ -0,0 +1,8 @@ ++// PROBLEM: none ++class C { ++ companion object { ++ fun foo() {} + } ++} + -+ override fun applyTo(element: JetFunctionLiteralExpression, editor: Editor) { -+ val params = element.getFunctionLiteral().getValueParameterList() -+ val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext() -+ val func = context.get(BindingContext.FUNCTION, element.getFunctionLiteral())!! -+ val valueParameters = func!!.getValueParameters() -+ val expectedReturnType = func!!.getReturnType() -+ val expectedReceiverType = func!!.getReceiverParameter()?.getType() -+ val parameterString = StringUtil.join(valueParameters, -+ {(descriptor: ValueParameterDescriptor?): String -> -+ """" + descriptor!!.getName() + -+ "": "" + DescriptorRenderer.TEXT.renderType(descriptor!!.getType()) -+ }, -+ "", ""); -+ -+ // Step 1: make the parameters types explicit -+ val newParameterList = JetPsiFactory.createParameterList(element.getProject(), ""("" + parameterString + "")"") -+ if (params != null) { -+ params.replace(newParameterList) -+ } -+ else { -+ val openBraceElement = element.getFunctionLiteral().getOpenBraceNode().getPsi() -+ val nextSibling = openBraceElement?.getNextSibling() -+ val whitespaceToAdd = (if (nextSibling is PsiWhiteSpace && nextSibling?.getText()?.contains(""\n"")?: false) -+ nextSibling?.copy()","There's a warning here and on the previous line about a useless `?:` -",Add a license header here. -36,"@@ -0,0 +1,108 @@ -+/* -+ * 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. -+ */ ++fun test() = C.Companion::foo","Please check also the following case: +``` +val obj = C.Companion // PROBLEM: none +```",Companion::foo is not a valid ide +196,"@@ -0,0 +1,8 @@ ++// PROBLEM: none ++interface F ++ ++val f = object : F { ++ fun equals(other: F?): Boolean {",Same as above.,What's the difference between `F` +197,"@@ -0,0 +1,8 @@ ++// WITH_RUNTIME + -+package org.jetbrains.kotlin.wrappers.symbols -+ -+import com.intellij.psi.CommonClassNames -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.load.java.structure.* -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.Name -+import org.jetbrains.kotlin.name.SpecialNames -+import javax.lang.model.element.ElementKind -+import javax.lang.model.element.ExecutableElement -+import javax.lang.model.element.TypeElement -+import javax.lang.model.element.VariableElement -+import javax.lang.model.type.NoType -+import javax.lang.model.type.TypeKind -+ -+class SymbolBasedClass(element: T,",Looks like generic parameter `T` can de dropped here and `element` could just have the type `TypeElement`,No wildcard imports. -37,"@@ -0,0 +1,108 @@ -+/* -+ * 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. -+ */ ++fun test() { ++ listOf(","I think one example may be not enough here. At least, it would be good to test comment preserving for all three `when` branches above.",I think you can delete this test. +198,"@@ -0,0 +1,8 @@ ++// WITH_RUNTIME ++// FIX: Change call to 'map' + -+package org.jetbrains.kotlin.wrappers.symbols -+ -+import com.intellij.psi.CommonClassNames -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.load.java.structure.* -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.Name -+import org.jetbrains.kotlin.name.SpecialNames -+import javax.lang.model.element.ElementKind -+import javax.lang.model.element.ExecutableElement -+import javax.lang.model.element.TypeElement -+import javax.lang.model.element.VariableElement -+import javax.lang.model.type.NoType -+import javax.lang.model.type.TypeKind -+ -+class SymbolBasedClass(element: T, -+ javac: JavacWrapper) : SymbolBasedClassifier(element, javac), JavaClass { -+ -+ override val name -+ get() = SpecialNames.safeIdentifier(element.simpleName.toString())","There's no point in calling `safeIdentifier` on a non-null string, it's the same as simply `Name.identifier`. Maybe you meant to handle the case of anonymous classes? The docs say an empty string will be returned in that case.",Please do not wildcard imp -38,"@@ -0,0 +1,108 @@ -+/* -+ * 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. -+ */ ++fun foo(c: Collection) { ++ c.mapNotNull {","Please add a test with label before lambda: + +``` +c.mapNotNull label@{ + return@label """" +} +```",Is this expected to be a valid us +199,"@@ -0,0 +1,8 @@ ++// WITH_RUNTIME ++import java.io.File + -+package org.jetbrains.kotlin.wrappers.symbols ++fun main(args: Array) { ++ File(""hello-world.txt"").bufferedReader().use { reader -> ++ reader.close()",I'm not sure this a valid fix in general case. This is not a refactoring and what if `close()` throws an exception on the second execution?,This file doesn't have to be incl +200,"@@ -0,0 +1,8 @@ ++enum class E { ++FOO ++fun foo() : Unit { ++FOO.toString() ++} ++public fun name() : String { return """" } ++public fun order() : Int { return 0 } ++} +\ No newline at end of file","The same: code formatting is wrong +",missing new line at the end of fi +201,"@@ -0,0 +1,8 @@ ++fun foo() { ++ if (true) { ++ System.out?.println()",Don't use print in tests,The `if (true)` looks weird. Can +202,"@@ -0,0 +1,8 @@ ++inline fun f(g: (Int) -> Unit) = g(0)","Please split test into two FILE sections (see nearby tests), it will also allow to test inliing against binaries",This appears to be unrelated to t +203,"@@ -0,0 +1,8 @@ ++package kotlin + -+import com.intellij.psi.CommonClassNames -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.load.java.structure.* -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.Name -+import org.jetbrains.kotlin.name.SpecialNames -+import javax.lang.model.element.ElementKind -+import javax.lang.model.element.ExecutableElement -+import javax.lang.model.element.TypeElement -+import javax.lang.model.element.VariableElement -+import javax.lang.model.type.NoType -+import javax.lang.model.type.TypeKind ++/** ++ * This annotation is present for methods generated by the Kotlin compiler ++ */ ++@Retention(AnnotationRetention.RUNTIME) ++@Target(AnnotationTarget.FUNCTION) ++annotation class Generated","Why is this annotation is a part of `runtime.jvm`? And if it supposed to be Jvm only, according to existing naming convention it should be `JvmGenerated` instead",Why did you remove the `@Retentio +204,"@@ -0,0 +1,8 @@ ++var status: String = ""fail""","I beleive it would be good to add comment explaining why ""status"" here is top-level property instead of local variable. +",what is the reason for this chang +205,"@@ -0,0 +1,85 @@ ++// IGNORE_BACKEND: JS",I'd name this test file `javaObjectType.kt`,Was this meant to be committed? +206,"@@ -0,0 +1,9 @@ ++// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. ++package org.jetbrains.kotlin.idea.debugger.sequence.lib ++ ++/** ++ * @author Vitaliy.Bibaev",We do not allow `@author` comments (`CodeConformanceTest#testNoBadSubstringsInProjectCode`).,no need for `@author` +207,"@@ -0,0 +1,9 @@ ++// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. ++package org.jetbrains.kotlin.idea.debugger.sequence.lib ++ ++/** ++ * @author Vitaliy.Bibaev ++ */ ++object LibraryUtil { ++ const val KOTLIN_LANGUAGE_ID = ""kotlin""",What's the purpose of this? You can use `KotlinLanguage.NAME` in Kotlin project.,why does this exist? +208,"@@ -0,0 +1,9 @@ ++// FILE: test.kt ++class AtomicInt(var value: Int) ++object Foo { ++ var field1: Int = 10 ++ val backer2 = AtomicInt(0) ++ var field2: Int ++ get() = backer2.value ++ set(value: Int) { backer2.value = value } ++}","No tests for `@ThreadLocal` singletons. +Also no tests for plain top-level properties.",Can you also add an example to show that `object.value` can be `undefined`? +209,"@@ -0,0 +1,9 @@ ++// FIX: Add explicit Unit return type",Please add `// PROBLEM: ` to one test with JUnit function and one test with main function,Add a TODO to remove this. +210,"@@ -0,0 +1,9 @@ ++// IGNORE_BACKEND: ANY_FIR","Great, thank you!",I'm a bit confused by this. Why is it `ANY_FIRR`? +211,"@@ -0,0 +1,9 @@ ++// IGNORE_BACKEND: JVM","Actually I think it'd be better to avoid adding tests where `JVM` is disabled, and just have these logged in KT-34338 (which I think all of them are already). The reason is that we usually keep the compiler test data as the current production state, and report all cases which don't work as intended to YouTrack, because it somewhat simplifies working with test data. + +I know there are already several tests that pass on JVM_IR and are ignored for JVM, but I don't want that to be the rule. For non-major issues like this one, IMHO it's OK to keep the difference in behavior underspecified, and come back to it only in the future when JVM IR becomes the default backend.",I think this should be removed. +212,"@@ -0,0 +1,9 @@ ++// IS_APPLICABLE: false ++// WITH_RUNTIME ++class A(val _value: Int) { ++ operator fun compareTo(other: Int) = _value.compareTo(other) ++} + -+class SymbolBasedClass(element: T, -+ javac: JavacWrapper) : SymbolBasedClassifier(element, javac), JavaClass { ++fun test(a: A): Boolean { ++ return a >= 0 && a <= 100","My suggested change to KotlinType.isComparable() will break this test, but I think it's OK because this test should be red, and we make no guarantees regarding the behavior of intentions on red code.",The name of this test case is a bit misleading. I would expect a test like +213,"@@ -0,0 +1,9 @@ ++// PROBLEM: none",Shouldn't we suggest the fix?,Is this intended to be part of this PR? +214,"@@ -0,0 +1,9 @@ ++// PROBLEM: none ++fun foo(f: (String?) -> Int) {} ++ ++fun test() { ++ foo { ++ if (it != null) return@foo 1","Please make sure that the inspection is not suggested when using the function expression syntax: +``` +foo(fun(it: String?): Int { + if (it != null) return@foo 1 + return 0 +}) +``` +",Nit: do you mind making this `if (it != null)` for consistency with the res +215,"@@ -0,0 +1,9 @@ ++// PROBLEM: none ++fun test() {","We should convert to +```kotlin +fun test() { + run { + val a = 42 + use(a, a) + } + val a = 33 +} +```",Did you mean to add this to the PR? +216,"@@ -0,0 +1,9 @@ ++// WITH_RUNTIME ++// IS_APPLICABLE: FALSE ++fun String.withIndices(): Int = 42 + -+ override val name -+ get() = SpecialNames.safeIdentifier(element.simpleName.toString()) ++fun foo(s: String) { ++ for (a in s) { + -+ override val isAbstract -+ get() = element.isAbstract ++ } ++}","The test is fine, the naming is not: _overridden_ function is a function declaration in a subclass with the same signature as in the superclass. There are no overridden functions here, `withIndices` is just an extension function +",I think this will fail on older browsers. +217,"@@ -0,0 +1,9 @@ ++// WITH_RUNTIME ++class FooException : Exception() ++ ++class Test { ++ val getter: String ++ @Throws(FooException::class) ++",Suspicious empty line.,"The property is not annotated as `throws`, so this test will fail." +218,"@@ -0,0 +1,9 @@ ++fun test() { ++ val items = listOf() ++ items.forEach { } ++ items.forEach { item -> } ++ items.forEach { doSomething(it) } ++ items.forEach { item -> doSomething(item) } ++}","I'd add some tests with nested `forEach`, to make sure we handle correctly situations with multiple `it`.","Instead of `forEach`, use `forEach(x => x.forEach(x -> doSomething(x))`" +219,"@@ -0,0 +1,9 @@ ++interface B { ++ fun c() ++} + -+ override val isStatic -+ get() = element.isStatic + -+ override val isFinal -+ get() = element.isFinal ++object A : B {",This should be `object a`,I am not sure how this will work. The `B` is not an `interface` so I am not +220,"@@ -0,0 +1,90 @@ ++/* ++ * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license ++ * that can be found in the license/LICENSE.txt file. ++ */ + -+ override val visibility -+ get() = element.getVisibility() ++package org.jetbrains.kotlin.gradle.model; + -+ override val typeParameters -+ get() = element.typeParameters.map { SymbolBasedTypeParameter(it, javac) } ++import org.jetbrains.annotations.NotNull; + -+ override val fqName -+ get() = FqName(element.qualifiedName.toString()) ++import java.io.File; ++import java.util.Collection; + -+ override val supertypes","To be honest, I prefer properties and functions with explicit return type, unless omitting it makes code substantially more readable, which is not the case here, I think (I mean not only this file, but all files added in these commits).",Please add a license heade -39,"@@ -0,0 +1,11 @@ -+// !DIAGNOSTICS: -INVISIBLE_MEMBER -INVISIBLE_REFERENCE -UNUSED_PARAMETER -+// !LANGUAGE: +CalledInPlaceEffect ++/** ++ * Represents a source set for a given Kotlin Gradle project. ++ * @see KotlinProject ++ */ ++public interface SourceSet {","If we rewrite the interfaces in Kotlin, we might get much cleaner implementations, e.g. +```kotlin +interface SourceSet { + val name: String + /* ... */ +} + +data class SourceSetImpl( + override val name: String + /* ... */ +) : SourceSet +```",I'm not sure if this is the correct package for this annotation. +221,"@@ -0,0 +1,91 @@ ++/* ++ * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license ++ * that can be found in the license/LICENSE.txt file. ++ */ + -+import kotlin.internal.* ++package org.jetbrains.kotlin.idea.inspections",A more suitable package is `org.jetbrains.kotlin.idea.inspections.collections`.,package name should start with _idea_ +222,"@@ -0,0 +1,91 @@ ++// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. ++package org.jetbrains.kotlin.idea.debugger.sequence.trace.dsl + -+inline fun myRun(@CalledInPlace(InvocationCount.EXACTLY_ONCE) block: () -> Unit) = block() ++import com.intellij.debugger.streams.trace.dsl.Types ++import com.intellij.debugger.streams.trace.impl.handler.type.* + -+fun throwInLambda(): Int { -+ val x = myRun { throw java.lang.IllegalArgumentException() } -+ return x","Unclear place. First, why `TYPE_MISMATCH`? In this context, `x` should probably have `Nothing` type. Second, `UNREACHABLE_CODE` is expected here. Third, I don't quite understand why it appears after introduction of language features (the last but one commit).",Shouldn't this be in the s -40,"@@ -0,0 +1,11 @@ -+// WITH_RUNTIME -+// IS_APPLICABLE: FALSE -+import java.util.LinkedList ++/** ++ * @author Vitaliy.Bibaev ++ */ ++object KotlinTypes : Types {",I'd rename this object to `SequenceKotlinTypes` or something else as we have a `KotlinType` and `KotlinTypes` will appear in auto-completion.,Isn't there a pattern to have wildcard imports? +223,"@@ -0,0 +1,96 @@ ++fun Int.foo(a: Int = 1,","The correct spelling is `extension` :) +",Can you add a case for `a: Int = 2`? +224,"@@ -1,10 +1,17 @@ +-// IGNORE_BACKEND: JVM_IR + fun f() { + for (c in ""123"") { + print(c) + } + } + ++// Different locals slot numbers are used in JVM vs JVM IR for loop and induction variables. + -+fun Int.withIndices(): List> = LinkedList>() ++// JVM_TEMPLATES + // 1 ISTORE 0\s+L3 + // 1 ILOAD 0\s+INVOKEVIRTUAL java/io/PrintStream.print \(C\)V +-// 1 LOCALVARIABLE c C L3 L.* 0 ++// 1 LOCALVARIABLE c C L3 L\d+ 0 + -+fun foo(s: Int) { -+ for ((index, a) in s.withIndices()) { -+ -+ } -+}","Also please rename this test -",I don't think this test be -41,"@@ -0,0 +1,110 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetCallExpression -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.resolve.BindingContext -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetPrefixExpression -+import org.jetbrains.jet.plugin.codeInsight.ShortenReferences -+import org.jetbrains.jet.lang.psi.JetCallableReferenceExpression -+import org.jetbrains.jet.lang.resolve.DescriptorUtils -+import kotlin.properties.Delegates -+import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns -+import org.jetbrains.jet.lang.psi.JetIfExpression -+import org.jetbrains.jet.plugin.intentions.branchedTransformations.extractExpressionIfSingle -+import org.jetbrains.jet.lang.psi.JetThrowExpression -+import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall -+import org.jetbrains.jet.lang.descriptors.CallableDescriptor -+import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression -+import com.intellij.psi.PsiElement -+import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument -+import org.jetbrains.jet.renderer.DescriptorRenderer -+import org.jetbrains.jet.lang.psi.JetExpression -+import org.jetbrains.jet.lang.psi.JetUserType -+ -+public class ConvertIfWithThrowToAssertIntention : JetSelfTargetingIntention( -+ ""convert.if.with.throw.to.assert"", javaClass()) { -+ -+ private var resolvedCall: ResolvedCall by Delegates.notNull() -+ private var param: ResolvedValueArgument by Delegates.notNull() -+ -+ override fun isApplicableTo(element: JetIfExpression): Boolean { -+ if (element.getElse() != null) return false -+ -+ val thenExpr = element.getThen()?.extractExpressionIfSingle() -+ if (thenExpr !is JetThrowExpression) return false -+ -+ val thrownExpr = getSelector(thenExpr.getThrownExpression()) -+ if (thrownExpr !is JetCallExpression) return false -+ -+ if (thrownExpr.getCalleeExpression()?.getText() != ""AssertionError"") return false -+ -+ val context = AnalyzerFacadeWithCache.getContextForElement(thrownExpr) -+ val nullableResolvedCall = context[BindingContext.RESOLVED_CALL, thrownExpr.getCalleeExpression()] -+ if (nullableResolvedCall == null) return false -+ resolvedCall = nullableResolvedCall -+ -+ val paramAmount = resolvedCall.getValueArguments().size -+ if (paramAmount != 1) return false -+ -+ val paramDescriptor = resolvedCall.getResultingDescriptor().getValueParameters()[0] -+ param = resolvedCall.getValueArguments()[paramDescriptor]!! -+ if (param.toString() == ""null"") return false -+ -+ return DescriptorUtils.getFqName(resolvedCall.getResultingDescriptor()).toString() == ""java.lang.AssertionError."" -+ } -+ -+ private fun getSelector(element: JetExpression?): JetExpression? { -+ if (element is JetDotQualifiedExpression) { -+ return element.getSelectorExpression() -+ } -+ return element -+ } -+ -+ override fun applyTo(element: JetIfExpression, editor: Editor) { -+ val condition = element.getCondition() -+ if (condition == null) return -+ -+ val negatedCondition = JetPsiFactory.createExpression(element.getProject(), ""!true"") as JetPrefixExpression -+ negatedCondition.getBaseExpression()!!.replace(condition) -+ condition.replace(negatedCondition) -+ -+ val newCondition = element.getCondition() as JetPrefixExpression -+ val simplifier = SimplifyNegatedBinaryExpressionIntention() -+ if (simplifier.isApplicableTo(newCondition)) { -+ simplifier.applyTo(newCondition, editor) -+ } -+ -+ val assertText = ""assert(${element.getCondition()?.getText()}, $param)"" -+ val assertExpr = JetPsiFactory.createExpression(element.getProject(), assertText) -+ -+ val newExpr = element.replace(assertExpr) as JetCallExpression -+ if (isCalResolvedToKotlinAssert(newExpr)) return","ShortenReferences was not working for ""kotlin.assert"" it would always process it back to the full ""kotlin.assert"", i tried debugging it for a couple of days but when i couldn't i figured this method should be just as good, I create the element with the short name ""assert"" and then get the resolved call, if it doesn't resolve to ""kotlin.assert"" i replace it with the dot qualified call -",Could you please add a lic -42,"@@ -0,0 +1,111 @@ -+/* -+ * 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.android.quickfix -+ -+import com.intellij.codeInsight.intention.IntentionAction -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiFile -+import org.jetbrains.android.facet.AndroidFacet -+import org.jetbrains.kotlin.descriptors.ClassDescriptor -+import org.jetbrains.kotlin.diagnostics.Diagnostic -+import org.jetbrains.kotlin.diagnostics.Errors.SUPERTYPE_NOT_INITIALIZED -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.idea.core.ShortenReferences -+import org.jetbrains.kotlin.idea.core.replaced -+import org.jetbrains.kotlin.idea.quickfix.KotlinQuickFixAction -+import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory -+import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers -+import org.jetbrains.kotlin.idea.util.addAnnotation -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.psi.* -+import org.jetbrains.kotlin.psi.psiUtil.containingClass -+import org.jetbrains.kotlin.resolve.BindingContext -+import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe -+import org.jetbrains.kotlin.types.KotlinType -+import org.jetbrains.kotlin.types.typeUtil.makeNotNullable -+import org.jetbrains.kotlin.types.typeUtil.supertypes -+ -+class KotlinAndroidViewConstructorFix(element: KtSuperTypeEntry) : KotlinQuickFixAction(element) { -+ -+ override fun getText() = ""Add Android View constructors using '@JvmOverloads'"" -+ override fun getFamilyName() = text -+ -+ override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean { -+ if (AndroidFacet.getInstance(file) == null) return false -+ return super.isAvailable(project, editor, file) -+ } -+ -+ override fun invoke(project: Project, editor: Editor?, file: KtFile) { -+ val element = element ?: return -+ val ktClass = element.containingClass() ?: return -+ -+ val factory = KtPsiFactory(element) -+ -+ val newPrimaryConstructor = factory.createDeclarationByPattern( -+ ""class A constructor(\n $0, $1, $2\n)"", -+ factory.createParameter(""context: android.content.Context""), -+ factory.createParameter(""attrs: android.util.AttributeSet? = null""), -+ factory.createParameter(""defStyleAttr: Int = 0"") -+ ).primaryConstructor ?: return -+ -+ val primaryConstructor = ktClass.createPrimaryConstructorIfAbsent().replaced(newPrimaryConstructor) -+ primaryConstructor.valueParameterList?.let { ShortenReferences.DEFAULT.process(it) } -+ -+ primaryConstructor.addAnnotation(fqNameAnnotation, whiteSpaceText = "" "") -+ -+ element.replace(factory.createSuperTypeCallEntry(element.text + ""(context, attrs, defStyleAttr)"")) -+ } -+ -+ companion object Factory : KotlinSingleIntentionActionFactory() { -+ -+ private val fqNameAnnotation = FqName(""kotlin.jvm.JvmOverloads"") -+ -+ private val requiredConstructorParameterTypes = -+ listOf(""android.content.Context"", ""android.util.AttributeSet"", ""kotlin.Int"") -+ -+ override fun createAction(diagnostic: Diagnostic): IntentionAction? { -+ val superTypeEntry = SUPERTYPE_NOT_INITIALIZED.cast(diagnostic).psiElement -+ -+ val ktClass = superTypeEntry.containingClass() ?: return null -+ if (ktClass.primaryConstructor != null) return null -+ -+ val context = superTypeEntry.analyze() -+ val type = superTypeEntry.typeReference?.let { context[BindingContext.TYPE, it] } ?: return null -+ -+ if (!type.isAndroidView() && type.supertypes().none { it.isAndroidView() }) return null -+ -+ val names = type.constructorParameters() ?: return null -+ if (requiredConstructorParameterTypes !in names) return null -+ -+ return KotlinAndroidViewConstructorFix(superTypeEntry) -+ } -+ -+ private fun KotlinType.isAndroidView(): Boolean { -+ return constructor.declarationDescriptor?.fqNameUnsafe?.asString() == ""android.view.View"" -+ } -+ -+ private fun KotlinType.constructorParameters(): List>? { -+ val classDescriptor = constructor.declarationDescriptor as? ClassDescriptor ?: return null -+ return classDescriptor.constructors.map { -+ it.valueParameters.map { IdeDescriptorRenderers.SOURCE_CODE_NOT_NULL_TYPE_APPROXIMATION.renderType(it.type.makeNotNullable()) } -+ } -+ } -+ }","I suggest minor refactoring -```kotlin -private fun KotlinType.getFqNameAsString() = constructor.declarationDescriptor?.fqNameUnsafe?.asString() - -private fun KotlinType.isAndroidView() = getFqNameAsString() == ""android.view.View"" - -// and we can avoid IdeDescriptorRenderers -// ... - it.valueParameters.map { it.type.getFqNameAsString() } -// ... -} -``` -",Shouldn't this be part of -43,"@@ -0,0 +1,115 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions.attributeCallReplacements -+ -+import org.jetbrains.jet.lang.psi.JetCallExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetQualifiedExpression -+import org.jetbrains.jet.lang.psi.JetExpression -+import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression -+import org.jetbrains.jet.plugin.JetBundle -+import com.intellij.psi.PsiFile -+import org.jetbrains.jet.lang.psi.psiUtil.getParentByTypesAndPredicate -+import com.intellij.openapi.project.Project -+import com.intellij.codeInsight.intention.impl.BaseIntentionAction -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+ -+public abstract class AttributeCallReplacementIntention(val name: String) : BaseIntentionAction() { -+ { -+ setText(getFamilyName()) -+ } -+ -+ protected class Replacement(val target: JetExpression, val text: String) -+ -+ private val elementType = javaClass() -+ -+ abstract protected fun isApplicableToCall(call: JetCallExpression) : Boolean -+ abstract protected fun makeReplacement(element: JetQualifiedExpression, call: JetCallExpression, receiver: JetExpression) : Replacement -+ -+ protected fun getTarget(editor: Editor, file: PsiFile): JetDotQualifiedExpression? { -+ val offset = editor.getCaretModel().getOffset() -+ return file.findElementAt(offset)?.getParentByTypesAndPredicate(false, elementType) { -+ element -> with (element.getSelectorExpression()) {","Is this kosher? -",These action classes are o -44,"@@ -0,0 +1,115 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions.attributeCallReplacements -+ -+import org.jetbrains.jet.lang.psi.JetCallExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetQualifiedExpression -+import org.jetbrains.jet.lang.psi.JetExpression -+import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression -+import org.jetbrains.jet.plugin.JetBundle -+import com.intellij.psi.PsiFile -+import org.jetbrains.jet.lang.psi.psiUtil.getParentByTypesAndPredicate -+import com.intellij.openapi.project.Project -+import com.intellij.codeInsight.intention.impl.BaseIntentionAction -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+ -+public abstract class AttributeCallReplacementIntention(val name: String) : BaseIntentionAction() { -+ { -+ setText(getFamilyName()) -+ } -+ -+ protected class Replacement(val target: JetExpression, val text: String) -+ -+ private val elementType = javaClass() -+ -+ abstract protected fun isApplicableToCall(call: JetCallExpression) : Boolean -+ abstract protected fun makeReplacement(element: JetQualifiedExpression, call: JetCallExpression, receiver: JetExpression) : Replacement -+ -+ protected fun getTarget(editor: Editor, file: PsiFile): JetDotQualifiedExpression? { -+ val offset = editor.getCaretModel().getOffset() -+ return file.findElementAt(offset)?.getParentByTypesAndPredicate(false, elementType) { -+ element -> with (element.getSelectorExpression()) { -+ when (this) { -+ is JetCallExpression -> isApplicableToCall(this) -+ else -> false -+ } -+ } -+ } -+ } -+ -+ public override fun isAvailable(project: Project, editor: Editor, file: PsiFile): Boolean { -+ return with (getTarget(editor, file)) { -+ when(this) { -+ null -> false -+ else -> { -+ updateText(this, this.getSelectorExpression() as JetCallExpression, this.getReceiverExpression()) -+ true -+ } -+ } -+ } -+ } -+ -+ // Override this to manually specify the intention text. -+ protected open fun updateText(element: JetQualifiedExpression, call: JetCallExpression, receiver: JetExpression) { -+ val replacement = makeReplacement(element, call, receiver) -+ val before = replacement.target.getText() -+ val after = replacement.text -+ if (before != null) -+ setText(before, after) -+ } -+ -+ protected fun setText(before: String, after: String) { -+ setText(JetBundle.message(""replace.attribute.call"", before, after)) -+ } -+ -+ -+ public override fun getFamilyName() : String { -+ return JetBundle.message(""replace.attribute.call.family"", name) -+ } -+ -+ public override fun invoke(project: Project, editor: Editor, file: PsiFile): Unit { -+ val target = getTarget(editor, file) -+ assert(target != null, ""Intention is not applicable"") -+ target!! // It matches","There has to be a better way to do this. -",These action classes are o -45,"@@ -0,0 +1,117 @@ -+/* -+ * 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.jvm.compiler -+ -+import com.intellij.openapi.Disposable -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles -+import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment -+import org.jetbrains.kotlin.config.JVMConfigurationKeys -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.renderer.* -+import org.jetbrains.kotlin.resolve.lazy.JvmResolveUtil -+import org.jetbrains.kotlin.test.ConfigurationKind -+import org.jetbrains.kotlin.test.KotlinTestUtils -+import org.jetbrains.kotlin.test.TestCaseWithTmpdir -+import org.jetbrains.kotlin.test.TestJdkKind -+import org.junit.Assert -+ -+import java.io.File -+import java.io.IOException -+import java.lang.annotation.Retention -+ -+import org.jetbrains.kotlin.test.KotlinTestUtils.* -+import org.jetbrains.kotlin.test.util.RecursiveDescriptorComparator.validateAndCompareDescriptorWithFile -+ -+abstract class AbstractCompileJavaAgainstKotlinTest : TestCaseWithTmpdir() { -+ -+ @Throws(IOException::class) -+ protected fun doTest(ktFilePath: String) { -+ Assert.assertTrue(ktFilePath.endsWith("".kt"")) -+ val ktFile = File(ktFilePath) -+ val javaFile = File(ktFilePath.replaceFirst(""\\.kt$"".toRegex(), "".java"")) -+ -+ val javaErrorFile = File(ktFilePath.replaceFirst(""\\.kt$"".toRegex(), "".javaerr.txt"")) -+ -+ val useJavac = true","I'd make this a class property, set it into `false` for old tests and `true` for new tests.",Could you please move `org -46,"@@ -0,0 +1,118 @@ -+/* -+ * 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.wrappers.trees -+ -+import com.intellij.psi.CommonClassNames -+import com.sun.source.tree.Tree -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.code.Flags -+import com.sun.tools.javac.tree.JCTree -+import com.sun.tools.javac.tree.TreeInfo -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.wrappers.symbols.JavacClassifierType -+import org.jetbrains.kotlin.load.java.structure.JavaAnnotation -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.java.structure.JavaClassifierType -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.SpecialNames -+ -+class JCClass(tree: T, -+ treePath: TreePath, -+ javac: Javac) : JCClassifier(tree, treePath, javac), JavaClass { -+ -+ override val name -+ get() = SpecialNames.safeIdentifier(tree.simpleName.toString()) -+ -+ override val annotations: Collection -+ get() = emptyList()",Why?,"Please remove this file, i" -47,"@@ -0,0 +1,118 @@ -+/* -+ * 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.wrappers.trees -+ -+import com.intellij.psi.CommonClassNames -+import com.sun.source.tree.Tree -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.code.Flags -+import com.sun.tools.javac.tree.JCTree -+import com.sun.tools.javac.tree.TreeInfo -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.wrappers.symbols.JavacClassifierType -+import org.jetbrains.kotlin.load.java.structure.JavaAnnotation -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.java.structure.JavaClassifierType -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.SpecialNames -+ -+class JCClass(tree: T, -+ treePath: TreePath, -+ javac: Javac) : JCClassifier(tree, treePath, javac), JavaClass { -+ -+ override val name -+ get() = SpecialNames.safeIdentifier(tree.simpleName.toString()) -+ -+ override val annotations: Collection -+ get() = emptyList() -+ -+ override fun findAnnotation(fqName: FqName) = annotations.find { it.classId?.asSingleFqName() == fqName }",What do you want to find in the empty list (see above)?,Please add `@since` annota -48,"@@ -0,0 +1,118 @@ -+/* -+ * 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.wrappers.trees -+ -+import com.intellij.psi.CommonClassNames -+import com.sun.source.tree.Tree -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.code.Flags -+import com.sun.tools.javac.tree.JCTree -+import com.sun.tools.javac.tree.TreeInfo -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.wrappers.symbols.JavacClassifierType -+import org.jetbrains.kotlin.load.java.structure.JavaAnnotation -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.java.structure.JavaClassifierType -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.SpecialNames -+ -+class JCClass(tree: T, -+ treePath: TreePath, -+ javac: Javac) : JCClassifier(tree, treePath, javac), JavaClass { -+ -+ override val name -+ get() = SpecialNames.safeIdentifier(tree.simpleName.toString()) -+ -+ override val annotations: Collection -+ get() = emptyList() -+ -+ override fun findAnnotation(fqName: FqName) = annotations.find { it.classId?.asSingleFqName() == fqName } -+ -+ override val isAbstract -+ get() = tree.modifiers.isAbstract","Is it true for interfaces? They are abstract without a modifier. I'm not sure should we return `abstract = true` for them, but probably yes.",Please add `@since` annotation here. -49,"@@ -0,0 +1,118 @@ -+/* -+ * 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.wrappers.trees -+ -+import com.intellij.psi.CommonClassNames -+import com.sun.source.tree.Tree -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.code.Flags -+import com.sun.tools.javac.tree.JCTree -+import com.sun.tools.javac.tree.TreeInfo -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.wrappers.symbols.JavacClassifierType -+import org.jetbrains.kotlin.load.java.structure.JavaAnnotation -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.java.structure.JavaClassifierType -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.SpecialNames -+ -+class JCClass(tree: T, -+ treePath: TreePath, -+ javac: Javac) : JCClassifier(tree, treePath, javac), JavaClass { -+ -+ override val name -+ get() = SpecialNames.safeIdentifier(tree.simpleName.toString()) -+ -+ override val annotations: Collection -+ get() = emptyList() -+ -+ override fun findAnnotation(fqName: FqName) = annotations.find { it.classId?.asSingleFqName() == fqName } -+ -+ override val isAbstract -+ get() = tree.modifiers.isAbstract -+ -+ override val isStatic -+ get() = tree.modifiers.isStatic",Probably false if class is nested in interface (see JCField),Please add `@since` annotation here. -50,"@@ -0,0 +1,118 @@ -+/* -+ * 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.wrappers.trees -+ -+import com.intellij.psi.CommonClassNames -+import com.sun.source.tree.Tree -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.code.Flags -+import com.sun.tools.javac.tree.JCTree -+import com.sun.tools.javac.tree.TreeInfo -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.wrappers.symbols.JavacClassifierType -+import org.jetbrains.kotlin.load.java.structure.JavaAnnotation -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.java.structure.JavaClassifierType -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.SpecialNames -+ -+class JCClass(tree: T, -+ treePath: TreePath, -+ javac: Javac) : JCClassifier(tree, treePath, javac), JavaClass { -+ -+ override val name -+ get() = SpecialNames.safeIdentifier(tree.simpleName.toString()) -+ -+ override val annotations: Collection -+ get() = emptyList() -+ -+ override fun findAnnotation(fqName: FqName) = annotations.find { it.classId?.asSingleFqName() == fqName } -+ -+ override val isAbstract -+ get() = tree.modifiers.isAbstract -+ -+ override val isStatic -+ get() = tree.modifiers.isStatic -+ -+ override val isFinal -+ get() = tree.modifiers.isFinal -+ -+ override val visibility -+ get() = tree.modifiers.visibility",Probably false if class is nested in interface (see JCField),Please add `@since` annotation here. -51,"@@ -0,0 +1,118 @@ -+/* -+ * 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.wrappers.trees -+ -+import com.intellij.psi.CommonClassNames -+import com.sun.source.tree.Tree -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.code.Flags -+import com.sun.tools.javac.tree.JCTree -+import com.sun.tools.javac.tree.TreeInfo -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.wrappers.symbols.JavacClassifierType -+import org.jetbrains.kotlin.load.java.structure.JavaAnnotation -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.java.structure.JavaClassifierType -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.SpecialNames -+ -+class JCClass(tree: T, -+ treePath: TreePath, -+ javac: Javac) : JCClassifier(tree, treePath, javac), JavaClass { -+ -+ override val name -+ get() = SpecialNames.safeIdentifier(tree.simpleName.toString()) -+ -+ override val annotations: Collection -+ get() = emptyList() -+ -+ override fun findAnnotation(fqName: FqName) = annotations.find { it.classId?.asSingleFqName() == fqName } -+ -+ override val isAbstract -+ get() = tree.modifiers.isAbstract -+ -+ override val isStatic -+ get() = tree.modifiers.isStatic -+ -+ override val isFinal -+ get() = tree.modifiers.isFinal -+ -+ override val visibility -+ get() = tree.modifiers.visibility -+ -+ override val typeParameters -+ get() = tree.typeParameters.map { JCTypeParameter(it, TreePath(treePath, it), javac) } -+ -+ override val fqName = treePath.reversed() -+ .joinToString(separator = ""."") { -+ (it as? JCTree.JCCompilationUnit)?.packageName?.toString() -+ ?: (it as JCTree.JCClassDecl).name -+ } -+ .let(::FqName) -+ -+ override val supertypes -+ get() = arrayListOf().apply { -+ fun JCTree.mapToJavaClassifierType() = when { -+ this is JCTree.JCExpression -> JCClassifierType(this, TreePath(treePath, this), javac)",Don't quite understand this branch. Do you have some example?,Please add `@since` annotation here. -52,"@@ -0,0 +1,118 @@ -+/* -+ * 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.wrappers.trees -+ -+import com.intellij.psi.CommonClassNames -+import com.sun.source.tree.Tree -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.code.Flags -+import com.sun.tools.javac.tree.JCTree -+import com.sun.tools.javac.tree.TreeInfo -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.wrappers.symbols.JavacClassifierType -+import org.jetbrains.kotlin.load.java.structure.JavaAnnotation -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.java.structure.JavaClassifierType -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.SpecialNames -+ -+class JCClass(tree: T, -+ treePath: TreePath, -+ javac: Javac) : JCClassifier(tree, treePath, javac), JavaClass { -+ -+ override val name -+ get() = SpecialNames.safeIdentifier(tree.simpleName.toString()) -+ -+ override val annotations: Collection -+ get() = emptyList() -+ -+ override fun findAnnotation(fqName: FqName) = annotations.find { it.classId?.asSingleFqName() == fqName } -+ -+ override val isAbstract -+ get() = tree.modifiers.isAbstract -+ -+ override val isStatic -+ get() = tree.modifiers.isStatic -+ -+ override val isFinal -+ get() = tree.modifiers.isFinal -+ -+ override val visibility -+ get() = tree.modifiers.visibility -+ -+ override val typeParameters -+ get() = tree.typeParameters.map { JCTypeParameter(it, TreePath(treePath, it), javac) } -+ -+ override val fqName = treePath.reversed() -+ .joinToString(separator = ""."") { -+ (it as? JCTree.JCCompilationUnit)?.packageName?.toString() -+ ?: (it as JCTree.JCClassDecl).name -+ } -+ .let(::FqName) -+ -+ override val supertypes -+ get() = arrayListOf().apply { -+ fun JCTree.mapToJavaClassifierType() = when { -+ this is JCTree.JCExpression -> JCClassifierType(this, TreePath(treePath, this), javac) -+ this is JCTree.JCTypeApply -> JCClassifierTypeWithTypeArgument(this, TreePath(treePath, this), javac) -+ else -> null -+ } -+ -+ tree.extending?.mapToJavaClassifierType()?.let(this::add) -+ tree.implementing?.map { it.mapToJavaClassifierType() }?.filterNotNull()?.let(this::addAll) -+ -+ if (find { it.canonicalText == CommonClassNames.JAVA_LANG_OBJECT } == null) { -+ javac.JAVA_LANG_OBJECT?.let { add(JavacClassifierType(it.element.asType(), javac)) }","Again, do we need it if super class is given explicitly?",Please add `@since` annotation here. -53,"@@ -0,0 +1,118 @@ -+/* -+ * 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.wrappers.trees -+ -+import com.intellij.psi.CommonClassNames -+import com.sun.source.tree.Tree -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.code.Flags -+import com.sun.tools.javac.tree.JCTree -+import com.sun.tools.javac.tree.TreeInfo -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.wrappers.symbols.JavacClassifierType -+import org.jetbrains.kotlin.load.java.structure.JavaAnnotation -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.java.structure.JavaClassifierType -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.SpecialNames -+ -+class JCClass(tree: T, -+ treePath: TreePath, -+ javac: Javac) : JCClassifier(tree, treePath, javac), JavaClass { -+ -+ override val name -+ get() = SpecialNames.safeIdentifier(tree.simpleName.toString()) -+ -+ override val annotations: Collection -+ get() = emptyList() -+ -+ override fun findAnnotation(fqName: FqName) = annotations.find { it.classId?.asSingleFqName() == fqName } -+ -+ override val isAbstract -+ get() = tree.modifiers.isAbstract -+ -+ override val isStatic -+ get() = tree.modifiers.isStatic -+ -+ override val isFinal -+ get() = tree.modifiers.isFinal -+ -+ override val visibility -+ get() = tree.modifiers.visibility -+ -+ override val typeParameters -+ get() = tree.typeParameters.map { JCTypeParameter(it, TreePath(treePath, it), javac) } -+ -+ override val fqName = treePath.reversed() -+ .joinToString(separator = ""."") { -+ (it as? JCTree.JCCompilationUnit)?.packageName?.toString() -+ ?: (it as JCTree.JCClassDecl).name -+ } -+ .let(::FqName) -+ -+ override val supertypes -+ get() = arrayListOf().apply { -+ fun JCTree.mapToJavaClassifierType() = when { -+ this is JCTree.JCExpression -> JCClassifierType(this, TreePath(treePath, this), javac) -+ this is JCTree.JCTypeApply -> JCClassifierTypeWithTypeArgument(this, TreePath(treePath, this), javac) -+ else -> null -+ } -+ -+ tree.extending?.mapToJavaClassifierType()?.let(this::add) -+ tree.implementing?.map { it.mapToJavaClassifierType() }?.filterNotNull()?.let(this::addAll) -+ -+ if (find { it.canonicalText == CommonClassNames.JAVA_LANG_OBJECT } == null) { -+ javac.JAVA_LANG_OBJECT?.let { add(JavacClassifierType(it.element.asType(), javac)) } -+ } -+ } -+ -+ override val innerClasses -+ get() = tree.members -+ .filterIsInstance(JCTree.JCClassDecl::class.java) -+ .map { JCClass(it, TreePath(treePath, it), javac) } -+ -+ override val outerClass -+ get() = (treePath.parentPath.leaf as? JCTree.JCClassDecl)?.let { JCClass(it, treePath.parentPath, javac) } -+ -+ override val isInterface by lazy { tree.modifiers.flags and Flags.INTERFACE.toLong() != 0L }","Here you're using `by lazy` instead of `get`. Why here, and why just here?",Please add `@since` annotation here. -54,"@@ -0,0 +1,12 @@ -+ -+ -+ -+ -+ -+",Not needed,I think the version should be 1.0. W -55,"@@ -0,0 +1,12 @@ -+class A { -+ val a = """" -+ val b = """" -+} -+ -+fun box(): String { -+ val a = A::a.name -+ if (a != ""a"") return ""Fail $a"" -+ val b = A::`b`.name -+ if (b != ""b"") return ""Fail $b"" -+ return ""OK""","This test doesn't check that no classes were generated for the property reference. I don't think it's possible in a `box` test, please try a bytecode listing test instead (`compiler/testData/codegen/bytecodeListing`). - -Also please test constructors and functions -",This isn't necessary. -56,"@@ -0,0 +1,12 @@ -+public class TestingUse { -+ fun test6(funcLitfunc: ((x: Int) -> Int) -> Boolean, innerfunc: (y: Int) -> Int): Unit { -+ val result = funcLitfunc(innerfunc) -+ var num = 0 -+ if (result == true) num = 1 -+ else num = 2","This is a nice test case, but is this code really needed to test your intention? I think it's just confusing... -","How about `TestingUse = (x: Int, y: " -57,"@@ -0,0 +1,120 @@ -+/* -+ * 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.inspections -+ -+import com.intellij.codeInspection.LocalQuickFix -+import com.intellij.codeInspection.ProblemDescriptor -+import com.intellij.codeInspection.ProblemsHolder -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiElementVisitor -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.idea.core.replaced -+import org.jetbrains.kotlin.idea.intentions.branchedTransformations.unwrapBlockOrParenthesis -+import org.jetbrains.kotlin.psi.* -+import org.jetbrains.kotlin.psi.psiUtil.startOffset -+import org.jetbrains.kotlin.resolve.BindingContext -+import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression -+import org.jetbrains.kotlin.resolve.calls.callUtil.getType -+import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator -+import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode -+ -+class ConstantConditionIfInspection : AbstractKotlinInspection() { -+ -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { -+ return object : KtVisitorVoid() { -+ override fun visitIfExpression(expression: KtIfExpression) { -+ super.visitIfExpression(expression) -+ -+ val condition = expression.condition ?: return -+ -+ val context = condition.analyze(BodyResolveMode.PARTIAL) -+ val constantValue = condition.constantBooleanValue(context) ?: return -+ -+ val fixes = mutableListOf() -+ -+ if (expression.branch(constantValue) != null) { -+ fixes += SimplifyFix(constantValue, expression.isUsedAsExpression(context)) -+ } -+ -+ if (!constantValue && expression.`else` == null) { -+ fixes += RemoveFix() -+ } -+ -+ holder.registerProblem(expression, ""Condition of 'if' expression is constant"", *fixes.toTypedArray()) -+ } -+ } -+ } -+ -+ private class SimplifyFix( -+ private val conditionValue: Boolean, -+ private val isUsedAsExpression: Boolean -+ ) : LocalQuickFix { -+ override fun getFamilyName() = ""Simplify expression"" -+ -+ override fun applyFix(project: Project, descriptor: ProblemDescriptor) { -+ val ifExpression = descriptor.psiElement as? KtIfExpression ?: return -+ val caretModel = ifExpression.findExistingEditor()?.caretModel -+ -+ val branch = ifExpression.branch(conditionValue)?.unwrapBlockOrParenthesis() ?: return -+ -+ val lastExpression = -+ if (branch !is KtBlockExpression) {",Probably with `when` it will be more readable,I don't think this file should be in -58,"@@ -0,0 +1,121 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.psi.JetFile -+import org.jetbrains.jet.lang.resolve.BindingContext -+import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor -+import org.jetbrains.jet.renderer.DescriptorRenderer -+import org.jetbrains.jet.lang.types.ErrorUtils -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import com.intellij.psi.PsiWhiteSpace -+import org.jetbrains.jet.plugin.codeInsight.ShortenReferences -+ -+public class MakeTypeExplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.explicit.in.lambda"", javaClass()) { -+ private var hasImplicitReturnType = false -+ private var hasImplicitReceiverType = false","Please don't store any information in mutable `var`s inside your intention: it might cause problems with concurrency. E.g. see what problems Gavin encountered in #411 -",I don't see any references to this c -59,"@@ -0,0 +1,121 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.psi.JetFile -+import org.jetbrains.jet.lang.resolve.BindingContext -+import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor -+import org.jetbrains.jet.renderer.DescriptorRenderer -+import org.jetbrains.jet.lang.types.ErrorUtils -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import com.intellij.psi.PsiWhiteSpace -+import org.jetbrains.jet.plugin.codeInsight.ShortenReferences -+ -+public class MakeTypeExplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.explicit.in.lambda"", javaClass()) { -+ private var hasImplicitReturnType = false -+ private var hasImplicitReceiverType = false -+ -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ throw IllegalStateException(""isApplicableTo(JetExpressionImpl, Editor) should be called instead"") -+ } -+ -+ override fun isApplicableTo(element: JetFunctionLiteralExpression, editor: Editor): Boolean { -+ val openBraceOffset = element.getLeftCurlyBrace().getStartOffset() -+ val closeBraceOffset = element.getRightCurlyBrace()?.getStartOffset() -+ val caretLocation = editor.getCaretModel().getOffset() -+ val paramsTextRange = element.getFunctionLiteral().getValueParameterList()?.getTextRange() -+ val caretIsInParams = if (paramsTextRange != null) {","This can be simplified to `paramsTextRange != null && caretLocation in paramsTextRange` or `paramsTextRange?.contains(caretLocation) ?: false`, whichever you like the most -",Maybe rename this class to `MakeType -60,"@@ -0,0 +1,121 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.psi.JetFile -+import org.jetbrains.jet.lang.resolve.BindingContext -+import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor -+import org.jetbrains.jet.renderer.DescriptorRenderer -+import org.jetbrains.jet.lang.types.ErrorUtils -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import com.intellij.psi.PsiWhiteSpace -+import org.jetbrains.jet.plugin.codeInsight.ShortenReferences -+ -+public class MakeTypeExplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.explicit.in.lambda"", javaClass()) { -+ private var hasImplicitReturnType = false -+ private var hasImplicitReceiverType = false -+ -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ throw IllegalStateException(""isApplicableTo(JetExpressionImpl, Editor) should be called instead"") -+ } -+ -+ override fun isApplicableTo(element: JetFunctionLiteralExpression, editor: Editor): Boolean { -+ val openBraceOffset = element.getLeftCurlyBrace().getStartOffset() -+ val closeBraceOffset = element.getRightCurlyBrace()?.getStartOffset() -+ val caretLocation = editor.getCaretModel().getOffset() -+ val paramsTextRange = element.getFunctionLiteral().getValueParameterList()?.getTextRange() -+ val caretIsInParams = if (paramsTextRange != null) { -+ caretLocation in paramsTextRange -+ } -+ else false -+ -+ if (!(caretLocation == openBraceOffset + 1 || caretLocation == closeBraceOffset || caretIsInParams)) return false","Please convert this to `&&` by DeMorgan, it'll be more readable that way -",Maybe rename this class to `MakeType -61,"@@ -0,0 +1,121 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.psi.JetFile -+import org.jetbrains.jet.lang.resolve.BindingContext -+import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor -+import org.jetbrains.jet.renderer.DescriptorRenderer -+import org.jetbrains.jet.lang.types.ErrorUtils -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import com.intellij.psi.PsiWhiteSpace -+import org.jetbrains.jet.plugin.codeInsight.ShortenReferences -+ -+public class MakeTypeExplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.explicit.in.lambda"", javaClass()) { -+ private var hasImplicitReturnType = false -+ private var hasImplicitReceiverType = false -+ -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ throw IllegalStateException(""isApplicableTo(JetExpressionImpl, Editor) should be called instead"") -+ } -+ -+ override fun isApplicableTo(element: JetFunctionLiteralExpression, editor: Editor): Boolean { -+ val openBraceOffset = element.getLeftCurlyBrace().getStartOffset() -+ val closeBraceOffset = element.getRightCurlyBrace()?.getStartOffset() -+ val caretLocation = editor.getCaretModel().getOffset() -+ val paramsTextRange = element.getFunctionLiteral().getValueParameterList()?.getTextRange() -+ val caretIsInParams = if (paramsTextRange != null) { -+ caretLocation in paramsTextRange -+ } -+ else false -+ -+ if (!(caretLocation == openBraceOffset + 1 || caretLocation == closeBraceOffset || caretIsInParams)) return false -+ -+ val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext() -+ val func = context[BindingContext.FUNCTION, element.getFunctionLiteral()] -+ if (func == null || ErrorUtils.containsErrorType(func)) return false -+ -+ hasImplicitReturnType = !element.hasDeclaredReturnType() -+ hasImplicitReceiverType = element.getFunctionLiteral().getReceiverTypeRef() == null -+ if (hasImplicitReturnType && func.getReturnType() != null) return true -+ if (hasImplicitReceiverType && func.getReceiverParameter()?.getType() != null) return true -+ -+ val params = element.getValueParameters() -+ if (params.any { it.getTypeReference() == null } || params.isEmpty()) return true","This is rather minor, but you should always strive to do simple checks first and complex checks later. It increases both readability and performance. Here `params.isEmpty()` is obviously very cheap compared to the other condition which involves looping over a collection -",Maybe rename this class to `MakeType -62,"@@ -0,0 +1,121 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.psi.JetFile -+import org.jetbrains.jet.lang.resolve.BindingContext -+import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor -+import org.jetbrains.jet.renderer.DescriptorRenderer -+import org.jetbrains.jet.lang.types.ErrorUtils -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import com.intellij.psi.PsiWhiteSpace -+import org.jetbrains.jet.plugin.codeInsight.ShortenReferences -+ -+public class MakeTypeExplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.explicit.in.lambda"", javaClass()) { -+ private var hasImplicitReturnType = false -+ private var hasImplicitReceiverType = false -+ -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ throw IllegalStateException(""isApplicableTo(JetExpressionImpl, Editor) should be called instead"") -+ } -+ -+ override fun isApplicableTo(element: JetFunctionLiteralExpression, editor: Editor): Boolean { -+ val openBraceOffset = element.getLeftCurlyBrace().getStartOffset() -+ val closeBraceOffset = element.getRightCurlyBrace()?.getStartOffset() -+ val caretLocation = editor.getCaretModel().getOffset() -+ val paramsTextRange = element.getFunctionLiteral().getValueParameterList()?.getTextRange() -+ val caretIsInParams = if (paramsTextRange != null) { -+ caretLocation in paramsTextRange -+ } -+ else false -+ -+ if (!(caretLocation == openBraceOffset + 1 || caretLocation == closeBraceOffset || caretIsInParams)) return false -+ -+ val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext() -+ val func = context[BindingContext.FUNCTION, element.getFunctionLiteral()] -+ if (func == null || ErrorUtils.containsErrorType(func)) return false -+ -+ hasImplicitReturnType = !element.hasDeclaredReturnType() -+ hasImplicitReceiverType = element.getFunctionLiteral().getReceiverTypeRef() == null -+ if (hasImplicitReturnType && func.getReturnType() != null) return true -+ if (hasImplicitReceiverType && func.getReceiverParameter()?.getType() != null) return true -+ -+ val params = element.getValueParameters() -+ if (params.any { it.getTypeReference() == null } || params.isEmpty()) return true -+ -+ return false -+ } -+ -+ override fun applyTo(element: JetFunctionLiteralExpression, editor: Editor) { -+ val functionLiteral = element.getFunctionLiteral() -+ val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext() -+ val func = context[BindingContext.FUNCTION, functionLiteral]!! -+ -+ // Step 1: make the parameters types explicit -+ val valueParameters = func.getValueParameters() -+ val parameterString = valueParameters.map({(descriptor: ValueParameterDescriptor?): String ->","Type of `descriptor` can be a non-null `ValueParameterDescriptor` here, because Kotlin sees Java generic types with non-null type arguments by default, so `valueParameters` is actually `List`, not `List` -",Maybe rename this class to `MakeType -63,"@@ -0,0 +1,121 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.psi.JetFile -+import org.jetbrains.jet.lang.resolve.BindingContext -+import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor -+import org.jetbrains.jet.renderer.DescriptorRenderer -+import org.jetbrains.jet.lang.types.ErrorUtils -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import com.intellij.psi.PsiWhiteSpace -+import org.jetbrains.jet.plugin.codeInsight.ShortenReferences -+ -+public class MakeTypeExplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.explicit.in.lambda"", javaClass()) { -+ private var hasImplicitReturnType = false -+ private var hasImplicitReceiverType = false -+ -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ throw IllegalStateException(""isApplicableTo(JetExpressionImpl, Editor) should be called instead"") -+ } -+ -+ override fun isApplicableTo(element: JetFunctionLiteralExpression, editor: Editor): Boolean { -+ val openBraceOffset = element.getLeftCurlyBrace().getStartOffset() -+ val closeBraceOffset = element.getRightCurlyBrace()?.getStartOffset() -+ val caretLocation = editor.getCaretModel().getOffset() -+ val paramsTextRange = element.getFunctionLiteral().getValueParameterList()?.getTextRange() -+ val caretIsInParams = if (paramsTextRange != null) { -+ caretLocation in paramsTextRange -+ } -+ else false -+ -+ if (!(caretLocation == openBraceOffset + 1 || caretLocation == closeBraceOffset || caretIsInParams)) return false -+ -+ val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext() -+ val func = context[BindingContext.FUNCTION, element.getFunctionLiteral()] -+ if (func == null || ErrorUtils.containsErrorType(func)) return false -+ -+ hasImplicitReturnType = !element.hasDeclaredReturnType() -+ hasImplicitReceiverType = element.getFunctionLiteral().getReceiverTypeRef() == null -+ if (hasImplicitReturnType && func.getReturnType() != null) return true -+ if (hasImplicitReceiverType && func.getReceiverParameter()?.getType() != null) return true -+ -+ val params = element.getValueParameters() -+ if (params.any { it.getTypeReference() == null } || params.isEmpty()) return true -+ -+ return false -+ } -+ -+ override fun applyTo(element: JetFunctionLiteralExpression, editor: Editor) { -+ val functionLiteral = element.getFunctionLiteral() -+ val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext() -+ val func = context[BindingContext.FUNCTION, functionLiteral]!! -+ -+ // Step 1: make the parameters types explicit -+ val valueParameters = func.getValueParameters() -+ val parameterString = valueParameters.map({(descriptor: ValueParameterDescriptor?): String -> -+ """" + descriptor!!.getName() + -+ "": "" + DescriptorRenderer.TEXT.renderType(descriptor.getType()) -+ }).makeString("", "", ""("", "")"") -+ val newParameterList = JetPsiFactory.createParameterList(element.getProject(), parameterString) -+ val params = functionLiteral.getValueParameterList()","I think `params` should have been named `oldParameterList`, to oppose `newParameterList` -",Maybe rename this class to `MakeType -64,"@@ -0,0 +1,121 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.psi.JetFile -+import org.jetbrains.jet.lang.resolve.BindingContext -+import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor -+import org.jetbrains.jet.renderer.DescriptorRenderer -+import org.jetbrains.jet.lang.types.ErrorUtils -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import com.intellij.psi.PsiWhiteSpace -+import org.jetbrains.jet.plugin.codeInsight.ShortenReferences -+ -+public class MakeTypeExplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.explicit.in.lambda"", javaClass()) { -+ private var hasImplicitReturnType = false -+ private var hasImplicitReceiverType = false -+ -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ throw IllegalStateException(""isApplicableTo(JetExpressionImpl, Editor) should be called instead"") -+ } -+ -+ override fun isApplicableTo(element: JetFunctionLiteralExpression, editor: Editor): Boolean { -+ val openBraceOffset = element.getLeftCurlyBrace().getStartOffset() -+ val closeBraceOffset = element.getRightCurlyBrace()?.getStartOffset() -+ val caretLocation = editor.getCaretModel().getOffset() -+ val paramsTextRange = element.getFunctionLiteral().getValueParameterList()?.getTextRange() -+ val caretIsInParams = if (paramsTextRange != null) { -+ caretLocation in paramsTextRange -+ } -+ else false -+ -+ if (!(caretLocation == openBraceOffset + 1 || caretLocation == closeBraceOffset || caretIsInParams)) return false -+ -+ val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext() -+ val func = context[BindingContext.FUNCTION, element.getFunctionLiteral()] -+ if (func == null || ErrorUtils.containsErrorType(func)) return false -+ -+ hasImplicitReturnType = !element.hasDeclaredReturnType() -+ hasImplicitReceiverType = element.getFunctionLiteral().getReceiverTypeRef() == null -+ if (hasImplicitReturnType && func.getReturnType() != null) return true -+ if (hasImplicitReceiverType && func.getReceiverParameter()?.getType() != null) return true -+ -+ val params = element.getValueParameters() -+ if (params.any { it.getTypeReference() == null } || params.isEmpty()) return true -+ -+ return false -+ } -+ -+ override fun applyTo(element: JetFunctionLiteralExpression, editor: Editor) { -+ val functionLiteral = element.getFunctionLiteral() -+ val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext() -+ val func = context[BindingContext.FUNCTION, functionLiteral]!! -+ -+ // Step 1: make the parameters types explicit -+ val valueParameters = func.getValueParameters() -+ val parameterString = valueParameters.map({(descriptor: ValueParameterDescriptor?): String -> -+ """" + descriptor!!.getName() + -+ "": "" + DescriptorRenderer.TEXT.renderType(descriptor.getType()) -+ }).makeString("", "", ""("", "")"") -+ val newParameterList = JetPsiFactory.createParameterList(element.getProject(), parameterString) -+ val params = functionLiteral.getValueParameterList() -+ if (params != null) { -+ params.replace(newParameterList) -+ } -+ else { -+ val openBraceElement = functionLiteral.getOpenBraceNode().getPsi() -+ val nextSibling = openBraceElement?.getNextSibling() -+ val whitespaceToAdd = (if (nextSibling is PsiWhiteSpace && nextSibling?.getText()?.contains(""\n"")?: false)","There's a warning on `?.` here :) If you're not sure whether or not your code has warnings, check the small box in IntelliJ's top-right corner, it should be green -",Maybe rename this class to `MakeTypeExplicitInLambdaIntention` -65,"@@ -0,0 +1,122 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.psi.JetFile -+import org.jetbrains.jet.lang.resolve.BindingContext -+import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor -+import org.jetbrains.jet.renderer.DescriptorRenderer -+import org.jetbrains.jet.lang.types.ErrorUtils -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import com.intellij.psi.PsiWhiteSpace -+import org.jetbrains.jet.plugin.codeInsight.ShortenReferences -+ -+public class MakeTypeExplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.explicit.in.lambda"", javaClass()) { -+ -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ throw IllegalStateException(""isApplicableTo(JetExpressionImpl, Editor) should be called instead"") -+ } -+ -+ override fun isApplicableTo(element: JetFunctionLiteralExpression, editor: Editor): Boolean { -+ val openBraceOffset = element.getLeftCurlyBrace().getStartOffset() -+ val closeBraceOffset = element.getRightCurlyBrace()?.getStartOffset() -+ val caretLocation = editor.getCaretModel().getOffset() -+ val arrow = element.getFunctionLiteral().getArrowNode() -+ if (arrow != null && !(openBraceOffset < caretLocation && caretLocation < arrow.getStartOffset() + 2) && -+ caretLocation != closeBraceOffset) return false -+ else if (arrow == null && caretLocation != openBraceOffset + 1 && caretLocation != closeBraceOffset) return false -+ -+ val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext() -+ val func = context[BindingContext.FUNCTION, element.getFunctionLiteral()] -+ if (func == null || ErrorUtils.containsErrorType(func)) return false -+ -+ if (hasImplicitReturnType(element) && func.getReturnType() != null) return true -+ if (hasImplicitReceiverType(element) && func.getReceiverParameter()?.getType() != null) return true -+ -+ val params = element.getValueParameters() -+ if (params.isEmpty() || params.any { it.getTypeReference() == null }) return true -+ -+ return false","Please collapse these two lines. `if (condition) return true; return false` can be simplified to `return condition` -",Please rename this class to `MakeTypeExplicitInLambdaIntention -66,"@@ -0,0 +1,122 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.psi.JetFile -+import org.jetbrains.jet.lang.resolve.BindingContext -+import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor -+import org.jetbrains.jet.renderer.DescriptorRenderer -+import org.jetbrains.jet.lang.types.ErrorUtils -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import com.intellij.psi.PsiWhiteSpace -+import org.jetbrains.jet.plugin.codeInsight.ShortenReferences -+ -+public class MakeTypeExplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.explicit.in.lambda"", javaClass()) { -+ -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ throw IllegalStateException(""isApplicableTo(JetExpressionImpl, Editor) should be called instead"") -+ } -+ -+ override fun isApplicableTo(element: JetFunctionLiteralExpression, editor: Editor): Boolean { -+ val openBraceOffset = element.getLeftCurlyBrace().getStartOffset() -+ val closeBraceOffset = element.getRightCurlyBrace()?.getStartOffset() -+ val caretLocation = editor.getCaretModel().getOffset() -+ val arrow = element.getFunctionLiteral().getArrowNode() -+ if (arrow != null && !(openBraceOffset < caretLocation && caretLocation < arrow.getStartOffset() + 2) && -+ caretLocation != closeBraceOffset) return false -+ else if (arrow == null && caretLocation != openBraceOffset + 1 && caretLocation != closeBraceOffset) return false -+ -+ val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext() -+ val func = context[BindingContext.FUNCTION, element.getFunctionLiteral()] -+ if (func == null || ErrorUtils.containsErrorType(func)) return false -+ -+ if (hasImplicitReturnType(element) && func.getReturnType() != null) return true -+ if (hasImplicitReceiverType(element) && func.getReceiverParameter()?.getType() != null) return true -+ -+ val params = element.getValueParameters() -+ if (params.isEmpty() || params.any { it.getTypeReference() == null }) return true -+ -+ return false -+ } -+ -+ override fun applyTo(element: JetFunctionLiteralExpression, editor: Editor) { -+ val functionLiteral = element.getFunctionLiteral() -+ val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext() -+ val func = context[BindingContext.FUNCTION, functionLiteral]!! -+ -+ // Step 1: make the parameters types explicit -+ val valueParameters = func.getValueParameters() -+ val parameterString = valueParameters.map({(descriptor: ValueParameterDescriptor): String ->","Ditto: I don't think types are needed here -",Please rename this class to `MakeTypeExplicitInLambdaIntention -67,"@@ -0,0 +1,122 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.psi.JetFile -+import org.jetbrains.jet.lang.resolve.BindingContext -+import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor -+import org.jetbrains.jet.renderer.DescriptorRenderer -+import org.jetbrains.jet.lang.types.ErrorUtils -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import com.intellij.psi.PsiWhiteSpace -+import org.jetbrains.jet.plugin.codeInsight.ShortenReferences -+ -+public class MakeTypeExplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.explicit.in.lambda"", javaClass()) { -+ -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ throw IllegalStateException(""isApplicableTo(JetExpressionImpl, Editor) should be called instead"") -+ } -+ -+ override fun isApplicableTo(element: JetFunctionLiteralExpression, editor: Editor): Boolean { -+ val openBraceOffset = element.getLeftCurlyBrace().getStartOffset() -+ val closeBraceOffset = element.getRightCurlyBrace()?.getStartOffset() -+ val caretLocation = editor.getCaretModel().getOffset() -+ val arrow = element.getFunctionLiteral().getArrowNode() -+ if (arrow != null && !(openBraceOffset < caretLocation && caretLocation < arrow.getStartOffset() + 2) && -+ caretLocation != closeBraceOffset) return false -+ else if (arrow == null && caretLocation != openBraceOffset + 1 && caretLocation != closeBraceOffset) return false -+ -+ val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext() -+ val func = context[BindingContext.FUNCTION, element.getFunctionLiteral()] -+ if (func == null || ErrorUtils.containsErrorType(func)) return false -+ -+ if (hasImplicitReturnType(element) && func.getReturnType() != null) return true -+ if (hasImplicitReceiverType(element) && func.getReceiverParameter()?.getType() != null) return true -+ -+ val params = element.getValueParameters() -+ if (params.isEmpty() || params.any { it.getTypeReference() == null }) return true -+ -+ return false -+ } -+ -+ override fun applyTo(element: JetFunctionLiteralExpression, editor: Editor) { -+ val functionLiteral = element.getFunctionLiteral() -+ val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext() -+ val func = context[BindingContext.FUNCTION, functionLiteral]!! -+ -+ // Step 1: make the parameters types explicit -+ val valueParameters = func.getValueParameters() -+ val parameterString = valueParameters.map({(descriptor: ValueParameterDescriptor): String -> -+ """" + descriptor.getName() + -+ "": "" + DescriptorRenderer.TEXT.renderType(descriptor.getType()) -+ }).makeString("", "", ""("", "")"") -+ val newParameterList = JetPsiFactory.createParameterList(element.getProject(), parameterString) -+ val oldParameterList = functionLiteral.getValueParameterList() -+ if (oldParameterList != null) { -+ oldParameterList.replace(newParameterList) -+ } -+ else { -+ val openBraceElement = functionLiteral.getOpenBraceNode().getPsi() -+ val nextSibling = openBraceElement?.getNextSibling() -+ val whitespaceToAdd = (if (nextSibling is PsiWhiteSpace && nextSibling.getText()?.contains(""\n"")?: false)","I couldn't find tests on this code, am I missing something? It looks kind of complex -",Please rename this class to `MakeTypeExplicitInLambdaIntention -68,"@@ -0,0 +1,122 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.psi.JetFile -+import org.jetbrains.jet.lang.resolve.BindingContext -+import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor -+import org.jetbrains.jet.renderer.DescriptorRenderer -+import org.jetbrains.jet.lang.types.ErrorUtils -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import com.intellij.psi.PsiWhiteSpace -+import org.jetbrains.jet.plugin.codeInsight.ShortenReferences -+ -+public class MakeTypeExplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.explicit.in.lambda"", javaClass()) { -+ -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ throw IllegalStateException(""isApplicableTo(JetExpressionImpl, Editor) should be called instead"") -+ } -+ -+ override fun isApplicableTo(element: JetFunctionLiteralExpression, editor: Editor): Boolean { -+ val openBraceOffset = element.getLeftCurlyBrace().getStartOffset() -+ val closeBraceOffset = element.getRightCurlyBrace()?.getStartOffset() -+ val caretLocation = editor.getCaretModel().getOffset() -+ val arrow = element.getFunctionLiteral().getArrowNode() -+ if (arrow != null && !(openBraceOffset < caretLocation && caretLocation < arrow.getStartOffset() + 2) && -+ caretLocation != closeBraceOffset) return false -+ else if (arrow == null && caretLocation != openBraceOffset + 1 && caretLocation != closeBraceOffset) return false -+ -+ val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext() -+ val func = context[BindingContext.FUNCTION, element.getFunctionLiteral()] -+ if (func == null || ErrorUtils.containsErrorType(func)) return false -+ -+ if (hasImplicitReturnType(element) && func.getReturnType() != null) return true -+ if (hasImplicitReceiverType(element) && func.getReceiverParameter()?.getType() != null) return true -+ -+ val params = element.getValueParameters() -+ if (params.isEmpty() || params.any { it.getTypeReference() == null }) return true -+ -+ return false -+ } -+ -+ override fun applyTo(element: JetFunctionLiteralExpression, editor: Editor) { -+ val functionLiteral = element.getFunctionLiteral() -+ val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext() -+ val func = context[BindingContext.FUNCTION, functionLiteral]!! -+ -+ // Step 1: make the parameters types explicit -+ val valueParameters = func.getValueParameters() -+ val parameterString = valueParameters.map({(descriptor: ValueParameterDescriptor): String -> -+ """" + descriptor.getName() + -+ "": "" + DescriptorRenderer.TEXT.renderType(descriptor.getType()) -+ }).makeString("", "", ""("", "")"") -+ val newParameterList = JetPsiFactory.createParameterList(element.getProject(), parameterString) -+ val oldParameterList = functionLiteral.getValueParameterList() -+ if (oldParameterList != null) { -+ oldParameterList.replace(newParameterList) -+ } -+ else { -+ val openBraceElement = functionLiteral.getOpenBraceNode().getPsi() -+ val nextSibling = openBraceElement?.getNextSibling() -+ val whitespaceToAdd = (if (nextSibling is PsiWhiteSpace && nextSibling.getText()?.contains(""\n"")?: false) -+ nextSibling.copy() -+ else -+ null) -+ val whitespaceAndArrow = JetPsiFactory.createWhitespaceAndArrow(element.getProject()) -+ functionLiteral.addRangeAfter(whitespaceAndArrow.first, whitespaceAndArrow.second, openBraceElement) -+ functionLiteral.addAfter(newParameterList, openBraceElement) -+ if (whitespaceToAdd != null) { -+ functionLiteral.addAfter(whitespaceToAdd, openBraceElement) -+ } -+ } -+ ShortenReferences.process(element.getValueParameters()) -+ -+ -+ // Step 2: make the return type explicit -+ val expectedReturnType = func.getReturnType() -+ if (hasImplicitReturnType(element) && expectedReturnType != null) { -+ val paramList = functionLiteral.getValueParameterList() -+ val returnTypeColon = JetPsiFactory.createColon(element.getProject()) -+ val returnTypeExpr = JetPsiFactory.createType(element.getProject(), DescriptorRenderer.TEXT.renderType(expectedReturnType)) -+ ShortenReferences.process(returnTypeExpr) -+ functionLiteral.addAfter(returnTypeExpr, paramList) -+ functionLiteral.addAfter(returnTypeColon, paramList) -+ } -+ -+ // Step 3: make the receiver type explicit -+ val expectedReceiverType = func.getReceiverParameter()?.getType() -+ if (hasImplicitReceiverType(element) && expectedReceiverType != null) { -+ val receiverTypeString = DescriptorRenderer.TEXT.renderType(expectedReceiverType) -+ val paramListString = functionLiteral.getValueParameterList()?.getText() -+ val paramListWithReceiver = JetPsiFactory.createExpression(element.getProject(), receiverTypeString + ""."" + paramListString) -+ ShortenReferences.process(paramListWithReceiver) -+ functionLiteral.getValueParameterList()?.replace(paramListWithReceiver) -+ } -+ } -+ -+ fun hasImplicitReturnType(element: JetFunctionLiteralExpression): Boolean { -+ return !element.hasDeclaredReturnType() -+ } -+ -+ fun hasImplicitReceiverType(element: JetFunctionLiteralExpression): Boolean { -+ return element.getFunctionLiteral().getReceiverTypeRef() == null -+ }","The last 2 functions in this file should be `private` -",Please rename this class to `MakeTypeExplicitInLambdaIntention -69,"@@ -0,0 +1,124 @@ -+/* -+ * 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.idea.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.kotlin.builtins.KotlinBuiltIns -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.idea.intentions.branchedTransformations.evaluatesTo -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.* -+import org.jetbrains.kotlin.resolve.calls.callUtil.getType -+ -+class ConvertTwoComparisonsToRangeCheckIntention : SelfTargetingOffsetIndependentIntention(KtBinaryExpression::class.java, ""Convert to range check"") { -+ -+ private data class RangeExpressionData(val value: String, val min: String, val max: String) -+ -+ override fun isApplicableTo(condition: KtBinaryExpression) = generateRangeExpressionData(condition) != null -+ -+ override fun applyTo(condition: KtBinaryExpression, editor: Editor?) { -+ val rangeData = generateRangeExpressionData(condition) ?: return -+ condition.replace(KtPsiFactory(condition).createExpressionByPattern(""$0 in $1..$2"", rangeData.value, rangeData.min, rangeData.max)) -+ } -+ -+ private fun generateRangeExpressionData(condition: KtBinaryExpression): RangeExpressionData? { -+ if (condition.operationToken != KtTokens.ANDAND) return null -+ val firstCondition = condition.left as? KtBinaryExpression ?: return null -+ val secondCondition = condition.right as? KtBinaryExpression ?: return null -+ val firstOpToken = firstCondition.operationToken -+ val secondOpToken = secondCondition.operationToken -+ val firstLeft = firstCondition.left ?: return null -+ val firstRight = firstCondition.right ?: return null -+ val secondLeft = secondCondition.left ?: return null -+ val secondRight = secondCondition.right ?: return null -+ -+ return when (firstOpToken) {","This `when` is written in a very straight-forward way. Please, think a bit how to make it shorter. All branches are very like one another.",Why not just call `generateRangeExpressionData(condition)` dir -70,"@@ -0,0 +1,124 @@ -+/* -+ * 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.idea.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.kotlin.builtins.KotlinBuiltIns -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.idea.intentions.branchedTransformations.evaluatesTo -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.* -+import org.jetbrains.kotlin.resolve.calls.callUtil.getType -+ -+class ConvertTwoComparisonsToRangeCheckIntention : SelfTargetingOffsetIndependentIntention(KtBinaryExpression::class.java, ""Convert to range check"") { -+ -+ private data class RangeExpressionData(val value: String, val min: String, val max: String) -+ -+ override fun isApplicableTo(condition: KtBinaryExpression) = generateRangeExpressionData(condition) != null -+ -+ override fun applyTo(condition: KtBinaryExpression, editor: Editor?) { -+ val rangeData = generateRangeExpressionData(condition) ?: return -+ condition.replace(KtPsiFactory(condition).createExpressionByPattern(""$0 in $1..$2"", rangeData.value, rangeData.min, rangeData.max)) -+ } -+ -+ private fun generateRangeExpressionData(condition: KtBinaryExpression): RangeExpressionData? { -+ if (condition.operationToken != KtTokens.ANDAND) return null -+ val firstCondition = condition.left as? KtBinaryExpression ?: return null -+ val secondCondition = condition.right as? KtBinaryExpression ?: return null -+ val firstOpToken = firstCondition.operationToken -+ val secondOpToken = secondCondition.operationToken -+ val firstLeft = firstCondition.left ?: return null -+ val firstRight = firstCondition.right ?: return null -+ val secondLeft = secondCondition.left ?: return null -+ val secondRight = secondCondition.right ?: return null -+ -+ return when (firstOpToken) { -+ KtTokens.GTEQ, KtTokens.GT -> { -+ when (secondOpToken) { -+ KtTokens.GTEQ, KtTokens.GT -> when { -+ firstLeft !is KtConstantExpression && firstLeft.evaluatesTo(secondRight) -> -+ generateRangeExpressionData(firstLeft, firstRight, secondLeft, minDecrementByOne = firstOpToken == KtTokens.GT, maxDecrementByOne = secondOpToken == KtTokens.GT) -+ firstRight !is KtConstantExpression && firstRight.evaluatesTo(secondLeft) -> -+ generateRangeExpressionData(firstRight, secondRight, firstLeft, minDecrementByOne = firstOpToken == KtTokens.GT, maxDecrementByOne = secondOpToken == KtTokens.GT) -+ else -> null -+ } -+ KtTokens.LTEQ, KtTokens.LT -> when { -+ firstLeft !is KtConstantExpression && firstLeft.evaluatesTo(secondLeft) -> -+ generateRangeExpressionData(firstLeft, firstRight, secondRight, minDecrementByOne = firstOpToken == KtTokens.GT, maxDecrementByOne = secondOpToken == KtTokens.LT) -+ firstRight !is KtConstantExpression && firstRight.evaluatesTo(secondRight) -> -+ generateRangeExpressionData(firstRight, secondLeft, firstLeft, minDecrementByOne = firstOpToken == KtTokens.GT, maxDecrementByOne = secondOpToken == KtTokens.LT) -+ else -> null -+ } -+ else -> null -+ } -+ } -+ KtTokens.LTEQ, KtTokens.LT -> { -+ when (secondOpToken) { -+ KtTokens.GTEQ, KtTokens.GT -> when { -+ firstLeft !is KtConstantExpression && firstLeft.evaluatesTo(secondLeft) -> -+ generateRangeExpressionData(firstLeft, secondRight, firstRight, minDecrementByOne = firstOpToken == KtTokens.LT, maxDecrementByOne = secondOpToken == KtTokens.GT) -+ firstRight !is KtConstantExpression && firstRight.evaluatesTo(secondRight) -> -+ generateRangeExpressionData(firstRight, firstLeft, secondLeft, minDecrementByOne = firstOpToken == KtTokens.LT, maxDecrementByOne = secondOpToken == KtTokens.GT) -+ else -> null -+ } -+ KtTokens.LTEQ, KtTokens.LT -> when { -+ firstLeft !is KtConstantExpression && firstLeft.evaluatesTo(secondRight) -> -+ generateRangeExpressionData(firstLeft, secondLeft, firstRight, minDecrementByOne = firstOpToken == KtTokens.LT, maxDecrementByOne = secondOpToken == KtTokens.LT) -+ firstRight !is KtConstantExpression && firstRight.evaluatesTo(secondLeft) -> -+ generateRangeExpressionData(firstRight, firstLeft, secondRight, minDecrementByOne = firstOpToken == KtTokens.LT, maxDecrementByOne = secondOpToken == KtTokens.LT) -+ else -> null -+ } -+ else -> null -+ } -+ } -+ else -> null -+ } -+ } -+ -+ private fun generateRangeExpressionData(value: KtExpression, min: KtExpression, max: KtExpression, minDecrementByOne: Boolean = false, maxDecrementByOne: Boolean = false): RangeExpressionData? { -+ if (minDecrementByOne || maxDecrementByOne) { -+ val type = value.getType(value.analyze()) ?: return null -+ if (!KotlinBuiltIns.isInt(type) && !KotlinBuiltIns.isLong(type) && !KotlinBuiltIns.isShort(type) && !KotlinBuiltIns.isChar(type)) return null -+ } -+ -+ val minText = if (minDecrementByOne) min.getDecrementByOneString() else min.text -+ val maxText = if (maxDecrementByOne) max.getDecrementByOneString() else max.text -+ return RangeExpressionData(value.text, minText ?: return null, maxText ?: return null) -+ } -+ -+ private fun KtExpression.getDecrementByOneString(): String? { -+ val type = getType(analyze()) ?: return null -+ -+ when (this) { -+ is KtConstantExpression -> { -+ val number: Number = when { -+ KotlinBuiltIns.isInt(type) -> text.toInt() - 1 -+ KotlinBuiltIns.isLong(type) -> { -+ val text = text -+ val longText = if (text.endsWith(""l"") || text.endsWith(""L"")) text.substring(0, text.length - 1) else text -+ longText.toLong() - 1 -+ } -+ KotlinBuiltIns.isShort(type) -> java.lang.Short.parseShort(text) - 1 -+ KotlinBuiltIns.isChar(type) -> text[0].toInt() - 1","I think it is better to replace character with character, either explicit e.g. `'z' - 1` or implicit `'y'`",Why not just call `generateRangeExpressionData(condition)` dir -71,"@@ -0,0 +1,124 @@ -+/* -+ * 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.idea.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.kotlin.builtins.KotlinBuiltIns -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.idea.intentions.branchedTransformations.evaluatesTo -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.* -+import org.jetbrains.kotlin.resolve.calls.callUtil.getType -+ -+class ConvertTwoComparisonsToRangeCheckIntention : SelfTargetingOffsetIndependentIntention(KtBinaryExpression::class.java, ""Convert to range check"") { -+ -+ private data class RangeExpressionData(val value: String, val min: String, val max: String) -+ -+ override fun isApplicableTo(condition: KtBinaryExpression) = generateRangeExpressionData(condition) != null -+ -+ override fun applyTo(condition: KtBinaryExpression, editor: Editor?) { -+ val rangeData = generateRangeExpressionData(condition) ?: return -+ condition.replace(KtPsiFactory(condition).createExpressionByPattern(""$0 in $1..$2"", rangeData.value, rangeData.min, rangeData.max)) -+ } -+ -+ private fun generateRangeExpressionData(condition: KtBinaryExpression): RangeExpressionData? { -+ if (condition.operationToken != KtTokens.ANDAND) return null -+ val firstCondition = condition.left as? KtBinaryExpression ?: return null -+ val secondCondition = condition.right as? KtBinaryExpression ?: return null -+ val firstOpToken = firstCondition.operationToken -+ val secondOpToken = secondCondition.operationToken -+ val firstLeft = firstCondition.left ?: return null -+ val firstRight = firstCondition.right ?: return null -+ val secondLeft = secondCondition.left ?: return null -+ val secondRight = secondCondition.right ?: return null -+ -+ return when (firstOpToken) { -+ KtTokens.GTEQ, KtTokens.GT -> { -+ when (secondOpToken) { -+ KtTokens.GTEQ, KtTokens.GT -> when { -+ firstLeft !is KtConstantExpression && firstLeft.evaluatesTo(secondRight) -> -+ generateRangeExpressionData(firstLeft, firstRight, secondLeft, minDecrementByOne = firstOpToken == KtTokens.GT, maxDecrementByOne = secondOpToken == KtTokens.GT) -+ firstRight !is KtConstantExpression && firstRight.evaluatesTo(secondLeft) -> -+ generateRangeExpressionData(firstRight, secondRight, firstLeft, minDecrementByOne = firstOpToken == KtTokens.GT, maxDecrementByOne = secondOpToken == KtTokens.GT) -+ else -> null -+ } -+ KtTokens.LTEQ, KtTokens.LT -> when { -+ firstLeft !is KtConstantExpression && firstLeft.evaluatesTo(secondLeft) -> -+ generateRangeExpressionData(firstLeft, firstRight, secondRight, minDecrementByOne = firstOpToken == KtTokens.GT, maxDecrementByOne = secondOpToken == KtTokens.LT) -+ firstRight !is KtConstantExpression && firstRight.evaluatesTo(secondRight) -> -+ generateRangeExpressionData(firstRight, secondLeft, firstLeft, minDecrementByOne = firstOpToken == KtTokens.GT, maxDecrementByOne = secondOpToken == KtTokens.LT) -+ else -> null -+ } -+ else -> null -+ } -+ } -+ KtTokens.LTEQ, KtTokens.LT -> { -+ when (secondOpToken) { -+ KtTokens.GTEQ, KtTokens.GT -> when { -+ firstLeft !is KtConstantExpression && firstLeft.evaluatesTo(secondLeft) -> -+ generateRangeExpressionData(firstLeft, secondRight, firstRight, minDecrementByOne = firstOpToken == KtTokens.LT, maxDecrementByOne = secondOpToken == KtTokens.GT) -+ firstRight !is KtConstantExpression && firstRight.evaluatesTo(secondRight) -> -+ generateRangeExpressionData(firstRight, firstLeft, secondLeft, minDecrementByOne = firstOpToken == KtTokens.LT, maxDecrementByOne = secondOpToken == KtTokens.GT) -+ else -> null -+ } -+ KtTokens.LTEQ, KtTokens.LT -> when { -+ firstLeft !is KtConstantExpression && firstLeft.evaluatesTo(secondRight) -> -+ generateRangeExpressionData(firstLeft, secondLeft, firstRight, minDecrementByOne = firstOpToken == KtTokens.LT, maxDecrementByOne = secondOpToken == KtTokens.LT) -+ firstRight !is KtConstantExpression && firstRight.evaluatesTo(secondLeft) -> -+ generateRangeExpressionData(firstRight, firstLeft, secondRight, minDecrementByOne = firstOpToken == KtTokens.LT, maxDecrementByOne = secondOpToken == KtTokens.LT) -+ else -> null -+ } -+ else -> null -+ } -+ } -+ else -> null -+ } -+ } -+ -+ private fun generateRangeExpressionData(value: KtExpression, min: KtExpression, max: KtExpression, minDecrementByOne: Boolean = false, maxDecrementByOne: Boolean = false): RangeExpressionData? { -+ if (minDecrementByOne || maxDecrementByOne) { -+ val type = value.getType(value.analyze()) ?: return null -+ if (!KotlinBuiltIns.isInt(type) && !KotlinBuiltIns.isLong(type) && !KotlinBuiltIns.isShort(type) && !KotlinBuiltIns.isChar(type)) return null -+ } -+ -+ val minText = if (minDecrementByOne) min.getDecrementByOneString() else min.text -+ val maxText = if (maxDecrementByOne) max.getDecrementByOneString() else max.text -+ return RangeExpressionData(value.text, minText ?: return null, maxText ?: return null) -+ } -+ -+ private fun KtExpression.getDecrementByOneString(): String? { -+ val type = getType(analyze()) ?: return null -+ -+ when (this) { -+ is KtConstantExpression -> { -+ val number: Number = when { -+ KotlinBuiltIns.isInt(type) -> text.toInt() - 1 -+ KotlinBuiltIns.isLong(type) -> { -+ val text = text -+ val longText = if (text.endsWith(""l"") || text.endsWith(""L"")) text.substring(0, text.length - 1) else text -+ longText.toLong() - 1 -+ } -+ KotlinBuiltIns.isShort(type) -> java.lang.Short.parseShort(text) - 1 -+ KotlinBuiltIns.isChar(type) -> text[0].toInt() - 1 -+ else -> return null -+ } -+ return number.toString() -+ } -+ else -> return ""($text - 1)""","This is very controversial. What if expression is a `String`, for example?",Why not just call `generateRangeExpressionData(condition)` dir -72,"@@ -0,0 +1,124 @@ -+/* -+ * 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.wrappers.trees -+ -+import com.intellij.psi.CommonClassNames -+import com.sun.source.tree.Tree -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.code.Flags -+import com.sun.tools.javac.tree.JCTree -+import com.sun.tools.javac.tree.TreeInfo -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.wrappers.symbols.JavacClassifierType -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.java.structure.JavaClassifierType -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.SpecialNames -+ -+class JCClass(tree: T, -+ treePath: TreePath, -+ javac: JavacWrapper) : JCElement(tree, treePath, javac), JavaClass { -+ -+ override val name -+ get() = SpecialNames.safeIdentifier(tree.simpleName.toString()) -+ -+ override val annotations by lazy { tree.annotations().map { JCAnnotation(it, treePath, javac) } } -+ -+ override fun findAnnotation(fqName: FqName) = annotations.find { it.classId?.asSingleFqName() == fqName } -+ -+ override val isDeprecatedInJavaDoc -+ get() = findAnnotation(FqName(""java.lang.Deprecated"")) != null -+ -+ override val isAbstract -+ get() = tree.modifiers.isAbstract -+ -+ override val isStatic -+ get() = tree.modifiers.isStatic",What about interface member classes? (they're always static as I know),"Please remove this file, it does not add anything." -73,"@@ -0,0 +1,124 @@ -+/* -+ * 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.wrappers.trees -+ -+import com.intellij.psi.CommonClassNames -+import com.sun.source.tree.Tree -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.code.Flags -+import com.sun.tools.javac.tree.JCTree -+import com.sun.tools.javac.tree.TreeInfo -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.wrappers.symbols.JavacClassifierType -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.java.structure.JavaClassifierType -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.SpecialNames -+ -+class JCClass(tree: T, -+ treePath: TreePath, -+ javac: JavacWrapper) : JCElement(tree, treePath, javac), JavaClass { -+ -+ override val name -+ get() = SpecialNames.safeIdentifier(tree.simpleName.toString()) -+ -+ override val annotations by lazy { tree.annotations().map { JCAnnotation(it, treePath, javac) } } -+ -+ override fun findAnnotation(fqName: FqName) = annotations.find { it.classId?.asSingleFqName() == fqName } -+ -+ override val isDeprecatedInJavaDoc -+ get() = findAnnotation(FqName(""java.lang.Deprecated"")) != null -+ -+ override val isAbstract -+ get() = tree.modifiers.isAbstract -+ -+ override val isStatic -+ get() = tree.modifiers.isStatic -+ -+ override val isFinal -+ get() = tree.modifiers.isFinal -+ -+ override val visibility -+ get() = tree.modifiers.visibility",What about interface member classes? (they're always public as I know),"Please remove this file, it does not add anything." -74,"@@ -0,0 +1,126 @@ -+/* -+ * 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.android.quickfix -+ -+import com.intellij.codeInsight.intention.IntentionAction -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.project.Project -+import com.intellij.psi.* -+import com.intellij.psi.util.PsiTypesUtil -+import org.jetbrains.android.facet.AndroidFacet -+import org.jetbrains.kotlin.asJava.toLightClass -+import org.jetbrains.kotlin.diagnostics.Diagnostic -+import org.jetbrains.kotlin.diagnostics.Errors.SUPERTYPE_NOT_INITIALIZED -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.idea.core.ShortenReferences -+import org.jetbrains.kotlin.idea.core.replaced -+import org.jetbrains.kotlin.idea.quickfix.KotlinQuickFixAction -+import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory -+import org.jetbrains.kotlin.idea.util.addAnnotation -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.psi.* -+import org.jetbrains.kotlin.psi.psiUtil.containingClass -+import org.jetbrains.kotlin.resolve.BindingContext -+import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils -+import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe -+import org.jetbrains.kotlin.types.KotlinType -+import org.jetbrains.kotlin.types.typeUtil.supertypes -+ -+class KotlinAndroidViewConstructorFix(element: KtSuperTypeEntry) : KotlinQuickFixAction(element) { -+ -+ override fun getText() = ""Add Android View constructors using '@JvmOverloads'"" -+ override fun getFamilyName() = text -+ -+ override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean { -+ if (AndroidFacet.getInstance(file) == null) return false -+ return super.isAvailable(project, editor, file) -+ } -+ -+ override fun invoke(project: Project, editor: Editor?, file: KtFile) { -+ val element = element ?: return -+ val ktClass = element.containingClass() ?: return -+ -+ val factory = KtPsiFactory(element) -+ -+ val newPrimaryConstructor = factory.createDeclarationByPattern( -+ ""class A constructor(\n $0, $1, $2\n)"", -+ factory.createParameter(""context: android.content.Context""), -+ factory.createParameter(""attrs: android.util.AttributeSet? = null""), -+ factory.createParameter(""defStyleAttr: Int = 0"") -+ ).primaryConstructor!!",i think `?: return` will be better,Why does this class need to be in the package package? Does it -75,"@@ -0,0 +1,126 @@ -+/* -+ * 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.android.quickfix -+ -+import com.intellij.codeInsight.intention.IntentionAction -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.project.Project -+import com.intellij.psi.* -+import com.intellij.psi.util.PsiTypesUtil -+import org.jetbrains.android.facet.AndroidFacet -+import org.jetbrains.kotlin.asJava.toLightClass -+import org.jetbrains.kotlin.diagnostics.Diagnostic -+import org.jetbrains.kotlin.diagnostics.Errors.SUPERTYPE_NOT_INITIALIZED -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.idea.core.ShortenReferences -+import org.jetbrains.kotlin.idea.core.replaced -+import org.jetbrains.kotlin.idea.quickfix.KotlinQuickFixAction -+import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory -+import org.jetbrains.kotlin.idea.util.addAnnotation -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.psi.* -+import org.jetbrains.kotlin.psi.psiUtil.containingClass -+import org.jetbrains.kotlin.resolve.BindingContext -+import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils -+import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe -+import org.jetbrains.kotlin.types.KotlinType -+import org.jetbrains.kotlin.types.typeUtil.supertypes -+ -+class KotlinAndroidViewConstructorFix(element: KtSuperTypeEntry) : KotlinQuickFixAction(element) { -+ -+ override fun getText() = ""Add Android View constructors using '@JvmOverloads'"" -+ override fun getFamilyName() = text -+ -+ override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean { -+ if (AndroidFacet.getInstance(file) == null) return false -+ return super.isAvailable(project, editor, file) -+ } -+ -+ override fun invoke(project: Project, editor: Editor?, file: KtFile) { -+ val element = element ?: return -+ val ktClass = element.containingClass() ?: return -+ -+ val factory = KtPsiFactory(element) -+ -+ val newPrimaryConstructor = factory.createDeclarationByPattern( -+ ""class A constructor(\n $0, $1, $2\n)"", -+ factory.createParameter(""context: android.content.Context""), -+ factory.createParameter(""attrs: android.util.AttributeSet? = null""), -+ factory.createParameter(""defStyleAttr: Int = 0"") -+ ).primaryConstructor!! -+ -+ val primaryConstructor = ktClass.createPrimaryConstructorIfAbsent().replaced(newPrimaryConstructor) -+ ShortenReferences.DEFAULT.process(primaryConstructor.valueParameterList!!)",`primaryConstructor.valueParameterList?.apply { ShortenReferences.DEFAULT.process(this) }`,Why does this class need to be in the package package? Does it -76,"@@ -0,0 +1,126 @@ -+/* -+ * 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.android.quickfix -+ -+import com.intellij.codeInsight.intention.IntentionAction -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.project.Project -+import com.intellij.psi.* -+import com.intellij.psi.util.PsiTypesUtil -+import org.jetbrains.android.facet.AndroidFacet -+import org.jetbrains.kotlin.asJava.toLightClass -+import org.jetbrains.kotlin.diagnostics.Diagnostic -+import org.jetbrains.kotlin.diagnostics.Errors.SUPERTYPE_NOT_INITIALIZED -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.idea.core.ShortenReferences -+import org.jetbrains.kotlin.idea.core.replaced -+import org.jetbrains.kotlin.idea.quickfix.KotlinQuickFixAction -+import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory -+import org.jetbrains.kotlin.idea.util.addAnnotation -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.psi.* -+import org.jetbrains.kotlin.psi.psiUtil.containingClass -+import org.jetbrains.kotlin.resolve.BindingContext -+import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils -+import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe -+import org.jetbrains.kotlin.types.KotlinType -+import org.jetbrains.kotlin.types.typeUtil.supertypes -+ -+class KotlinAndroidViewConstructorFix(element: KtSuperTypeEntry) : KotlinQuickFixAction(element) { -+ -+ override fun getText() = ""Add Android View constructors using '@JvmOverloads'"" -+ override fun getFamilyName() = text -+ -+ override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean { -+ if (AndroidFacet.getInstance(file) == null) return false -+ return super.isAvailable(project, editor, file) -+ } -+ -+ override fun invoke(project: Project, editor: Editor?, file: KtFile) { -+ val element = element ?: return -+ val ktClass = element.containingClass() ?: return -+ -+ val factory = KtPsiFactory(element) -+ -+ val newPrimaryConstructor = factory.createDeclarationByPattern( -+ ""class A constructor(\n $0, $1, $2\n)"", -+ factory.createParameter(""context: android.content.Context""), -+ factory.createParameter(""attrs: android.util.AttributeSet? = null""), -+ factory.createParameter(""defStyleAttr: Int = 0"") -+ ).primaryConstructor!! -+ -+ val primaryConstructor = ktClass.createPrimaryConstructorIfAbsent().replaced(newPrimaryConstructor) -+ ShortenReferences.DEFAULT.process(primaryConstructor.valueParameterList!!) -+ -+ primaryConstructor.addAnnotation(fqNameAnnotation, whiteSpaceText = "" "") -+ -+ element.replace(factory.createSuperTypeCallEntry(element.text + ""(context, attrs, defStyleAttr)"")) -+ } -+ -+ companion object Factory : KotlinSingleIntentionActionFactory() { -+ -+ private val fqNameAnnotation = FqName(""kotlin.jvm.JvmOverloads"") -+ -+ private val requireConstructorParameterTypes = listOf(","I think we may check only for a presence of the third one `""android.content.Context"", ""android.util.AttributeSet"", ""int""`, since we are using only it, if I understood correctly",Why does this class need to be in the package package? Does it -77,"@@ -0,0 +1,126 @@ -+/* -+ * 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.android.quickfix -+ -+import com.intellij.codeInsight.intention.IntentionAction -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.project.Project -+import com.intellij.psi.* -+import com.intellij.psi.util.PsiTypesUtil -+import org.jetbrains.android.facet.AndroidFacet -+import org.jetbrains.kotlin.asJava.toLightClass -+import org.jetbrains.kotlin.diagnostics.Diagnostic -+import org.jetbrains.kotlin.diagnostics.Errors.SUPERTYPE_NOT_INITIALIZED -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.idea.core.ShortenReferences -+import org.jetbrains.kotlin.idea.core.replaced -+import org.jetbrains.kotlin.idea.quickfix.KotlinQuickFixAction -+import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory -+import org.jetbrains.kotlin.idea.util.addAnnotation -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.psi.* -+import org.jetbrains.kotlin.psi.psiUtil.containingClass -+import org.jetbrains.kotlin.resolve.BindingContext -+import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils -+import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe -+import org.jetbrains.kotlin.types.KotlinType -+import org.jetbrains.kotlin.types.typeUtil.supertypes -+ -+class KotlinAndroidViewConstructorFix(element: KtSuperTypeEntry) : KotlinQuickFixAction(element) { -+ -+ override fun getText() = ""Add Android View constructors using '@JvmOverloads'"" -+ override fun getFamilyName() = text -+ -+ override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean { -+ if (AndroidFacet.getInstance(file) == null) return false -+ return super.isAvailable(project, editor, file) -+ } -+ -+ override fun invoke(project: Project, editor: Editor?, file: KtFile) { -+ val element = element ?: return -+ val ktClass = element.containingClass() ?: return -+ -+ val factory = KtPsiFactory(element) -+ -+ val newPrimaryConstructor = factory.createDeclarationByPattern( -+ ""class A constructor(\n $0, $1, $2\n)"", -+ factory.createParameter(""context: android.content.Context""), -+ factory.createParameter(""attrs: android.util.AttributeSet? = null""), -+ factory.createParameter(""defStyleAttr: Int = 0"") -+ ).primaryConstructor!! -+ -+ val primaryConstructor = ktClass.createPrimaryConstructorIfAbsent().replaced(newPrimaryConstructor) -+ ShortenReferences.DEFAULT.process(primaryConstructor.valueParameterList!!) -+ -+ primaryConstructor.addAnnotation(fqNameAnnotation, whiteSpaceText = "" "") -+ -+ element.replace(factory.createSuperTypeCallEntry(element.text + ""(context, attrs, defStyleAttr)"")) -+ } -+ -+ companion object Factory : KotlinSingleIntentionActionFactory() { -+ -+ private val fqNameAnnotation = FqName(""kotlin.jvm.JvmOverloads"") -+ -+ private val requireConstructorParameterTypes = listOf( -+ listOf(""android.content.Context""), -+ listOf(""android.content.Context"", ""android.util.AttributeSet""), -+ listOf(""android.content.Context"", ""android.util.AttributeSet"", ""int"") -+ ) -+ -+ override fun createAction(diagnostic: Diagnostic): IntentionAction? { -+ val superTypeEntry = SUPERTYPE_NOT_INITIALIZED.cast(diagnostic).psiElement -+ -+ val ktClass = superTypeEntry.containingClass() ?: return null -+ if (ktClass.primaryConstructor != null) return null -+ -+ val context = superTypeEntry.analyze() -+ val type = superTypeEntry.typeReference?.let { context[BindingContext.TYPE, it] } ?: return null -+ -+ if (!type.isAndroidView() && type.supertypes().none { it.isAndroidView() }) return null -+ -+ var declaration = type.getDeclaration() -+ -+ if (declaration is KtClass) { -+ declaration = declaration.toLightClass()","I think it could be implemented without light classes, they are pretty heavy and should be avoided if possible -Try to get everything you need from descriptor -```Kotlin -val classDescriptor = type.constructor.declarationDescriptor as? ClassDescriptor ?: return null -val constructorParameters = classDescriptor.constructors.forEach { - it.valueParameters... // some checking stuff -} -```",Why does this class need to be in the package package? Does it -78,"@@ -0,0 +1,13 @@","What is this file? Is it for manual testing? -",This file doesn't belong to the PR. -79,"@@ -0,0 +1,132 @@ -+/* -+ * 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.jvm.compiler -+ -+import com.intellij.openapi.Disposable -+import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles -+import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment -+import org.jetbrains.kotlin.config.JVMConfigurationKeys -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.renderer.* -+import org.jetbrains.kotlin.resolve.lazy.JvmResolveUtil -+import org.jetbrains.kotlin.test.ConfigurationKind -+import org.jetbrains.kotlin.test.KotlinTestUtils -+import org.jetbrains.kotlin.test.TestCaseWithTmpdir -+import org.jetbrains.kotlin.test.TestJdkKind -+import org.junit.Assert -+ -+import java.io.File -+import java.io.IOException -+import java.lang.annotation.Retention -+ -+import org.jetbrains.kotlin.test.KotlinTestUtils.* -+import org.jetbrains.kotlin.test.util.RecursiveDescriptorComparator.validateAndCompareDescriptorWithFile -+ -+abstract class AbstractCompileJavaAgainstKotlinTest : TestCaseWithTmpdir() { -+ -+ @Throws(IOException::class) -+ protected fun doTest(ktFilePath: String) { -+ Assert.assertTrue(ktFilePath.endsWith("".kt"")) -+ val ktFile = File(ktFilePath) -+ val javaFile = File(ktFilePath.replaceFirst(""\\.kt$"".toRegex(), "".java"")) -+ -+ val javaErrorFile = File(ktFilePath.replaceFirst(""\\.kt$"".toRegex(), "".javaerr.txt"")) -+ -+ val out = File(tmpdir, ""out"") -+ -+ val useJavac = this::class.java.name.contains(""WithJavac"")",This is too hacky. We normally use a bunch of protected methods to inject custom behavior in abstract test class,Could you please move `org.jetbrains.kotlin.cli.javac.JavacWra -80,"@@ -0,0 +1,134 @@ -+/* -+ * Copyright 2010-2017 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.kotlin.wrappers.trees -+ -+import com.sun.source.tree.Tree -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.code.Flags -+import com.sun.tools.javac.tree.JCTree -+import com.sun.tools.javac.tree.TreeInfo -+import org.jetbrains.kotlin.descriptors.Visibilities.PUBLIC -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.wrappers.symbols.SymbolBasedClass -+import org.jetbrains.kotlin.wrappers.symbols.SymbolBasedClassifierType -+import org.jetbrains.kotlin.wrappers.symbols.SymbolBasedType -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.java.structure.JavaClassifierType -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.Name -+import org.jetbrains.kotlin.name.SpecialNames -+ -+class TreeBasedClass(tree: T, -+ treePath: TreePath, -+ javac: JavacWrapper) : TreeBasedElement(tree, treePath, javac), JavaClass { -+ -+ override val name -+ get() = SpecialNames.safeIdentifier(tree.simpleName.toString())","Ditto, replace with `Name.identifier`",Please annotate `T` as `@Nullable`. -81,"@@ -0,0 +1,134 @@ -+/* -+ * Copyright 2010-2017 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.kotlin.wrappers.trees -+ -+import com.sun.source.tree.Tree -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.code.Flags -+import com.sun.tools.javac.tree.JCTree -+import com.sun.tools.javac.tree.TreeInfo -+import org.jetbrains.kotlin.descriptors.Visibilities.PUBLIC -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.wrappers.symbols.SymbolBasedClass -+import org.jetbrains.kotlin.wrappers.symbols.SymbolBasedClassifierType -+import org.jetbrains.kotlin.wrappers.symbols.SymbolBasedType -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.java.structure.JavaClassifierType -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.Name -+import org.jetbrains.kotlin.name.SpecialNames -+ -+class TreeBasedClass(tree: T, -+ treePath: TreePath, -+ javac: JavacWrapper) : TreeBasedElement(tree, treePath, javac), JavaClass { -+ -+ override val name -+ get() = SpecialNames.safeIdentifier(tree.simpleName.toString()) -+ -+ override val annotations by lazy { tree.annotations().map { TreeBasedAnnotation(it, treePath, javac) } } -+ -+ override fun findAnnotation(fqName: FqName) = annotations.find { it.classId?.asSingleFqName() == fqName } -+ -+ override val isDeprecatedInJavaDoc -+ get() = findAnnotation(FqName(""java.lang.Deprecated"")) != null -+ -+ override val isAbstract -+ get() = tree.modifiers.isAbstract","Note that there's a corner case of enums with abstract members, which are considered abstract in Java but do not require (and even prohibit) the `abstract` keyword. Please add a test and ensure that it works",Please annotate `T` as `@Nullable`. -82,"@@ -0,0 +1,134 @@ -+/* -+ * Copyright 2010-2017 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.kotlin.wrappers.trees -+ -+import com.sun.source.tree.Tree -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.code.Flags -+import com.sun.tools.javac.tree.JCTree -+import com.sun.tools.javac.tree.TreeInfo -+import org.jetbrains.kotlin.descriptors.Visibilities.PUBLIC -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.wrappers.symbols.SymbolBasedClass -+import org.jetbrains.kotlin.wrappers.symbols.SymbolBasedClassifierType -+import org.jetbrains.kotlin.wrappers.symbols.SymbolBasedType -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.java.structure.JavaClassifierType -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.Name -+import org.jetbrains.kotlin.name.SpecialNames -+ -+class TreeBasedClass(tree: T, -+ treePath: TreePath, -+ javac: JavacWrapper) : TreeBasedElement(tree, treePath, javac), JavaClass { -+ -+ override val name -+ get() = SpecialNames.safeIdentifier(tree.simpleName.toString()) -+ -+ override val annotations by lazy { tree.annotations().map { TreeBasedAnnotation(it, treePath, javac) } } -+ -+ override fun findAnnotation(fqName: FqName) = annotations.find { it.classId?.asSingleFqName() == fqName } -+ -+ override val isDeprecatedInJavaDoc -+ get() = findAnnotation(FqName(""java.lang.Deprecated"")) != null -+ -+ override val isAbstract -+ get() = tree.modifiers.isAbstract -+ -+ override val isStatic",Also please add a test on a nested enum (enum is never inner in Java),Please annotate `T` as `@Nullable`. -83,"@@ -0,0 +1,134 @@ -+/* -+ * Copyright 2010-2017 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.kotlin.wrappers.trees -+ -+import com.sun.source.tree.Tree -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.code.Flags -+import com.sun.tools.javac.tree.JCTree -+import com.sun.tools.javac.tree.TreeInfo -+import org.jetbrains.kotlin.descriptors.Visibilities.PUBLIC -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.wrappers.symbols.SymbolBasedClass -+import org.jetbrains.kotlin.wrappers.symbols.SymbolBasedClassifierType -+import org.jetbrains.kotlin.wrappers.symbols.SymbolBasedType -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.java.structure.JavaClassifierType -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.Name -+import org.jetbrains.kotlin.name.SpecialNames -+ -+class TreeBasedClass(tree: T, -+ treePath: TreePath, -+ javac: JavacWrapper) : TreeBasedElement(tree, treePath, javac), JavaClass { -+ -+ override val name -+ get() = SpecialNames.safeIdentifier(tree.simpleName.toString()) -+ -+ override val annotations by lazy { tree.annotations().map { TreeBasedAnnotation(it, treePath, javac) } } -+ -+ override fun findAnnotation(fqName: FqName) = annotations.find { it.classId?.asSingleFqName() == fqName } -+ -+ override val isDeprecatedInJavaDoc -+ get() = findAnnotation(FqName(""java.lang.Deprecated"")) != null -+ -+ override val isAbstract -+ get() = tree.modifiers.isAbstract -+ -+ override val isStatic -+ get() = (outerClass?.isInterface ?: false) || tree.modifiers.isStatic","Not sure if `isInterface` returns true for annotations, please check and call `isAnnotation` if needed (a test would be nice in any case)",Please annotate `T` as `@Nullable`. -84,"@@ -0,0 +1,134 @@ -+/* -+ * Copyright 2010-2017 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.kotlin.wrappers.trees -+ -+import com.sun.source.tree.Tree -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.code.Flags -+import com.sun.tools.javac.tree.JCTree -+import com.sun.tools.javac.tree.TreeInfo -+import org.jetbrains.kotlin.descriptors.Visibilities.PUBLIC -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.wrappers.symbols.SymbolBasedClass -+import org.jetbrains.kotlin.wrappers.symbols.SymbolBasedClassifierType -+import org.jetbrains.kotlin.wrappers.symbols.SymbolBasedType -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.java.structure.JavaClassifierType -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.Name -+import org.jetbrains.kotlin.name.SpecialNames -+ -+class TreeBasedClass(tree: T, -+ treePath: TreePath, -+ javac: JavacWrapper) : TreeBasedElement(tree, treePath, javac), JavaClass { -+ -+ override val name -+ get() = SpecialNames.safeIdentifier(tree.simpleName.toString()) -+ -+ override val annotations by lazy { tree.annotations().map { TreeBasedAnnotation(it, treePath, javac) } } -+ -+ override fun findAnnotation(fqName: FqName) = annotations.find { it.classId?.asSingleFqName() == fqName } -+ -+ override val isDeprecatedInJavaDoc -+ get() = findAnnotation(FqName(""java.lang.Deprecated"")) != null -+ -+ override val isAbstract -+ get() = tree.modifiers.isAbstract -+ -+ override val isStatic -+ get() = (outerClass?.isInterface ?: false) || tree.modifiers.isStatic -+ -+ override val isFinal -+ get() = tree.modifiers.isFinal -+ -+ override val visibility -+ get() = if (outerClass?.isInterface ?: false) PUBLIC else tree.modifiers.visibility",Also test annotations in addition to interfaces here,Please annotate `T` as `@Nullable`. -85,"@@ -0,0 +1,134 @@ -+/* -+ * Copyright 2010-2017 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.kotlin.wrappers.trees -+ -+import com.sun.source.tree.Tree -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.code.Flags -+import com.sun.tools.javac.tree.JCTree -+import com.sun.tools.javac.tree.TreeInfo -+import org.jetbrains.kotlin.descriptors.Visibilities.PUBLIC -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.wrappers.symbols.SymbolBasedClass -+import org.jetbrains.kotlin.wrappers.symbols.SymbolBasedClassifierType -+import org.jetbrains.kotlin.wrappers.symbols.SymbolBasedType -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.java.structure.JavaClassifierType -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.Name -+import org.jetbrains.kotlin.name.SpecialNames -+ -+class TreeBasedClass(tree: T, -+ treePath: TreePath, -+ javac: JavacWrapper) : TreeBasedElement(tree, treePath, javac), JavaClass { -+ -+ override val name -+ get() = SpecialNames.safeIdentifier(tree.simpleName.toString()) -+ -+ override val annotations by lazy { tree.annotations().map { TreeBasedAnnotation(it, treePath, javac) } } -+ -+ override fun findAnnotation(fqName: FqName) = annotations.find { it.classId?.asSingleFqName() == fqName } -+ -+ override val isDeprecatedInJavaDoc -+ get() = findAnnotation(FqName(""java.lang.Deprecated"")) != null -+ -+ override val isAbstract -+ get() = tree.modifiers.isAbstract -+ -+ override val isStatic -+ get() = (outerClass?.isInterface ?: false) || tree.modifiers.isStatic -+ -+ override val isFinal -+ get() = tree.modifiers.isFinal -+ -+ override val visibility -+ get() = if (outerClass?.isInterface ?: false) PUBLIC else tree.modifiers.visibility -+ -+ override val typeParameters -+ get() = tree.typeParameters.map { TreeBasedTypeParameter(it, TreePath(treePath, it), javac) } -+ -+ override val fqName = treePath.reversed() -+ .joinToString(separator = ""."") { -+ (it as? JCTree.JCCompilationUnit)?.packageName?.toString() -+ ?: (it as JCTree.JCClassDecl).name -+ } -+ .let(::FqName) -+ -+ override val supertypes",There's also an implicit supertype `java.lang.annotation.Annotation` for all annotations,Please annotate `T` as `@Nullable`. -86,"@@ -0,0 +1,134 @@ -+/* -+ * Copyright 2010-2017 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.kotlin.wrappers.trees -+ -+import com.sun.source.tree.Tree -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.code.Flags -+import com.sun.tools.javac.tree.JCTree -+import com.sun.tools.javac.tree.TreeInfo -+import org.jetbrains.kotlin.descriptors.Visibilities.PUBLIC -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.wrappers.symbols.SymbolBasedClass -+import org.jetbrains.kotlin.wrappers.symbols.SymbolBasedClassifierType -+import org.jetbrains.kotlin.wrappers.symbols.SymbolBasedType -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.java.structure.JavaClassifierType -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.Name -+import org.jetbrains.kotlin.name.SpecialNames -+ -+class TreeBasedClass(tree: T, -+ treePath: TreePath, -+ javac: JavacWrapper) : TreeBasedElement(tree, treePath, javac), JavaClass { -+ -+ override val name -+ get() = SpecialNames.safeIdentifier(tree.simpleName.toString()) -+ -+ override val annotations by lazy { tree.annotations().map { TreeBasedAnnotation(it, treePath, javac) } } -+ -+ override fun findAnnotation(fqName: FqName) = annotations.find { it.classId?.asSingleFqName() == fqName } -+ -+ override val isDeprecatedInJavaDoc -+ get() = findAnnotation(FqName(""java.lang.Deprecated"")) != null -+ -+ override val isAbstract -+ get() = tree.modifiers.isAbstract -+ -+ override val isStatic -+ get() = (outerClass?.isInterface ?: false) || tree.modifiers.isStatic -+ -+ override val isFinal -+ get() = tree.modifiers.isFinal -+ -+ override val visibility -+ get() = if (outerClass?.isInterface ?: false) PUBLIC else tree.modifiers.visibility -+ -+ override val typeParameters -+ get() = tree.typeParameters.map { TreeBasedTypeParameter(it, TreePath(treePath, it), javac) } -+ -+ override val fqName = treePath.reversed() -+ .joinToString(separator = ""."") { -+ (it as? JCTree.JCCompilationUnit)?.packageName?.toString() -+ ?: (it as JCTree.JCClassDecl).name -+ } -+ .let(::FqName) -+ -+ override val supertypes -+ get() = arrayListOf().apply { -+ fun JCTree.mapToJavaClassifierType() = when { -+ this is JCTree.JCTypeApply -> TreeBasedClassifierTypeWithTypeArgument(this, TreePath(treePath, this), javac) -+ this is JCTree.JCExpression -> TreeBasedClassifierTypeWithoutTypeArgument(this, TreePath(treePath, this), javac) -+ else -> null -+ } -+ -+ if (isEnum) { -+ (javac.findClass(FqName(""java.lang.Enum"")) as? SymbolBasedClass<*>) -+ ?.let { SymbolBasedType.create(it.element.asType(), javac) as? JavaClassifierType } -+ ?.let { add(it) } -+ } -+ -+ tree.implementing?.map { it.mapToJavaClassifierType() }?.filterNotNull()?.let(this::addAll)",`map` + `filterNotNull` = `mapNotNull`,Please annotate `T` as `@Nullable`. -87,"@@ -0,0 +1,134 @@ -+/* -+ * Copyright 2010-2017 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.kotlin.wrappers.trees -+ -+import com.sun.source.tree.Tree -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.code.Flags -+import com.sun.tools.javac.tree.JCTree -+import com.sun.tools.javac.tree.TreeInfo -+import org.jetbrains.kotlin.descriptors.Visibilities.PUBLIC -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.wrappers.symbols.SymbolBasedClass -+import org.jetbrains.kotlin.wrappers.symbols.SymbolBasedClassifierType -+import org.jetbrains.kotlin.wrappers.symbols.SymbolBasedType -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.java.structure.JavaClassifierType -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.Name -+import org.jetbrains.kotlin.name.SpecialNames -+ -+class TreeBasedClass(tree: T, -+ treePath: TreePath, -+ javac: JavacWrapper) : TreeBasedElement(tree, treePath, javac), JavaClass { -+ -+ override val name -+ get() = SpecialNames.safeIdentifier(tree.simpleName.toString()) -+ -+ override val annotations by lazy { tree.annotations().map { TreeBasedAnnotation(it, treePath, javac) } } -+ -+ override fun findAnnotation(fqName: FqName) = annotations.find { it.classId?.asSingleFqName() == fqName } -+ -+ override val isDeprecatedInJavaDoc -+ get() = findAnnotation(FqName(""java.lang.Deprecated"")) != null -+ -+ override val isAbstract -+ get() = tree.modifiers.isAbstract -+ -+ override val isStatic -+ get() = (outerClass?.isInterface ?: false) || tree.modifiers.isStatic -+ -+ override val isFinal -+ get() = tree.modifiers.isFinal -+ -+ override val visibility -+ get() = if (outerClass?.isInterface ?: false) PUBLIC else tree.modifiers.visibility -+ -+ override val typeParameters -+ get() = tree.typeParameters.map { TreeBasedTypeParameter(it, TreePath(treePath, it), javac) } -+ -+ override val fqName = treePath.reversed() -+ .joinToString(separator = ""."") { -+ (it as? JCTree.JCCompilationUnit)?.packageName?.toString() -+ ?: (it as JCTree.JCClassDecl).name -+ } -+ .let(::FqName) -+ -+ override val supertypes -+ get() = arrayListOf().apply { -+ fun JCTree.mapToJavaClassifierType() = when { -+ this is JCTree.JCTypeApply -> TreeBasedClassifierTypeWithTypeArgument(this, TreePath(treePath, this), javac) -+ this is JCTree.JCExpression -> TreeBasedClassifierTypeWithoutTypeArgument(this, TreePath(treePath, this), javac) -+ else -> null -+ } -+ -+ if (isEnum) { -+ (javac.findClass(FqName(""java.lang.Enum"")) as? SymbolBasedClass<*>) -+ ?.let { SymbolBasedType.create(it.element.asType(), javac) as? JavaClassifierType } -+ ?.let { add(it) } -+ } -+ -+ tree.implementing?.map { it.mapToJavaClassifierType() }?.filterNotNull()?.let(this::addAll) -+ tree.extending?.let { it.mapToJavaClassifierType()?.let(this::add) } -+ -+ if (isEmpty()) { -+ javac.JAVA_LANG_OBJECT?.let { add(SymbolBasedClassifierType(it.element.asType(), javac)) } -+ } -+ } -+ -+ val innerClasses by lazy {",Please also call `.associateBy { it.name }` to make this a map from name to class. This will allow `innerClassNames` and `findInnerClass` to work in O(1),Please annotate `T` as `@Nullable`. -88,"@@ -0,0 +1,134 @@ -+/* -+ * Copyright 2010-2017 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.kotlin.wrappers.trees -+ -+import com.sun.source.tree.Tree -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.code.Flags -+import com.sun.tools.javac.tree.JCTree -+import com.sun.tools.javac.tree.TreeInfo -+import org.jetbrains.kotlin.descriptors.Visibilities.PUBLIC -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.wrappers.symbols.SymbolBasedClass -+import org.jetbrains.kotlin.wrappers.symbols.SymbolBasedClassifierType -+import org.jetbrains.kotlin.wrappers.symbols.SymbolBasedType -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.java.structure.JavaClassifierType -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.Name -+import org.jetbrains.kotlin.name.SpecialNames -+ -+class TreeBasedClass(tree: T, -+ treePath: TreePath, -+ javac: JavacWrapper) : TreeBasedElement(tree, treePath, javac), JavaClass { -+ -+ override val name -+ get() = SpecialNames.safeIdentifier(tree.simpleName.toString()) -+ -+ override val annotations by lazy { tree.annotations().map { TreeBasedAnnotation(it, treePath, javac) } } -+ -+ override fun findAnnotation(fqName: FqName) = annotations.find { it.classId?.asSingleFqName() == fqName } -+ -+ override val isDeprecatedInJavaDoc -+ get() = findAnnotation(FqName(""java.lang.Deprecated"")) != null -+ -+ override val isAbstract -+ get() = tree.modifiers.isAbstract -+ -+ override val isStatic -+ get() = (outerClass?.isInterface ?: false) || tree.modifiers.isStatic -+ -+ override val isFinal -+ get() = tree.modifiers.isFinal -+ -+ override val visibility -+ get() = if (outerClass?.isInterface ?: false) PUBLIC else tree.modifiers.visibility -+ -+ override val typeParameters -+ get() = tree.typeParameters.map { TreeBasedTypeParameter(it, TreePath(treePath, it), javac) } -+ -+ override val fqName = treePath.reversed() -+ .joinToString(separator = ""."") { -+ (it as? JCTree.JCCompilationUnit)?.packageName?.toString() -+ ?: (it as JCTree.JCClassDecl).name -+ } -+ .let(::FqName) -+ -+ override val supertypes -+ get() = arrayListOf().apply { -+ fun JCTree.mapToJavaClassifierType() = when { -+ this is JCTree.JCTypeApply -> TreeBasedClassifierTypeWithTypeArgument(this, TreePath(treePath, this), javac) -+ this is JCTree.JCExpression -> TreeBasedClassifierTypeWithoutTypeArgument(this, TreePath(treePath, this), javac) -+ else -> null -+ } -+ -+ if (isEnum) { -+ (javac.findClass(FqName(""java.lang.Enum"")) as? SymbolBasedClass<*>) -+ ?.let { SymbolBasedType.create(it.element.asType(), javac) as? JavaClassifierType } -+ ?.let { add(it) } -+ } -+ -+ tree.implementing?.map { it.mapToJavaClassifierType() }?.filterNotNull()?.let(this::addAll) -+ tree.extending?.let { it.mapToJavaClassifierType()?.let(this::add) } -+ -+ if (isEmpty()) { -+ javac.JAVA_LANG_OBJECT?.let { add(SymbolBasedClassifierType(it.element.asType(), javac)) } -+ } -+ } -+ -+ val innerClasses by lazy { -+ tree.members -+ .filterIsInstance(JCTree.JCClassDecl::class.java) -+ .map { TreeBasedClass(it, TreePath(treePath, it), javac) } -+ } -+ -+ override val outerClass by lazy { -+ (treePath.parentPath.leaf as? JCTree.JCClassDecl)?.let { TreeBasedClass(it, treePath.parentPath, javac) } -+ } -+ -+ override val isInterface -+ get() = tree.modifiers.flags and Flags.INTERFACE.toLong() != 0L -+ -+ override val isAnnotationType -+ get() = tree.modifiers.flags and Flags.ANNOTATION.toLong() != 0L -+ -+ override val isEnum -+ get() = tree.modifiers.flags and Flags.ENUM.toLong() != 0L -+ -+ override val lightClassOriginKind = null",`get() = null`,Please annotate `T` as `@Nullable`. -89,"@@ -0,0 +1,1391 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.codeInsight.lookup.LookupElement; -+import com.intellij.codeInsight.lookup.LookupElementBuilder; -+import com.intellij.codeInsight.template.*; -+import com.intellij.codeInsight.template.impl.TemplateImpl; -+import com.intellij.codeInsight.template.impl.Variable; -+import com.intellij.ide.fileTemplates.FileTemplate; -+import com.intellij.ide.fileTemplates.FileTemplateManager; -+import com.intellij.ide.util.PsiElementListCellRenderer; -+import com.intellij.openapi.application.ApplicationManager; -+import com.intellij.openapi.command.CommandProcessor; -+import com.intellij.openapi.editor.CaretModel; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.fileEditor.FileEditorManager; -+import com.intellij.openapi.progress.ProcessCanceledException; -+import com.intellij.openapi.project.Project; -+import com.intellij.openapi.ui.popup.PopupChooserBuilder; -+import com.intellij.openapi.util.TextRange; -+import com.intellij.openapi.util.text.StringUtil; -+import com.intellij.openapi.vfs.VirtualFile; -+import com.intellij.psi.PsiDocumentManager; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.PsiReference; -+import com.intellij.psi.search.SearchScope; -+import com.intellij.psi.util.PsiTreeUtil; -+import com.intellij.refactoring.psi.SearchUtils; -+import com.intellij.ui.components.JBList; -+import com.intellij.util.ArrayUtil; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NonNls; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.descriptors.*; -+import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1; -+import org.jetbrains.jet.lang.diagnostics.Errors; -+import org.jetbrains.jet.lang.psi.*; -+import org.jetbrains.jet.lang.resolve.BindingContext; -+import org.jetbrains.jet.lang.resolve.BindingContextUtils; -+import org.jetbrains.jet.lang.resolve.DescriptorUtils; -+import org.jetbrains.jet.lang.resolve.name.Name; -+import org.jetbrains.jet.lang.resolve.scopes.JetScope; -+import org.jetbrains.jet.lang.types.*; -+import org.jetbrains.jet.lang.types.checker.JetTypeChecker; -+import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; -+import org.jetbrains.jet.plugin.JetBundle; -+import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening; -+import org.jetbrains.jet.plugin.presentation.JetLightClassListCellRenderer; -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; -+import org.jetbrains.jet.plugin.refactoring.JetNameSuggester; -+import org.jetbrains.jet.plugin.refactoring.JetNameValidator; -+import org.jetbrains.jet.plugin.references.JetSimpleNameReference; -+import org.jetbrains.jet.renderer.DescriptorRenderer; -+ -+import javax.swing.*; -+import java.util.*; -+import java.util.regex.Matcher; -+import java.util.regex.Pattern; -+ -+public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { -+ private static final String TYPE_PARAMETER_LIST_VARIABLE_NAME = ""typeParameterList""; -+ private static final String TEMPLATE_FROM_USAGE_METHOD_BODY = ""New Kotlin Method Body.kt""; -+ private static final Pattern COMPONENT_FUNCTION_PATTERN = Pattern.compile(""^component(\\d+)$""); -+ -+ /** -+ * Represents a single choice for a type (e.g. parameter type or return type). -+ */ -+ private static class TypeCandidate { -+ private final JetType type; -+ private final TypeParameterDescriptor[] typeParameters; -+ private String renderedType; -+ private String[] typeParameterNames; -+ -+ public TypeCandidate(@NotNull JetType type) { -+ this.type = type; -+ Set typeParametersInType = getTypeParametersInType(type); -+ typeParameters = typeParametersInType.toArray(new TypeParameterDescriptor[typeParametersInType.size()]); -+ renderedType = renderTypeShort(type, Collections.emptyMap()); -+ } -+ -+ public TypeCandidate(@NotNull JetType type, @NotNull JetScope scope) { -+ this.type = type; -+ typeParameters = getTypeParameterNamesNotInScope(getTypeParametersInType(type), scope); -+ } -+ -+ public void render(@NotNull Map typeParameterNameMap) { -+ renderedType = renderTypeShort(type, typeParameterNameMap); -+ typeParameterNames = new String[typeParameters.length]; -+ int i = 0; -+ for (TypeParameterDescriptor typeParameter : typeParameters) { -+ typeParameterNames[i] = typeParameterNameMap.get(typeParameter); -+ i++; -+ } -+ } -+ -+ @NotNull JetType getType() { -+ return type; -+ } -+ -+ @NotNull -+ public String getRenderedType() { -+ assert renderedType != null : ""call render() first""; -+ return renderedType; -+ } -+ -+ @NotNull -+ public String[] getTypeParameterNames() { -+ assert typeParameterNames != null : ""call render() first""; -+ return typeParameterNames; -+ } -+ -+ @NotNull -+ public TypeParameterDescriptor[] getTypeParameters() { -+ return typeParameters; -+ } -+ } -+ -+ /** -+ * Represents a concrete type or a set of types yet to be inferred from an expression. -+ */ -+ private static class TypeOrExpressionThereof { -+ private final JetExpression expressionOfType; -+ private final JetType type; -+ private final Variance variance; -+ private TypeCandidate[] typeCandidates; -+ private String[] cachedNameCandidatesFromExpression; -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType) { -+ this(expressionOfType, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType, Variance variance) { -+ this(expressionOfType, null, variance); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type) { -+ this(type, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type, Variance variance) { -+ this(null, type, variance); -+ } -+ -+ private TypeOrExpressionThereof(@Nullable JetExpression expressionOfType, @Nullable JetType type, Variance variance) { -+ this.expressionOfType = expressionOfType; -+ this.type = type; -+ this.variance = variance; -+ }","Five constructors for non-API constructor seems to be too much. Maybe provide default values manually on call sites? -",Why is this needed? Looks like a du -90,"@@ -0,0 +1,1391 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.codeInsight.lookup.LookupElement; -+import com.intellij.codeInsight.lookup.LookupElementBuilder; -+import com.intellij.codeInsight.template.*; -+import com.intellij.codeInsight.template.impl.TemplateImpl; -+import com.intellij.codeInsight.template.impl.Variable; -+import com.intellij.ide.fileTemplates.FileTemplate; -+import com.intellij.ide.fileTemplates.FileTemplateManager; -+import com.intellij.ide.util.PsiElementListCellRenderer; -+import com.intellij.openapi.application.ApplicationManager; -+import com.intellij.openapi.command.CommandProcessor; -+import com.intellij.openapi.editor.CaretModel; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.fileEditor.FileEditorManager; -+import com.intellij.openapi.progress.ProcessCanceledException; -+import com.intellij.openapi.project.Project; -+import com.intellij.openapi.ui.popup.PopupChooserBuilder; -+import com.intellij.openapi.util.TextRange; -+import com.intellij.openapi.util.text.StringUtil; -+import com.intellij.openapi.vfs.VirtualFile; -+import com.intellij.psi.PsiDocumentManager; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.PsiReference; -+import com.intellij.psi.search.SearchScope; -+import com.intellij.psi.util.PsiTreeUtil; -+import com.intellij.refactoring.psi.SearchUtils; -+import com.intellij.ui.components.JBList; -+import com.intellij.util.ArrayUtil; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NonNls; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.descriptors.*; -+import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1; -+import org.jetbrains.jet.lang.diagnostics.Errors; -+import org.jetbrains.jet.lang.psi.*; -+import org.jetbrains.jet.lang.resolve.BindingContext; -+import org.jetbrains.jet.lang.resolve.BindingContextUtils; -+import org.jetbrains.jet.lang.resolve.DescriptorUtils; -+import org.jetbrains.jet.lang.resolve.name.Name; -+import org.jetbrains.jet.lang.resolve.scopes.JetScope; -+import org.jetbrains.jet.lang.types.*; -+import org.jetbrains.jet.lang.types.checker.JetTypeChecker; -+import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; -+import org.jetbrains.jet.plugin.JetBundle; -+import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening; -+import org.jetbrains.jet.plugin.presentation.JetLightClassListCellRenderer; -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; -+import org.jetbrains.jet.plugin.refactoring.JetNameSuggester; -+import org.jetbrains.jet.plugin.refactoring.JetNameValidator; -+import org.jetbrains.jet.plugin.references.JetSimpleNameReference; -+import org.jetbrains.jet.renderer.DescriptorRenderer; -+ -+import javax.swing.*; -+import java.util.*; -+import java.util.regex.Matcher; -+import java.util.regex.Pattern; -+ -+public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { -+ private static final String TYPE_PARAMETER_LIST_VARIABLE_NAME = ""typeParameterList""; -+ private static final String TEMPLATE_FROM_USAGE_METHOD_BODY = ""New Kotlin Method Body.kt""; -+ private static final Pattern COMPONENT_FUNCTION_PATTERN = Pattern.compile(""^component(\\d+)$""); -+ -+ /** -+ * Represents a single choice for a type (e.g. parameter type or return type). -+ */ -+ private static class TypeCandidate { -+ private final JetType type; -+ private final TypeParameterDescriptor[] typeParameters; -+ private String renderedType; -+ private String[] typeParameterNames; -+ -+ public TypeCandidate(@NotNull JetType type) { -+ this.type = type; -+ Set typeParametersInType = getTypeParametersInType(type); -+ typeParameters = typeParametersInType.toArray(new TypeParameterDescriptor[typeParametersInType.size()]); -+ renderedType = renderTypeShort(type, Collections.emptyMap()); -+ } -+ -+ public TypeCandidate(@NotNull JetType type, @NotNull JetScope scope) { -+ this.type = type; -+ typeParameters = getTypeParameterNamesNotInScope(getTypeParametersInType(type), scope); -+ } -+ -+ public void render(@NotNull Map typeParameterNameMap) { -+ renderedType = renderTypeShort(type, typeParameterNameMap); -+ typeParameterNames = new String[typeParameters.length]; -+ int i = 0; -+ for (TypeParameterDescriptor typeParameter : typeParameters) { -+ typeParameterNames[i] = typeParameterNameMap.get(typeParameter); -+ i++; -+ } -+ } -+ -+ @NotNull JetType getType() { -+ return type; -+ } -+ -+ @NotNull -+ public String getRenderedType() { -+ assert renderedType != null : ""call render() first""; -+ return renderedType; -+ } -+ -+ @NotNull -+ public String[] getTypeParameterNames() { -+ assert typeParameterNames != null : ""call render() first""; -+ return typeParameterNames; -+ } -+ -+ @NotNull -+ public TypeParameterDescriptor[] getTypeParameters() { -+ return typeParameters; -+ } -+ } -+ -+ /** -+ * Represents a concrete type or a set of types yet to be inferred from an expression. -+ */ -+ private static class TypeOrExpressionThereof { -+ private final JetExpression expressionOfType; -+ private final JetType type; -+ private final Variance variance; -+ private TypeCandidate[] typeCandidates; -+ private String[] cachedNameCandidatesFromExpression; -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType) { -+ this(expressionOfType, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType, Variance variance) { -+ this(expressionOfType, null, variance); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type) { -+ this(type, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type, Variance variance) { -+ this(null, type, variance); -+ } -+ -+ private TypeOrExpressionThereof(@Nullable JetExpression expressionOfType, @Nullable JetType type, Variance variance) { -+ this.expressionOfType = expressionOfType; -+ this.type = type; -+ this.variance = variance; -+ } -+ -+ public boolean isType() { -+ return this.type != null; -+ } -+ -+ @NotNull -+ public JetType getType() { -+ assert this.type != null; -+ return this.type; -+ } -+ -+ @NotNull -+ private List getPossibleTypes(BindingContext context) { -+ List types = new ArrayList(); -+ if (isType()) { -+ assert type != null : ""!isType() means type == null && expressionOfType != null""; -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ for (JetType type : guessTypeForExpression(expressionOfType, context)) { -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } -+ } -+ return types; -+ } -+ -+ public void computeTypeCandidates(@NotNull BindingContext context) { -+ Collection types = getPossibleTypes(context); -+ -+ typeCandidates = new TypeCandidate[types.size()]; -+ int i = 0;","Use ArrayList instead of array. This won't take much extra memory, but will simplify code. -",Why is this needed? Looks like a du -91,"@@ -0,0 +1,1391 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.codeInsight.lookup.LookupElement; -+import com.intellij.codeInsight.lookup.LookupElementBuilder; -+import com.intellij.codeInsight.template.*; -+import com.intellij.codeInsight.template.impl.TemplateImpl; -+import com.intellij.codeInsight.template.impl.Variable; -+import com.intellij.ide.fileTemplates.FileTemplate; -+import com.intellij.ide.fileTemplates.FileTemplateManager; -+import com.intellij.ide.util.PsiElementListCellRenderer; -+import com.intellij.openapi.application.ApplicationManager; -+import com.intellij.openapi.command.CommandProcessor; -+import com.intellij.openapi.editor.CaretModel; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.fileEditor.FileEditorManager; -+import com.intellij.openapi.progress.ProcessCanceledException; -+import com.intellij.openapi.project.Project; -+import com.intellij.openapi.ui.popup.PopupChooserBuilder; -+import com.intellij.openapi.util.TextRange; -+import com.intellij.openapi.util.text.StringUtil; -+import com.intellij.openapi.vfs.VirtualFile; -+import com.intellij.psi.PsiDocumentManager; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.PsiReference; -+import com.intellij.psi.search.SearchScope; -+import com.intellij.psi.util.PsiTreeUtil; -+import com.intellij.refactoring.psi.SearchUtils; -+import com.intellij.ui.components.JBList; -+import com.intellij.util.ArrayUtil; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NonNls; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.descriptors.*; -+import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1; -+import org.jetbrains.jet.lang.diagnostics.Errors; -+import org.jetbrains.jet.lang.psi.*; -+import org.jetbrains.jet.lang.resolve.BindingContext; -+import org.jetbrains.jet.lang.resolve.BindingContextUtils; -+import org.jetbrains.jet.lang.resolve.DescriptorUtils; -+import org.jetbrains.jet.lang.resolve.name.Name; -+import org.jetbrains.jet.lang.resolve.scopes.JetScope; -+import org.jetbrains.jet.lang.types.*; -+import org.jetbrains.jet.lang.types.checker.JetTypeChecker; -+import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; -+import org.jetbrains.jet.plugin.JetBundle; -+import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening; -+import org.jetbrains.jet.plugin.presentation.JetLightClassListCellRenderer; -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; -+import org.jetbrains.jet.plugin.refactoring.JetNameSuggester; -+import org.jetbrains.jet.plugin.refactoring.JetNameValidator; -+import org.jetbrains.jet.plugin.references.JetSimpleNameReference; -+import org.jetbrains.jet.renderer.DescriptorRenderer; -+ -+import javax.swing.*; -+import java.util.*; -+import java.util.regex.Matcher; -+import java.util.regex.Pattern; -+ -+public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { -+ private static final String TYPE_PARAMETER_LIST_VARIABLE_NAME = ""typeParameterList""; -+ private static final String TEMPLATE_FROM_USAGE_METHOD_BODY = ""New Kotlin Method Body.kt""; -+ private static final Pattern COMPONENT_FUNCTION_PATTERN = Pattern.compile(""^component(\\d+)$""); -+ -+ /** -+ * Represents a single choice for a type (e.g. parameter type or return type). -+ */ -+ private static class TypeCandidate { -+ private final JetType type; -+ private final TypeParameterDescriptor[] typeParameters; -+ private String renderedType; -+ private String[] typeParameterNames; -+ -+ public TypeCandidate(@NotNull JetType type) { -+ this.type = type; -+ Set typeParametersInType = getTypeParametersInType(type); -+ typeParameters = typeParametersInType.toArray(new TypeParameterDescriptor[typeParametersInType.size()]); -+ renderedType = renderTypeShort(type, Collections.emptyMap()); -+ } -+ -+ public TypeCandidate(@NotNull JetType type, @NotNull JetScope scope) { -+ this.type = type; -+ typeParameters = getTypeParameterNamesNotInScope(getTypeParametersInType(type), scope); -+ } -+ -+ public void render(@NotNull Map typeParameterNameMap) { -+ renderedType = renderTypeShort(type, typeParameterNameMap); -+ typeParameterNames = new String[typeParameters.length]; -+ int i = 0; -+ for (TypeParameterDescriptor typeParameter : typeParameters) { -+ typeParameterNames[i] = typeParameterNameMap.get(typeParameter); -+ i++; -+ } -+ } -+ -+ @NotNull JetType getType() { -+ return type; -+ } -+ -+ @NotNull -+ public String getRenderedType() { -+ assert renderedType != null : ""call render() first""; -+ return renderedType; -+ } -+ -+ @NotNull -+ public String[] getTypeParameterNames() { -+ assert typeParameterNames != null : ""call render() first""; -+ return typeParameterNames; -+ } -+ -+ @NotNull -+ public TypeParameterDescriptor[] getTypeParameters() { -+ return typeParameters; -+ } -+ } -+ -+ /** -+ * Represents a concrete type or a set of types yet to be inferred from an expression. -+ */ -+ private static class TypeOrExpressionThereof { -+ private final JetExpression expressionOfType; -+ private final JetType type; -+ private final Variance variance; -+ private TypeCandidate[] typeCandidates; -+ private String[] cachedNameCandidatesFromExpression; -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType) { -+ this(expressionOfType, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType, Variance variance) { -+ this(expressionOfType, null, variance); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type) { -+ this(type, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type, Variance variance) { -+ this(null, type, variance); -+ } -+ -+ private TypeOrExpressionThereof(@Nullable JetExpression expressionOfType, @Nullable JetType type, Variance variance) { -+ this.expressionOfType = expressionOfType; -+ this.type = type; -+ this.variance = variance; -+ } -+ -+ public boolean isType() { -+ return this.type != null; -+ } -+ -+ @NotNull -+ public JetType getType() { -+ assert this.type != null; -+ return this.type; -+ } -+ -+ @NotNull -+ private List getPossibleTypes(BindingContext context) { -+ List types = new ArrayList(); -+ if (isType()) { -+ assert type != null : ""!isType() means type == null && expressionOfType != null""; -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ for (JetType type : guessTypeForExpression(expressionOfType, context)) { -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } -+ } -+ return types; -+ } -+ -+ public void computeTypeCandidates(@NotNull BindingContext context) { -+ Collection types = getPossibleTypes(context); -+ -+ typeCandidates = new TypeCandidate[types.size()]; -+ int i = 0; -+ for (JetType type : types) { -+ typeCandidates[i] = new TypeCandidate(type); -+ i++; -+ } -+ } -+ -+ public void computeTypeCandidates( -+ @NotNull BindingContext context, -+ @NotNull TypeSubstitution[] substitutions, -+ @NotNull JetScope scope -+ ) {","I don't understand what this method does. -",Why is this needed? Looks like a du -92,"@@ -0,0 +1,1391 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.codeInsight.lookup.LookupElement; -+import com.intellij.codeInsight.lookup.LookupElementBuilder; -+import com.intellij.codeInsight.template.*; -+import com.intellij.codeInsight.template.impl.TemplateImpl; -+import com.intellij.codeInsight.template.impl.Variable; -+import com.intellij.ide.fileTemplates.FileTemplate; -+import com.intellij.ide.fileTemplates.FileTemplateManager; -+import com.intellij.ide.util.PsiElementListCellRenderer; -+import com.intellij.openapi.application.ApplicationManager; -+import com.intellij.openapi.command.CommandProcessor; -+import com.intellij.openapi.editor.CaretModel; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.fileEditor.FileEditorManager; -+import com.intellij.openapi.progress.ProcessCanceledException; -+import com.intellij.openapi.project.Project; -+import com.intellij.openapi.ui.popup.PopupChooserBuilder; -+import com.intellij.openapi.util.TextRange; -+import com.intellij.openapi.util.text.StringUtil; -+import com.intellij.openapi.vfs.VirtualFile; -+import com.intellij.psi.PsiDocumentManager; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.PsiReference; -+import com.intellij.psi.search.SearchScope; -+import com.intellij.psi.util.PsiTreeUtil; -+import com.intellij.refactoring.psi.SearchUtils; -+import com.intellij.ui.components.JBList; -+import com.intellij.util.ArrayUtil; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NonNls; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.descriptors.*; -+import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1; -+import org.jetbrains.jet.lang.diagnostics.Errors; -+import org.jetbrains.jet.lang.psi.*; -+import org.jetbrains.jet.lang.resolve.BindingContext; -+import org.jetbrains.jet.lang.resolve.BindingContextUtils; -+import org.jetbrains.jet.lang.resolve.DescriptorUtils; -+import org.jetbrains.jet.lang.resolve.name.Name; -+import org.jetbrains.jet.lang.resolve.scopes.JetScope; -+import org.jetbrains.jet.lang.types.*; -+import org.jetbrains.jet.lang.types.checker.JetTypeChecker; -+import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; -+import org.jetbrains.jet.plugin.JetBundle; -+import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening; -+import org.jetbrains.jet.plugin.presentation.JetLightClassListCellRenderer; -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; -+import org.jetbrains.jet.plugin.refactoring.JetNameSuggester; -+import org.jetbrains.jet.plugin.refactoring.JetNameValidator; -+import org.jetbrains.jet.plugin.references.JetSimpleNameReference; -+import org.jetbrains.jet.renderer.DescriptorRenderer; -+ -+import javax.swing.*; -+import java.util.*; -+import java.util.regex.Matcher; -+import java.util.regex.Pattern; -+ -+public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { -+ private static final String TYPE_PARAMETER_LIST_VARIABLE_NAME = ""typeParameterList""; -+ private static final String TEMPLATE_FROM_USAGE_METHOD_BODY = ""New Kotlin Method Body.kt""; -+ private static final Pattern COMPONENT_FUNCTION_PATTERN = Pattern.compile(""^component(\\d+)$""); -+ -+ /** -+ * Represents a single choice for a type (e.g. parameter type or return type). -+ */ -+ private static class TypeCandidate { -+ private final JetType type; -+ private final TypeParameterDescriptor[] typeParameters; -+ private String renderedType; -+ private String[] typeParameterNames; -+ -+ public TypeCandidate(@NotNull JetType type) { -+ this.type = type; -+ Set typeParametersInType = getTypeParametersInType(type); -+ typeParameters = typeParametersInType.toArray(new TypeParameterDescriptor[typeParametersInType.size()]); -+ renderedType = renderTypeShort(type, Collections.emptyMap()); -+ } -+ -+ public TypeCandidate(@NotNull JetType type, @NotNull JetScope scope) { -+ this.type = type; -+ typeParameters = getTypeParameterNamesNotInScope(getTypeParametersInType(type), scope); -+ } -+ -+ public void render(@NotNull Map typeParameterNameMap) { -+ renderedType = renderTypeShort(type, typeParameterNameMap); -+ typeParameterNames = new String[typeParameters.length]; -+ int i = 0; -+ for (TypeParameterDescriptor typeParameter : typeParameters) { -+ typeParameterNames[i] = typeParameterNameMap.get(typeParameter); -+ i++; -+ } -+ } -+ -+ @NotNull JetType getType() { -+ return type; -+ } -+ -+ @NotNull -+ public String getRenderedType() { -+ assert renderedType != null : ""call render() first""; -+ return renderedType; -+ } -+ -+ @NotNull -+ public String[] getTypeParameterNames() { -+ assert typeParameterNames != null : ""call render() first""; -+ return typeParameterNames; -+ } -+ -+ @NotNull -+ public TypeParameterDescriptor[] getTypeParameters() { -+ return typeParameters; -+ } -+ } -+ -+ /** -+ * Represents a concrete type or a set of types yet to be inferred from an expression. -+ */ -+ private static class TypeOrExpressionThereof { -+ private final JetExpression expressionOfType; -+ private final JetType type; -+ private final Variance variance; -+ private TypeCandidate[] typeCandidates; -+ private String[] cachedNameCandidatesFromExpression; -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType) { -+ this(expressionOfType, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType, Variance variance) { -+ this(expressionOfType, null, variance); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type) { -+ this(type, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type, Variance variance) { -+ this(null, type, variance); -+ } -+ -+ private TypeOrExpressionThereof(@Nullable JetExpression expressionOfType, @Nullable JetType type, Variance variance) { -+ this.expressionOfType = expressionOfType; -+ this.type = type; -+ this.variance = variance; -+ } -+ -+ public boolean isType() { -+ return this.type != null; -+ } -+ -+ @NotNull -+ public JetType getType() { -+ assert this.type != null; -+ return this.type; -+ } -+ -+ @NotNull -+ private List getPossibleTypes(BindingContext context) { -+ List types = new ArrayList(); -+ if (isType()) { -+ assert type != null : ""!isType() means type == null && expressionOfType != null""; -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ for (JetType type : guessTypeForExpression(expressionOfType, context)) { -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } -+ } -+ return types; -+ } -+ -+ public void computeTypeCandidates(@NotNull BindingContext context) { -+ Collection types = getPossibleTypes(context); -+ -+ typeCandidates = new TypeCandidate[types.size()]; -+ int i = 0; -+ for (JetType type : types) { -+ typeCandidates[i] = new TypeCandidate(type); -+ i++; -+ } -+ } -+ -+ public void computeTypeCandidates( -+ @NotNull BindingContext context, -+ @NotNull TypeSubstitution[] substitutions, -+ @NotNull JetScope scope -+ ) { -+ List types = getPossibleTypes(context); -+ Collections.reverse(types); // reverse and reverse back later, so that things added below are added at the front -+ -+ Set newTypes = new LinkedHashSet(types); -+ for (TypeSubstitution substitution : substitutions) { // each substitution can be applied or not, so we offer all options","What does mean ""applied""? -",Why is this needed? Looks like a du -93,"@@ -0,0 +1,1391 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.codeInsight.lookup.LookupElement; -+import com.intellij.codeInsight.lookup.LookupElementBuilder; -+import com.intellij.codeInsight.template.*; -+import com.intellij.codeInsight.template.impl.TemplateImpl; -+import com.intellij.codeInsight.template.impl.Variable; -+import com.intellij.ide.fileTemplates.FileTemplate; -+import com.intellij.ide.fileTemplates.FileTemplateManager; -+import com.intellij.ide.util.PsiElementListCellRenderer; -+import com.intellij.openapi.application.ApplicationManager; -+import com.intellij.openapi.command.CommandProcessor; -+import com.intellij.openapi.editor.CaretModel; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.fileEditor.FileEditorManager; -+import com.intellij.openapi.progress.ProcessCanceledException; -+import com.intellij.openapi.project.Project; -+import com.intellij.openapi.ui.popup.PopupChooserBuilder; -+import com.intellij.openapi.util.TextRange; -+import com.intellij.openapi.util.text.StringUtil; -+import com.intellij.openapi.vfs.VirtualFile; -+import com.intellij.psi.PsiDocumentManager; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.PsiReference; -+import com.intellij.psi.search.SearchScope; -+import com.intellij.psi.util.PsiTreeUtil; -+import com.intellij.refactoring.psi.SearchUtils; -+import com.intellij.ui.components.JBList; -+import com.intellij.util.ArrayUtil; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NonNls; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.descriptors.*; -+import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1; -+import org.jetbrains.jet.lang.diagnostics.Errors; -+import org.jetbrains.jet.lang.psi.*; -+import org.jetbrains.jet.lang.resolve.BindingContext; -+import org.jetbrains.jet.lang.resolve.BindingContextUtils; -+import org.jetbrains.jet.lang.resolve.DescriptorUtils; -+import org.jetbrains.jet.lang.resolve.name.Name; -+import org.jetbrains.jet.lang.resolve.scopes.JetScope; -+import org.jetbrains.jet.lang.types.*; -+import org.jetbrains.jet.lang.types.checker.JetTypeChecker; -+import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; -+import org.jetbrains.jet.plugin.JetBundle; -+import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening; -+import org.jetbrains.jet.plugin.presentation.JetLightClassListCellRenderer; -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; -+import org.jetbrains.jet.plugin.refactoring.JetNameSuggester; -+import org.jetbrains.jet.plugin.refactoring.JetNameValidator; -+import org.jetbrains.jet.plugin.references.JetSimpleNameReference; -+import org.jetbrains.jet.renderer.DescriptorRenderer; -+ -+import javax.swing.*; -+import java.util.*; -+import java.util.regex.Matcher; -+import java.util.regex.Pattern; -+ -+public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { -+ private static final String TYPE_PARAMETER_LIST_VARIABLE_NAME = ""typeParameterList""; -+ private static final String TEMPLATE_FROM_USAGE_METHOD_BODY = ""New Kotlin Method Body.kt""; -+ private static final Pattern COMPONENT_FUNCTION_PATTERN = Pattern.compile(""^component(\\d+)$""); -+ -+ /** -+ * Represents a single choice for a type (e.g. parameter type or return type). -+ */ -+ private static class TypeCandidate { -+ private final JetType type; -+ private final TypeParameterDescriptor[] typeParameters; -+ private String renderedType; -+ private String[] typeParameterNames; -+ -+ public TypeCandidate(@NotNull JetType type) { -+ this.type = type; -+ Set typeParametersInType = getTypeParametersInType(type); -+ typeParameters = typeParametersInType.toArray(new TypeParameterDescriptor[typeParametersInType.size()]); -+ renderedType = renderTypeShort(type, Collections.emptyMap()); -+ } -+ -+ public TypeCandidate(@NotNull JetType type, @NotNull JetScope scope) { -+ this.type = type; -+ typeParameters = getTypeParameterNamesNotInScope(getTypeParametersInType(type), scope); -+ } -+ -+ public void render(@NotNull Map typeParameterNameMap) { -+ renderedType = renderTypeShort(type, typeParameterNameMap); -+ typeParameterNames = new String[typeParameters.length]; -+ int i = 0; -+ for (TypeParameterDescriptor typeParameter : typeParameters) { -+ typeParameterNames[i] = typeParameterNameMap.get(typeParameter); -+ i++; -+ } -+ } -+ -+ @NotNull JetType getType() { -+ return type; -+ } -+ -+ @NotNull -+ public String getRenderedType() { -+ assert renderedType != null : ""call render() first""; -+ return renderedType; -+ } -+ -+ @NotNull -+ public String[] getTypeParameterNames() { -+ assert typeParameterNames != null : ""call render() first""; -+ return typeParameterNames; -+ } -+ -+ @NotNull -+ public TypeParameterDescriptor[] getTypeParameters() { -+ return typeParameters; -+ } -+ } -+ -+ /** -+ * Represents a concrete type or a set of types yet to be inferred from an expression. -+ */ -+ private static class TypeOrExpressionThereof { -+ private final JetExpression expressionOfType; -+ private final JetType type; -+ private final Variance variance; -+ private TypeCandidate[] typeCandidates; -+ private String[] cachedNameCandidatesFromExpression; -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType) { -+ this(expressionOfType, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType, Variance variance) { -+ this(expressionOfType, null, variance); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type) { -+ this(type, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type, Variance variance) { -+ this(null, type, variance); -+ } -+ -+ private TypeOrExpressionThereof(@Nullable JetExpression expressionOfType, @Nullable JetType type, Variance variance) { -+ this.expressionOfType = expressionOfType; -+ this.type = type; -+ this.variance = variance; -+ } -+ -+ public boolean isType() { -+ return this.type != null; -+ } -+ -+ @NotNull -+ public JetType getType() { -+ assert this.type != null; -+ return this.type; -+ } -+ -+ @NotNull -+ private List getPossibleTypes(BindingContext context) { -+ List types = new ArrayList(); -+ if (isType()) { -+ assert type != null : ""!isType() means type == null && expressionOfType != null""; -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ for (JetType type : guessTypeForExpression(expressionOfType, context)) { -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } -+ } -+ return types; -+ } -+ -+ public void computeTypeCandidates(@NotNull BindingContext context) { -+ Collection types = getPossibleTypes(context); -+ -+ typeCandidates = new TypeCandidate[types.size()]; -+ int i = 0; -+ for (JetType type : types) { -+ typeCandidates[i] = new TypeCandidate(type); -+ i++; -+ } -+ } -+ -+ public void computeTypeCandidates( -+ @NotNull BindingContext context, -+ @NotNull TypeSubstitution[] substitutions, -+ @NotNull JetScope scope -+ ) { -+ List types = getPossibleTypes(context); -+ Collections.reverse(types); // reverse and reverse back later, so that things added below are added at the front -+ -+ Set newTypes = new LinkedHashSet(types); -+ for (TypeSubstitution substitution : substitutions) { // each substitution can be applied or not, so we offer all options -+ List toAdd = new ArrayList(); -+ List toRemove = new ArrayList(); -+ for (JetType type : newTypes) { -+ toAdd.add(substituteType(type, substitution, variance)); -+ // substitution.byType are type arguments, but they cannot already occur in the type before substitution -+ if (containsType(type, substitution.getByType())) { -+ toRemove.add(type); -+ } -+ } -+ newTypes.addAll(toAdd); -+ newTypes.removeAll(toRemove); -+ } -+ -+ if (newTypes.isEmpty()) { -+ newTypes.add(KotlinBuiltIns.getInstance().getAnyType()); -+ } -+ -+ typeCandidates = new TypeCandidate[newTypes.size()];","Use list, and `Collections.reverse()` afterwards. -",Why is this needed? Looks like a du -94,"@@ -0,0 +1,1391 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.codeInsight.lookup.LookupElement; -+import com.intellij.codeInsight.lookup.LookupElementBuilder; -+import com.intellij.codeInsight.template.*; -+import com.intellij.codeInsight.template.impl.TemplateImpl; -+import com.intellij.codeInsight.template.impl.Variable; -+import com.intellij.ide.fileTemplates.FileTemplate; -+import com.intellij.ide.fileTemplates.FileTemplateManager; -+import com.intellij.ide.util.PsiElementListCellRenderer; -+import com.intellij.openapi.application.ApplicationManager; -+import com.intellij.openapi.command.CommandProcessor; -+import com.intellij.openapi.editor.CaretModel; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.fileEditor.FileEditorManager; -+import com.intellij.openapi.progress.ProcessCanceledException; -+import com.intellij.openapi.project.Project; -+import com.intellij.openapi.ui.popup.PopupChooserBuilder; -+import com.intellij.openapi.util.TextRange; -+import com.intellij.openapi.util.text.StringUtil; -+import com.intellij.openapi.vfs.VirtualFile; -+import com.intellij.psi.PsiDocumentManager; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.PsiReference; -+import com.intellij.psi.search.SearchScope; -+import com.intellij.psi.util.PsiTreeUtil; -+import com.intellij.refactoring.psi.SearchUtils; -+import com.intellij.ui.components.JBList; -+import com.intellij.util.ArrayUtil; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NonNls; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.descriptors.*; -+import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1; -+import org.jetbrains.jet.lang.diagnostics.Errors; -+import org.jetbrains.jet.lang.psi.*; -+import org.jetbrains.jet.lang.resolve.BindingContext; -+import org.jetbrains.jet.lang.resolve.BindingContextUtils; -+import org.jetbrains.jet.lang.resolve.DescriptorUtils; -+import org.jetbrains.jet.lang.resolve.name.Name; -+import org.jetbrains.jet.lang.resolve.scopes.JetScope; -+import org.jetbrains.jet.lang.types.*; -+import org.jetbrains.jet.lang.types.checker.JetTypeChecker; -+import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; -+import org.jetbrains.jet.plugin.JetBundle; -+import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening; -+import org.jetbrains.jet.plugin.presentation.JetLightClassListCellRenderer; -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; -+import org.jetbrains.jet.plugin.refactoring.JetNameSuggester; -+import org.jetbrains.jet.plugin.refactoring.JetNameValidator; -+import org.jetbrains.jet.plugin.references.JetSimpleNameReference; -+import org.jetbrains.jet.renderer.DescriptorRenderer; -+ -+import javax.swing.*; -+import java.util.*; -+import java.util.regex.Matcher; -+import java.util.regex.Pattern; -+ -+public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { -+ private static final String TYPE_PARAMETER_LIST_VARIABLE_NAME = ""typeParameterList""; -+ private static final String TEMPLATE_FROM_USAGE_METHOD_BODY = ""New Kotlin Method Body.kt""; -+ private static final Pattern COMPONENT_FUNCTION_PATTERN = Pattern.compile(""^component(\\d+)$""); -+ -+ /** -+ * Represents a single choice for a type (e.g. parameter type or return type). -+ */ -+ private static class TypeCandidate { -+ private final JetType type; -+ private final TypeParameterDescriptor[] typeParameters; -+ private String renderedType; -+ private String[] typeParameterNames; -+ -+ public TypeCandidate(@NotNull JetType type) { -+ this.type = type; -+ Set typeParametersInType = getTypeParametersInType(type); -+ typeParameters = typeParametersInType.toArray(new TypeParameterDescriptor[typeParametersInType.size()]); -+ renderedType = renderTypeShort(type, Collections.emptyMap()); -+ } -+ -+ public TypeCandidate(@NotNull JetType type, @NotNull JetScope scope) { -+ this.type = type; -+ typeParameters = getTypeParameterNamesNotInScope(getTypeParametersInType(type), scope); -+ } -+ -+ public void render(@NotNull Map typeParameterNameMap) { -+ renderedType = renderTypeShort(type, typeParameterNameMap); -+ typeParameterNames = new String[typeParameters.length]; -+ int i = 0; -+ for (TypeParameterDescriptor typeParameter : typeParameters) { -+ typeParameterNames[i] = typeParameterNameMap.get(typeParameter); -+ i++; -+ } -+ } -+ -+ @NotNull JetType getType() { -+ return type; -+ } -+ -+ @NotNull -+ public String getRenderedType() { -+ assert renderedType != null : ""call render() first""; -+ return renderedType; -+ } -+ -+ @NotNull -+ public String[] getTypeParameterNames() { -+ assert typeParameterNames != null : ""call render() first""; -+ return typeParameterNames; -+ } -+ -+ @NotNull -+ public TypeParameterDescriptor[] getTypeParameters() { -+ return typeParameters; -+ } -+ } -+ -+ /** -+ * Represents a concrete type or a set of types yet to be inferred from an expression. -+ */ -+ private static class TypeOrExpressionThereof { -+ private final JetExpression expressionOfType; -+ private final JetType type; -+ private final Variance variance; -+ private TypeCandidate[] typeCandidates; -+ private String[] cachedNameCandidatesFromExpression; -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType) { -+ this(expressionOfType, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType, Variance variance) { -+ this(expressionOfType, null, variance); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type) { -+ this(type, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type, Variance variance) { -+ this(null, type, variance); -+ } -+ -+ private TypeOrExpressionThereof(@Nullable JetExpression expressionOfType, @Nullable JetType type, Variance variance) { -+ this.expressionOfType = expressionOfType; -+ this.type = type; -+ this.variance = variance; -+ } -+ -+ public boolean isType() { -+ return this.type != null; -+ } -+ -+ @NotNull -+ public JetType getType() { -+ assert this.type != null; -+ return this.type; -+ } -+ -+ @NotNull -+ private List getPossibleTypes(BindingContext context) { -+ List types = new ArrayList(); -+ if (isType()) { -+ assert type != null : ""!isType() means type == null && expressionOfType != null""; -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ for (JetType type : guessTypeForExpression(expressionOfType, context)) { -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } -+ } -+ return types; -+ } -+ -+ public void computeTypeCandidates(@NotNull BindingContext context) { -+ Collection types = getPossibleTypes(context); -+ -+ typeCandidates = new TypeCandidate[types.size()]; -+ int i = 0; -+ for (JetType type : types) { -+ typeCandidates[i] = new TypeCandidate(type); -+ i++; -+ } -+ } -+ -+ public void computeTypeCandidates( -+ @NotNull BindingContext context, -+ @NotNull TypeSubstitution[] substitutions, -+ @NotNull JetScope scope -+ ) { -+ List types = getPossibleTypes(context); -+ Collections.reverse(types); // reverse and reverse back later, so that things added below are added at the front -+ -+ Set newTypes = new LinkedHashSet(types); -+ for (TypeSubstitution substitution : substitutions) { // each substitution can be applied or not, so we offer all options -+ List toAdd = new ArrayList(); -+ List toRemove = new ArrayList(); -+ for (JetType type : newTypes) { -+ toAdd.add(substituteType(type, substitution, variance)); -+ // substitution.byType are type arguments, but they cannot already occur in the type before substitution -+ if (containsType(type, substitution.getByType())) { -+ toRemove.add(type); -+ } -+ } -+ newTypes.addAll(toAdd); -+ newTypes.removeAll(toRemove); -+ } -+ -+ if (newTypes.isEmpty()) { -+ newTypes.add(KotlinBuiltIns.getInstance().getAnyType()); -+ } -+ -+ typeCandidates = new TypeCandidate[newTypes.size()]; -+ int i = typeCandidates.length - 1; // reverse order (see explanation above) -+ for (JetType type : newTypes) { -+ typeCandidates[i] = new TypeCandidate(type, scope); -+ i--; -+ } -+ } -+ -+ @NotNull -+ public TypeCandidate[] getTypeCandidates() { -+ assert typeCandidates != null : ""call computeTypeCandidates() first""; -+ return typeCandidates; -+ } -+ -+ public void renderTypeCandidates(@NotNull Map typeParameterNameMap) { -+ for (TypeCandidate candidate : typeCandidates) { -+ candidate.render(typeParameterNameMap); -+ } -+ } -+ -+ @NotNull -+ public String[] getPossibleNamesFromExpression() { -+ if (cachedNameCandidatesFromExpression != null) return cachedNameCandidatesFromExpression; -+ if (isType()) { -+ cachedNameCandidatesFromExpression = ArrayUtil.EMPTY_STRING_ARRAY; -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ JetNameValidator dummyValidator = new DummyJetNameValidator(expressionOfType.getProject()); -+ cachedNameCandidatesFromExpression = JetNameSuggester.suggestNamesForExpression(expressionOfType, dummyValidator); -+ } -+ return cachedNameCandidatesFromExpression; -+ } -+ } -+ -+ /** -+ * Encapsulates information about a method parameter that is going to be created. -+ */ -+ private static class Parameter { -+ private final String preferredName; -+ private final TypeOrExpressionThereof type; -+ -+ public Parameter(@Nullable(""no preferred name"") String preferredName, TypeOrExpressionThereof type) { -+ this.preferredName = preferredName; -+ this.type = type; -+ } -+ -+ public String getPreferredName() { -+ return preferredName; -+ } -+ -+ public TypeOrExpressionThereof getType() { -+ return type; -+ } -+ } -+ -+ /** -+ * Special Expression for parameter names based on its type. -+ */ -+ private static class ParameterNameExpression extends Expression { -+ private final String[] names; -+ private final Map parameterTypeToNamesMap; -+ -+ public ParameterNameExpression(@NotNull String[] names, @NotNull Map parameterTypeToNamesMap) { -+ for (String name : names) { -+ assert name != null && !name.isEmpty(); -+ } -+ this.names = names; -+ this.parameterTypeToNamesMap = parameterTypeToNamesMap; -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ LookupElement[] lookupItems = calculateLookupItems(context); -+ if (lookupItems.length == 0) return new TextResult(""""); -+ -+ return new TextResult(lookupItems[0].getLookupString()); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ Set names = new LinkedHashSet(); -+ Collections.addAll(names, this.names); -+ -+ // find the parameter list -+ Project project = context.getProject(); -+ int offset = context.getStartOffset(); -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ Editor editor = context.getEditor(); -+ assert editor != null; -+ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); -+ assert file != null && file instanceof JetFile; -+ PsiElement elementAt = file.findElementAt(offset); -+ JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); -+ if (func == null) return new LookupElement[0]; -+ JetParameterList parameterList = func.getValueParameterList(); -+ assert parameterList != null; -+ -+ // add names based on selected type -+ JetParameter parameter = PsiTreeUtil.getParentOfType(elementAt, JetParameter.class); -+ if (parameter != null) { -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ String[] suggestedNamesBasedOnType = parameterTypeToNamesMap.get(parameterTypeRef.getText()); -+ if (suggestedNamesBasedOnType != null) { -+ Collections.addAll(names, suggestedNamesBasedOnType); -+ } -+ } -+ } -+ -+ // remember other parameter names for later use -+ Set parameterNames = new HashSet(); -+ for (JetParameter jetParameter : parameterList.getParameters()) { -+ if (jetParameter == parameter || jetParameter.getName() == null) continue; -+ parameterNames.add(jetParameter.getName()); -+ } -+ -+ // add fallback parameter name -+ if (names.isEmpty()) { -+ names.add(""arg""); -+ } -+ -+ // ensure there are no conflicts -+ List lookupElements = new ArrayList(); -+ for (String name : names) { -+ name = getNextAvailableName(name, parameterNames); -+ lookupElements.add(LookupElementBuilder.create(name)); -+ } -+ -+ // create and return -+ return lookupElements.toArray(new LookupElement[lookupElements.size()]); -+ } -+ } -+ -+ /** -+ * An Expression for type references. -+ */ -+ private static class TypeExpression extends Expression { -+ private final TypeOrExpressionThereof type; -+ private @NotNull LookupElement[] cachedLookupElements; -+ -+ public TypeExpression(@NotNull TypeOrExpressionThereof type) { -+ this.type = type; -+ TypeCandidate[] candidates = type.getTypeCandidates(); -+ cachedLookupElements = new LookupElement[candidates.length]; -+ for (int i = 0; i < candidates.length; i++) { -+ cachedLookupElements[i] = LookupElementBuilder.create(candidates[i], candidates[i].getRenderedType()); -+ } -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ LookupElement[] lookupItems = calculateLookupItems(context); -+ if (lookupItems.length == 0) return new TextResult(""""); -+ -+ return new TextResult(lookupItems[0].getLookupString()); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ return cachedLookupElements; -+ } -+ -+ @NotNull -+ public TypeOrExpressionThereof getType() { -+ return type; -+ } -+ -+ @Nullable(""can't be found"") -+ public JetType getTypeFromSelection(@NotNull String selection) { -+ TypeCandidate[] options = type.getTypeCandidates(); -+ for (TypeCandidate option : options) { -+ if (option.getRenderedType().equals(selection)) { -+ return option.getType(); -+ } -+ } -+ return null; -+ } -+ } -+ -+ /** -+ * A sort-of dummy Expression for parameter lists, to allow us to update the parameter list as the user makes selections. -+ */ -+ private static class TypeParameterListExpression extends Expression { -+ private final String[] typeParameterNamesFromReceiverType; -+ private final Map parameterTypeToTypeParameterNamesMap; -+ -+ public TypeParameterListExpression( -+ @NotNull String[] typeParameterNamesFromReceiverType, -+ @NotNull Map typeParametersMap -+ ) { -+ this.typeParameterNamesFromReceiverType = typeParameterNamesFromReceiverType; -+ this.parameterTypeToTypeParameterNamesMap = typeParametersMap; -+ } -+ -+ @NotNull -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ Project project = context.getProject(); -+ int offset = context.getStartOffset(); -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ Editor editor = context.getEditor(); -+ assert editor != null; -+ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); -+ assert file != null && file instanceof JetFile; -+ PsiElement elementAt = file.findElementAt(offset); -+ JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); -+ if (func == null) { -+ return new TextResult(""""); -+ } -+ List parameters = func.getValueParameters(); -+ -+ Set typeParameterNames = new LinkedHashSet(); -+ Collections.addAll(typeParameterNames, typeParameterNamesFromReceiverType); -+ for (JetParameter parameter : parameters) { -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ String[] typeParameterNamesFromParameter = parameterTypeToTypeParameterNamesMap.get(parameterTypeRef.getText()); -+ if (typeParameterNamesFromParameter != null) { -+ Collections.addAll(typeParameterNames, typeParameterNamesFromParameter); -+ } -+ } -+ } -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ if (returnTypeRef != null) { -+ String[] typeParameterNamesFromReturnType = parameterTypeToTypeParameterNamesMap.get(returnTypeRef.getText()); -+ if (typeParameterNamesFromReturnType != null) { -+ Collections.addAll(typeParameterNames, typeParameterNamesFromReturnType); -+ } -+ } -+ -+ return typeParameterNames.isEmpty() -+ ? new TextResult("""") -+ : new TextResult("" <"" + StringUtil.join(typeParameterNames, "", "") + "">""); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ return new LookupElement[0]; // do not offer the user any choices -+ } -+ } -+ -+ /** -+ * A JetNameValidator that always succeeds. -+ */ -+ private static class DummyJetNameValidator implements JetNameValidator { -+ private final Project project; -+ -+ public DummyJetNameValidator(Project project) { -+ this.project = project; -+ } -+ -+ @Nullable -+ @Override -+ public String validateName(String name) { -+ return name; -+ } -+ -+ @Override -+ public Project getProject() { -+ return project; -+ } -+ } -+ -+ /** -+ * Encapsulates a single type substitution of a JetType by another JetType. -+ */ -+ private static class TypeSubstitution {","We already have class called `TypeSubstitution` in Kotlin codebase, so, this name is too confusing. -",Why is this needed? Looks like a du -95,"@@ -0,0 +1,1391 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.codeInsight.lookup.LookupElement; -+import com.intellij.codeInsight.lookup.LookupElementBuilder; -+import com.intellij.codeInsight.template.*; -+import com.intellij.codeInsight.template.impl.TemplateImpl; -+import com.intellij.codeInsight.template.impl.Variable; -+import com.intellij.ide.fileTemplates.FileTemplate; -+import com.intellij.ide.fileTemplates.FileTemplateManager; -+import com.intellij.ide.util.PsiElementListCellRenderer; -+import com.intellij.openapi.application.ApplicationManager; -+import com.intellij.openapi.command.CommandProcessor; -+import com.intellij.openapi.editor.CaretModel; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.fileEditor.FileEditorManager; -+import com.intellij.openapi.progress.ProcessCanceledException; -+import com.intellij.openapi.project.Project; -+import com.intellij.openapi.ui.popup.PopupChooserBuilder; -+import com.intellij.openapi.util.TextRange; -+import com.intellij.openapi.util.text.StringUtil; -+import com.intellij.openapi.vfs.VirtualFile; -+import com.intellij.psi.PsiDocumentManager; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.PsiReference; -+import com.intellij.psi.search.SearchScope; -+import com.intellij.psi.util.PsiTreeUtil; -+import com.intellij.refactoring.psi.SearchUtils; -+import com.intellij.ui.components.JBList; -+import com.intellij.util.ArrayUtil; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NonNls; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.descriptors.*; -+import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1; -+import org.jetbrains.jet.lang.diagnostics.Errors; -+import org.jetbrains.jet.lang.psi.*; -+import org.jetbrains.jet.lang.resolve.BindingContext; -+import org.jetbrains.jet.lang.resolve.BindingContextUtils; -+import org.jetbrains.jet.lang.resolve.DescriptorUtils; -+import org.jetbrains.jet.lang.resolve.name.Name; -+import org.jetbrains.jet.lang.resolve.scopes.JetScope; -+import org.jetbrains.jet.lang.types.*; -+import org.jetbrains.jet.lang.types.checker.JetTypeChecker; -+import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; -+import org.jetbrains.jet.plugin.JetBundle; -+import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening; -+import org.jetbrains.jet.plugin.presentation.JetLightClassListCellRenderer; -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; -+import org.jetbrains.jet.plugin.refactoring.JetNameSuggester; -+import org.jetbrains.jet.plugin.refactoring.JetNameValidator; -+import org.jetbrains.jet.plugin.references.JetSimpleNameReference; -+import org.jetbrains.jet.renderer.DescriptorRenderer; -+ -+import javax.swing.*; -+import java.util.*; -+import java.util.regex.Matcher; -+import java.util.regex.Pattern; -+ -+public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { -+ private static final String TYPE_PARAMETER_LIST_VARIABLE_NAME = ""typeParameterList""; -+ private static final String TEMPLATE_FROM_USAGE_METHOD_BODY = ""New Kotlin Method Body.kt""; -+ private static final Pattern COMPONENT_FUNCTION_PATTERN = Pattern.compile(""^component(\\d+)$""); -+ -+ /** -+ * Represents a single choice for a type (e.g. parameter type or return type). -+ */ -+ private static class TypeCandidate { -+ private final JetType type; -+ private final TypeParameterDescriptor[] typeParameters; -+ private String renderedType; -+ private String[] typeParameterNames; -+ -+ public TypeCandidate(@NotNull JetType type) { -+ this.type = type; -+ Set typeParametersInType = getTypeParametersInType(type); -+ typeParameters = typeParametersInType.toArray(new TypeParameterDescriptor[typeParametersInType.size()]); -+ renderedType = renderTypeShort(type, Collections.emptyMap()); -+ } -+ -+ public TypeCandidate(@NotNull JetType type, @NotNull JetScope scope) { -+ this.type = type; -+ typeParameters = getTypeParameterNamesNotInScope(getTypeParametersInType(type), scope); -+ } -+ -+ public void render(@NotNull Map typeParameterNameMap) { -+ renderedType = renderTypeShort(type, typeParameterNameMap); -+ typeParameterNames = new String[typeParameters.length]; -+ int i = 0; -+ for (TypeParameterDescriptor typeParameter : typeParameters) { -+ typeParameterNames[i] = typeParameterNameMap.get(typeParameter); -+ i++; -+ } -+ } -+ -+ @NotNull JetType getType() { -+ return type; -+ } -+ -+ @NotNull -+ public String getRenderedType() { -+ assert renderedType != null : ""call render() first""; -+ return renderedType; -+ } -+ -+ @NotNull -+ public String[] getTypeParameterNames() { -+ assert typeParameterNames != null : ""call render() first""; -+ return typeParameterNames; -+ } -+ -+ @NotNull -+ public TypeParameterDescriptor[] getTypeParameters() { -+ return typeParameters; -+ } -+ } -+ -+ /** -+ * Represents a concrete type or a set of types yet to be inferred from an expression. -+ */ -+ private static class TypeOrExpressionThereof { -+ private final JetExpression expressionOfType; -+ private final JetType type; -+ private final Variance variance; -+ private TypeCandidate[] typeCandidates; -+ private String[] cachedNameCandidatesFromExpression; -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType) { -+ this(expressionOfType, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType, Variance variance) { -+ this(expressionOfType, null, variance); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type) { -+ this(type, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type, Variance variance) { -+ this(null, type, variance); -+ } -+ -+ private TypeOrExpressionThereof(@Nullable JetExpression expressionOfType, @Nullable JetType type, Variance variance) { -+ this.expressionOfType = expressionOfType; -+ this.type = type; -+ this.variance = variance; -+ } -+ -+ public boolean isType() { -+ return this.type != null; -+ } -+ -+ @NotNull -+ public JetType getType() { -+ assert this.type != null; -+ return this.type; -+ } -+ -+ @NotNull -+ private List getPossibleTypes(BindingContext context) { -+ List types = new ArrayList(); -+ if (isType()) { -+ assert type != null : ""!isType() means type == null && expressionOfType != null""; -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ for (JetType type : guessTypeForExpression(expressionOfType, context)) { -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } -+ } -+ return types; -+ } -+ -+ public void computeTypeCandidates(@NotNull BindingContext context) { -+ Collection types = getPossibleTypes(context); -+ -+ typeCandidates = new TypeCandidate[types.size()]; -+ int i = 0; -+ for (JetType type : types) { -+ typeCandidates[i] = new TypeCandidate(type); -+ i++; -+ } -+ } -+ -+ public void computeTypeCandidates( -+ @NotNull BindingContext context, -+ @NotNull TypeSubstitution[] substitutions, -+ @NotNull JetScope scope -+ ) { -+ List types = getPossibleTypes(context); -+ Collections.reverse(types); // reverse and reverse back later, so that things added below are added at the front -+ -+ Set newTypes = new LinkedHashSet(types); -+ for (TypeSubstitution substitution : substitutions) { // each substitution can be applied or not, so we offer all options -+ List toAdd = new ArrayList(); -+ List toRemove = new ArrayList(); -+ for (JetType type : newTypes) { -+ toAdd.add(substituteType(type, substitution, variance)); -+ // substitution.byType are type arguments, but they cannot already occur in the type before substitution -+ if (containsType(type, substitution.getByType())) { -+ toRemove.add(type); -+ } -+ } -+ newTypes.addAll(toAdd); -+ newTypes.removeAll(toRemove); -+ } -+ -+ if (newTypes.isEmpty()) { -+ newTypes.add(KotlinBuiltIns.getInstance().getAnyType()); -+ } -+ -+ typeCandidates = new TypeCandidate[newTypes.size()]; -+ int i = typeCandidates.length - 1; // reverse order (see explanation above) -+ for (JetType type : newTypes) { -+ typeCandidates[i] = new TypeCandidate(type, scope); -+ i--; -+ } -+ } -+ -+ @NotNull -+ public TypeCandidate[] getTypeCandidates() { -+ assert typeCandidates != null : ""call computeTypeCandidates() first""; -+ return typeCandidates; -+ } -+ -+ public void renderTypeCandidates(@NotNull Map typeParameterNameMap) { -+ for (TypeCandidate candidate : typeCandidates) { -+ candidate.render(typeParameterNameMap); -+ } -+ } -+ -+ @NotNull -+ public String[] getPossibleNamesFromExpression() { -+ if (cachedNameCandidatesFromExpression != null) return cachedNameCandidatesFromExpression; -+ if (isType()) { -+ cachedNameCandidatesFromExpression = ArrayUtil.EMPTY_STRING_ARRAY; -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ JetNameValidator dummyValidator = new DummyJetNameValidator(expressionOfType.getProject()); -+ cachedNameCandidatesFromExpression = JetNameSuggester.suggestNamesForExpression(expressionOfType, dummyValidator); -+ } -+ return cachedNameCandidatesFromExpression; -+ } -+ } -+ -+ /** -+ * Encapsulates information about a method parameter that is going to be created. -+ */ -+ private static class Parameter { -+ private final String preferredName; -+ private final TypeOrExpressionThereof type; -+ -+ public Parameter(@Nullable(""no preferred name"") String preferredName, TypeOrExpressionThereof type) { -+ this.preferredName = preferredName; -+ this.type = type; -+ } -+ -+ public String getPreferredName() { -+ return preferredName; -+ } -+ -+ public TypeOrExpressionThereof getType() { -+ return type; -+ } -+ } -+ -+ /** -+ * Special Expression for parameter names based on its type. -+ */ -+ private static class ParameterNameExpression extends Expression { -+ private final String[] names; -+ private final Map parameterTypeToNamesMap; -+ -+ public ParameterNameExpression(@NotNull String[] names, @NotNull Map parameterTypeToNamesMap) { -+ for (String name : names) { -+ assert name != null && !name.isEmpty(); -+ } -+ this.names = names; -+ this.parameterTypeToNamesMap = parameterTypeToNamesMap; -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ LookupElement[] lookupItems = calculateLookupItems(context); -+ if (lookupItems.length == 0) return new TextResult(""""); -+ -+ return new TextResult(lookupItems[0].getLookupString()); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ Set names = new LinkedHashSet(); -+ Collections.addAll(names, this.names); -+ -+ // find the parameter list -+ Project project = context.getProject(); -+ int offset = context.getStartOffset(); -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ Editor editor = context.getEditor(); -+ assert editor != null; -+ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); -+ assert file != null && file instanceof JetFile; -+ PsiElement elementAt = file.findElementAt(offset); -+ JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); -+ if (func == null) return new LookupElement[0]; -+ JetParameterList parameterList = func.getValueParameterList(); -+ assert parameterList != null; -+ -+ // add names based on selected type -+ JetParameter parameter = PsiTreeUtil.getParentOfType(elementAt, JetParameter.class); -+ if (parameter != null) { -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ String[] suggestedNamesBasedOnType = parameterTypeToNamesMap.get(parameterTypeRef.getText()); -+ if (suggestedNamesBasedOnType != null) { -+ Collections.addAll(names, suggestedNamesBasedOnType); -+ } -+ } -+ } -+ -+ // remember other parameter names for later use -+ Set parameterNames = new HashSet(); -+ for (JetParameter jetParameter : parameterList.getParameters()) { -+ if (jetParameter == parameter || jetParameter.getName() == null) continue; -+ parameterNames.add(jetParameter.getName()); -+ } -+ -+ // add fallback parameter name -+ if (names.isEmpty()) { -+ names.add(""arg""); -+ } -+ -+ // ensure there are no conflicts -+ List lookupElements = new ArrayList(); -+ for (String name : names) { -+ name = getNextAvailableName(name, parameterNames); -+ lookupElements.add(LookupElementBuilder.create(name)); -+ } -+ -+ // create and return -+ return lookupElements.toArray(new LookupElement[lookupElements.size()]); -+ } -+ } -+ -+ /** -+ * An Expression for type references. -+ */ -+ private static class TypeExpression extends Expression { -+ private final TypeOrExpressionThereof type; -+ private @NotNull LookupElement[] cachedLookupElements; -+ -+ public TypeExpression(@NotNull TypeOrExpressionThereof type) { -+ this.type = type; -+ TypeCandidate[] candidates = type.getTypeCandidates(); -+ cachedLookupElements = new LookupElement[candidates.length]; -+ for (int i = 0; i < candidates.length; i++) { -+ cachedLookupElements[i] = LookupElementBuilder.create(candidates[i], candidates[i].getRenderedType()); -+ } -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ LookupElement[] lookupItems = calculateLookupItems(context); -+ if (lookupItems.length == 0) return new TextResult(""""); -+ -+ return new TextResult(lookupItems[0].getLookupString()); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ return cachedLookupElements; -+ } -+ -+ @NotNull -+ public TypeOrExpressionThereof getType() { -+ return type; -+ } -+ -+ @Nullable(""can't be found"") -+ public JetType getTypeFromSelection(@NotNull String selection) { -+ TypeCandidate[] options = type.getTypeCandidates(); -+ for (TypeCandidate option : options) { -+ if (option.getRenderedType().equals(selection)) { -+ return option.getType(); -+ } -+ } -+ return null; -+ } -+ } -+ -+ /** -+ * A sort-of dummy Expression for parameter lists, to allow us to update the parameter list as the user makes selections. -+ */ -+ private static class TypeParameterListExpression extends Expression { -+ private final String[] typeParameterNamesFromReceiverType; -+ private final Map parameterTypeToTypeParameterNamesMap; -+ -+ public TypeParameterListExpression( -+ @NotNull String[] typeParameterNamesFromReceiverType, -+ @NotNull Map typeParametersMap -+ ) { -+ this.typeParameterNamesFromReceiverType = typeParameterNamesFromReceiverType; -+ this.parameterTypeToTypeParameterNamesMap = typeParametersMap; -+ } -+ -+ @NotNull -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ Project project = context.getProject(); -+ int offset = context.getStartOffset(); -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ Editor editor = context.getEditor(); -+ assert editor != null; -+ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); -+ assert file != null && file instanceof JetFile; -+ PsiElement elementAt = file.findElementAt(offset); -+ JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); -+ if (func == null) { -+ return new TextResult(""""); -+ } -+ List parameters = func.getValueParameters(); -+ -+ Set typeParameterNames = new LinkedHashSet(); -+ Collections.addAll(typeParameterNames, typeParameterNamesFromReceiverType); -+ for (JetParameter parameter : parameters) { -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ String[] typeParameterNamesFromParameter = parameterTypeToTypeParameterNamesMap.get(parameterTypeRef.getText()); -+ if (typeParameterNamesFromParameter != null) { -+ Collections.addAll(typeParameterNames, typeParameterNamesFromParameter); -+ } -+ } -+ } -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ if (returnTypeRef != null) { -+ String[] typeParameterNamesFromReturnType = parameterTypeToTypeParameterNamesMap.get(returnTypeRef.getText()); -+ if (typeParameterNamesFromReturnType != null) { -+ Collections.addAll(typeParameterNames, typeParameterNamesFromReturnType); -+ } -+ } -+ -+ return typeParameterNames.isEmpty() -+ ? new TextResult("""") -+ : new TextResult("" <"" + StringUtil.join(typeParameterNames, "", "") + "">""); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ return new LookupElement[0]; // do not offer the user any choices -+ } -+ } -+ -+ /** -+ * A JetNameValidator that always succeeds. -+ */ -+ private static class DummyJetNameValidator implements JetNameValidator { -+ private final Project project; -+ -+ public DummyJetNameValidator(Project project) { -+ this.project = project; -+ } -+ -+ @Nullable -+ @Override -+ public String validateName(String name) { -+ return name; -+ } -+ -+ @Override -+ public Project getProject() { -+ return project; -+ } -+ } -+ -+ /** -+ * Encapsulates a single type substitution of a JetType by another JetType. -+ */ -+ private static class TypeSubstitution { -+ private final JetType forType; -+ private final JetType byType; -+ -+ private TypeSubstitution(JetType forType, JetType byType) { -+ this.forType = forType; -+ this.byType = byType; -+ } -+ -+ private JetType getForType() { -+ return forType; -+ } -+ -+ private JetType getByType() { -+ return byType; -+ } -+ } -+ -+ private final String methodName; -+ private final TypeOrExpressionThereof ownerType; -+ private final TypeOrExpressionThereof returnType; -+ private final List parameters; -+ -+ private boolean isUnit; -+ private boolean isExtension; -+ private JetFile currentFile; -+ private JetFile containingFile; -+ private Editor currentFileEditor; -+ private Editor containingFileEditor; -+ private BindingContext currentFileContext; -+ private JetClass ownerClass; -+ private ClassDescriptor ownerClassDescriptor; -+ private TypeCandidate selectedReceiverType; -+ private Map typeParameterNameMap; -+ -+ public CreateMethodFromUsageFix(@NotNull PsiElement element, @NotNull TypeOrExpressionThereof ownerType, @NotNull String methodName, -+ @NotNull TypeOrExpressionThereof returnType, @NotNull List parameters) { -+ super(element); -+ this.methodName = methodName; -+ this.ownerType = ownerType; -+ this.returnType = returnType; -+ this.parameters = parameters; -+ } -+ -+ @NotNull -+ @Override -+ public String getText() { -+ return JetBundle.message(""create.method.from.usage"", methodName); -+ } -+ -+ @Override -+ public void invoke(@NotNull final Project project, Editor editor, PsiFile file) throws IncorrectOperationException { -+ assert file != null && file instanceof JetFile; -+ currentFile = (JetFile) file; -+ currentFileEditor = editor; -+ currentFileContext = AnalyzerFacadeWithCache.analyzeFileWithCache(currentFile).getBindingContext(); -+ -+ ownerType.computeTypeCandidates(currentFileContext); -+ TypeCandidate[] ownerTypeCandidates = ownerType.getTypeCandidates(); -+ assert ownerTypeCandidates.length > 0; -+ if (ownerTypeCandidates.length == 1 || ApplicationManager.getApplication().isUnitTestMode()) { -+ selectedReceiverType = ownerTypeCandidates[0]; -+ doInvoke(project); -+ } else { -+ // class selection -+ List options = new ArrayList(); -+ final Map optionToTypeMap = new HashMap(); -+ for (TypeCandidate ownerTypeCandidate : ownerTypeCandidates) { -+ ClassifierDescriptor possibleClassDescriptor = ownerTypeCandidate.getType().getConstructor().getDeclarationDescriptor(); -+ if (possibleClassDescriptor != null) { -+ String className = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(possibleClassDescriptor.getDefaultType()); -+ DeclarationDescriptor namespaceDescriptor = possibleClassDescriptor.getContainingDeclaration(); -+ String namespace = renderDescriptor(namespaceDescriptor, true); -+ String option = className + "" ("" + namespace + "")""; -+ options.add(option); -+ optionToTypeMap.put(option, ownerTypeCandidate); -+ } -+ } -+","Make popup look the same as for Java, see screenshot: -![Screen Shot 2013-04-24 at 18 17 37](https://f.cloud.github.com/assets/145855/430367/d8c2a7be-ae66-11e2-8886-ee07159d98d6.png) -",Why is this needed? Looks like a du -96,"@@ -0,0 +1,1391 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.codeInsight.lookup.LookupElement; -+import com.intellij.codeInsight.lookup.LookupElementBuilder; -+import com.intellij.codeInsight.template.*; -+import com.intellij.codeInsight.template.impl.TemplateImpl; -+import com.intellij.codeInsight.template.impl.Variable; -+import com.intellij.ide.fileTemplates.FileTemplate; -+import com.intellij.ide.fileTemplates.FileTemplateManager; -+import com.intellij.ide.util.PsiElementListCellRenderer; -+import com.intellij.openapi.application.ApplicationManager; -+import com.intellij.openapi.command.CommandProcessor; -+import com.intellij.openapi.editor.CaretModel; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.fileEditor.FileEditorManager; -+import com.intellij.openapi.progress.ProcessCanceledException; -+import com.intellij.openapi.project.Project; -+import com.intellij.openapi.ui.popup.PopupChooserBuilder; -+import com.intellij.openapi.util.TextRange; -+import com.intellij.openapi.util.text.StringUtil; -+import com.intellij.openapi.vfs.VirtualFile; -+import com.intellij.psi.PsiDocumentManager; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.PsiReference; -+import com.intellij.psi.search.SearchScope; -+import com.intellij.psi.util.PsiTreeUtil; -+import com.intellij.refactoring.psi.SearchUtils; -+import com.intellij.ui.components.JBList; -+import com.intellij.util.ArrayUtil; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NonNls; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.descriptors.*; -+import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1; -+import org.jetbrains.jet.lang.diagnostics.Errors; -+import org.jetbrains.jet.lang.psi.*; -+import org.jetbrains.jet.lang.resolve.BindingContext; -+import org.jetbrains.jet.lang.resolve.BindingContextUtils; -+import org.jetbrains.jet.lang.resolve.DescriptorUtils; -+import org.jetbrains.jet.lang.resolve.name.Name; -+import org.jetbrains.jet.lang.resolve.scopes.JetScope; -+import org.jetbrains.jet.lang.types.*; -+import org.jetbrains.jet.lang.types.checker.JetTypeChecker; -+import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; -+import org.jetbrains.jet.plugin.JetBundle; -+import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening; -+import org.jetbrains.jet.plugin.presentation.JetLightClassListCellRenderer; -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; -+import org.jetbrains.jet.plugin.refactoring.JetNameSuggester; -+import org.jetbrains.jet.plugin.refactoring.JetNameValidator; -+import org.jetbrains.jet.plugin.references.JetSimpleNameReference; -+import org.jetbrains.jet.renderer.DescriptorRenderer; -+ -+import javax.swing.*; -+import java.util.*; -+import java.util.regex.Matcher; -+import java.util.regex.Pattern; -+ -+public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { -+ private static final String TYPE_PARAMETER_LIST_VARIABLE_NAME = ""typeParameterList""; -+ private static final String TEMPLATE_FROM_USAGE_METHOD_BODY = ""New Kotlin Method Body.kt""; -+ private static final Pattern COMPONENT_FUNCTION_PATTERN = Pattern.compile(""^component(\\d+)$""); -+ -+ /** -+ * Represents a single choice for a type (e.g. parameter type or return type). -+ */ -+ private static class TypeCandidate { -+ private final JetType type; -+ private final TypeParameterDescriptor[] typeParameters; -+ private String renderedType; -+ private String[] typeParameterNames; -+ -+ public TypeCandidate(@NotNull JetType type) { -+ this.type = type; -+ Set typeParametersInType = getTypeParametersInType(type); -+ typeParameters = typeParametersInType.toArray(new TypeParameterDescriptor[typeParametersInType.size()]); -+ renderedType = renderTypeShort(type, Collections.emptyMap()); -+ } -+ -+ public TypeCandidate(@NotNull JetType type, @NotNull JetScope scope) { -+ this.type = type; -+ typeParameters = getTypeParameterNamesNotInScope(getTypeParametersInType(type), scope); -+ } -+ -+ public void render(@NotNull Map typeParameterNameMap) { -+ renderedType = renderTypeShort(type, typeParameterNameMap); -+ typeParameterNames = new String[typeParameters.length]; -+ int i = 0; -+ for (TypeParameterDescriptor typeParameter : typeParameters) { -+ typeParameterNames[i] = typeParameterNameMap.get(typeParameter); -+ i++; -+ } -+ } -+ -+ @NotNull JetType getType() { -+ return type; -+ } -+ -+ @NotNull -+ public String getRenderedType() { -+ assert renderedType != null : ""call render() first""; -+ return renderedType; -+ } -+ -+ @NotNull -+ public String[] getTypeParameterNames() { -+ assert typeParameterNames != null : ""call render() first""; -+ return typeParameterNames; -+ } -+ -+ @NotNull -+ public TypeParameterDescriptor[] getTypeParameters() { -+ return typeParameters; -+ } -+ } -+ -+ /** -+ * Represents a concrete type or a set of types yet to be inferred from an expression. -+ */ -+ private static class TypeOrExpressionThereof { -+ private final JetExpression expressionOfType; -+ private final JetType type; -+ private final Variance variance; -+ private TypeCandidate[] typeCandidates; -+ private String[] cachedNameCandidatesFromExpression; -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType) { -+ this(expressionOfType, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType, Variance variance) { -+ this(expressionOfType, null, variance); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type) { -+ this(type, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type, Variance variance) { -+ this(null, type, variance); -+ } -+ -+ private TypeOrExpressionThereof(@Nullable JetExpression expressionOfType, @Nullable JetType type, Variance variance) { -+ this.expressionOfType = expressionOfType; -+ this.type = type; -+ this.variance = variance; -+ } -+ -+ public boolean isType() { -+ return this.type != null; -+ } -+ -+ @NotNull -+ public JetType getType() { -+ assert this.type != null; -+ return this.type; -+ } -+ -+ @NotNull -+ private List getPossibleTypes(BindingContext context) { -+ List types = new ArrayList(); -+ if (isType()) { -+ assert type != null : ""!isType() means type == null && expressionOfType != null""; -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ for (JetType type : guessTypeForExpression(expressionOfType, context)) { -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } -+ } -+ return types; -+ } -+ -+ public void computeTypeCandidates(@NotNull BindingContext context) { -+ Collection types = getPossibleTypes(context); -+ -+ typeCandidates = new TypeCandidate[types.size()]; -+ int i = 0; -+ for (JetType type : types) { -+ typeCandidates[i] = new TypeCandidate(type); -+ i++; -+ } -+ } -+ -+ public void computeTypeCandidates( -+ @NotNull BindingContext context, -+ @NotNull TypeSubstitution[] substitutions, -+ @NotNull JetScope scope -+ ) { -+ List types = getPossibleTypes(context); -+ Collections.reverse(types); // reverse and reverse back later, so that things added below are added at the front -+ -+ Set newTypes = new LinkedHashSet(types); -+ for (TypeSubstitution substitution : substitutions) { // each substitution can be applied or not, so we offer all options -+ List toAdd = new ArrayList(); -+ List toRemove = new ArrayList(); -+ for (JetType type : newTypes) { -+ toAdd.add(substituteType(type, substitution, variance)); -+ // substitution.byType are type arguments, but they cannot already occur in the type before substitution -+ if (containsType(type, substitution.getByType())) { -+ toRemove.add(type); -+ } -+ } -+ newTypes.addAll(toAdd); -+ newTypes.removeAll(toRemove); -+ } -+ -+ if (newTypes.isEmpty()) { -+ newTypes.add(KotlinBuiltIns.getInstance().getAnyType()); -+ } -+ -+ typeCandidates = new TypeCandidate[newTypes.size()]; -+ int i = typeCandidates.length - 1; // reverse order (see explanation above) -+ for (JetType type : newTypes) { -+ typeCandidates[i] = new TypeCandidate(type, scope); -+ i--; -+ } -+ } -+ -+ @NotNull -+ public TypeCandidate[] getTypeCandidates() { -+ assert typeCandidates != null : ""call computeTypeCandidates() first""; -+ return typeCandidates; -+ } -+ -+ public void renderTypeCandidates(@NotNull Map typeParameterNameMap) { -+ for (TypeCandidate candidate : typeCandidates) { -+ candidate.render(typeParameterNameMap); -+ } -+ } -+ -+ @NotNull -+ public String[] getPossibleNamesFromExpression() { -+ if (cachedNameCandidatesFromExpression != null) return cachedNameCandidatesFromExpression; -+ if (isType()) { -+ cachedNameCandidatesFromExpression = ArrayUtil.EMPTY_STRING_ARRAY; -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ JetNameValidator dummyValidator = new DummyJetNameValidator(expressionOfType.getProject()); -+ cachedNameCandidatesFromExpression = JetNameSuggester.suggestNamesForExpression(expressionOfType, dummyValidator); -+ } -+ return cachedNameCandidatesFromExpression; -+ } -+ } -+ -+ /** -+ * Encapsulates information about a method parameter that is going to be created. -+ */ -+ private static class Parameter { -+ private final String preferredName; -+ private final TypeOrExpressionThereof type; -+ -+ public Parameter(@Nullable(""no preferred name"") String preferredName, TypeOrExpressionThereof type) { -+ this.preferredName = preferredName; -+ this.type = type; -+ } -+ -+ public String getPreferredName() { -+ return preferredName; -+ } -+ -+ public TypeOrExpressionThereof getType() { -+ return type; -+ } -+ } -+ -+ /** -+ * Special Expression for parameter names based on its type. -+ */ -+ private static class ParameterNameExpression extends Expression { -+ private final String[] names; -+ private final Map parameterTypeToNamesMap; -+ -+ public ParameterNameExpression(@NotNull String[] names, @NotNull Map parameterTypeToNamesMap) { -+ for (String name : names) { -+ assert name != null && !name.isEmpty(); -+ } -+ this.names = names; -+ this.parameterTypeToNamesMap = parameterTypeToNamesMap; -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ LookupElement[] lookupItems = calculateLookupItems(context); -+ if (lookupItems.length == 0) return new TextResult(""""); -+ -+ return new TextResult(lookupItems[0].getLookupString()); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ Set names = new LinkedHashSet(); -+ Collections.addAll(names, this.names); -+ -+ // find the parameter list -+ Project project = context.getProject(); -+ int offset = context.getStartOffset(); -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ Editor editor = context.getEditor(); -+ assert editor != null; -+ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); -+ assert file != null && file instanceof JetFile; -+ PsiElement elementAt = file.findElementAt(offset); -+ JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); -+ if (func == null) return new LookupElement[0]; -+ JetParameterList parameterList = func.getValueParameterList(); -+ assert parameterList != null; -+ -+ // add names based on selected type -+ JetParameter parameter = PsiTreeUtil.getParentOfType(elementAt, JetParameter.class); -+ if (parameter != null) { -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ String[] suggestedNamesBasedOnType = parameterTypeToNamesMap.get(parameterTypeRef.getText()); -+ if (suggestedNamesBasedOnType != null) { -+ Collections.addAll(names, suggestedNamesBasedOnType); -+ } -+ } -+ } -+ -+ // remember other parameter names for later use -+ Set parameterNames = new HashSet(); -+ for (JetParameter jetParameter : parameterList.getParameters()) { -+ if (jetParameter == parameter || jetParameter.getName() == null) continue; -+ parameterNames.add(jetParameter.getName()); -+ } -+ -+ // add fallback parameter name -+ if (names.isEmpty()) { -+ names.add(""arg""); -+ } -+ -+ // ensure there are no conflicts -+ List lookupElements = new ArrayList(); -+ for (String name : names) { -+ name = getNextAvailableName(name, parameterNames); -+ lookupElements.add(LookupElementBuilder.create(name)); -+ } -+ -+ // create and return -+ return lookupElements.toArray(new LookupElement[lookupElements.size()]); -+ } -+ } -+ -+ /** -+ * An Expression for type references. -+ */ -+ private static class TypeExpression extends Expression { -+ private final TypeOrExpressionThereof type; -+ private @NotNull LookupElement[] cachedLookupElements; -+ -+ public TypeExpression(@NotNull TypeOrExpressionThereof type) { -+ this.type = type; -+ TypeCandidate[] candidates = type.getTypeCandidates(); -+ cachedLookupElements = new LookupElement[candidates.length]; -+ for (int i = 0; i < candidates.length; i++) { -+ cachedLookupElements[i] = LookupElementBuilder.create(candidates[i], candidates[i].getRenderedType()); -+ } -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ LookupElement[] lookupItems = calculateLookupItems(context); -+ if (lookupItems.length == 0) return new TextResult(""""); -+ -+ return new TextResult(lookupItems[0].getLookupString()); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ return cachedLookupElements; -+ } -+ -+ @NotNull -+ public TypeOrExpressionThereof getType() { -+ return type; -+ } -+ -+ @Nullable(""can't be found"") -+ public JetType getTypeFromSelection(@NotNull String selection) { -+ TypeCandidate[] options = type.getTypeCandidates(); -+ for (TypeCandidate option : options) { -+ if (option.getRenderedType().equals(selection)) { -+ return option.getType(); -+ } -+ } -+ return null; -+ } -+ } -+ -+ /** -+ * A sort-of dummy Expression for parameter lists, to allow us to update the parameter list as the user makes selections. -+ */ -+ private static class TypeParameterListExpression extends Expression { -+ private final String[] typeParameterNamesFromReceiverType; -+ private final Map parameterTypeToTypeParameterNamesMap; -+ -+ public TypeParameterListExpression( -+ @NotNull String[] typeParameterNamesFromReceiverType, -+ @NotNull Map typeParametersMap -+ ) { -+ this.typeParameterNamesFromReceiverType = typeParameterNamesFromReceiverType; -+ this.parameterTypeToTypeParameterNamesMap = typeParametersMap; -+ } -+ -+ @NotNull -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ Project project = context.getProject(); -+ int offset = context.getStartOffset(); -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ Editor editor = context.getEditor(); -+ assert editor != null; -+ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); -+ assert file != null && file instanceof JetFile; -+ PsiElement elementAt = file.findElementAt(offset); -+ JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); -+ if (func == null) { -+ return new TextResult(""""); -+ } -+ List parameters = func.getValueParameters(); -+ -+ Set typeParameterNames = new LinkedHashSet(); -+ Collections.addAll(typeParameterNames, typeParameterNamesFromReceiverType); -+ for (JetParameter parameter : parameters) { -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ String[] typeParameterNamesFromParameter = parameterTypeToTypeParameterNamesMap.get(parameterTypeRef.getText()); -+ if (typeParameterNamesFromParameter != null) { -+ Collections.addAll(typeParameterNames, typeParameterNamesFromParameter); -+ } -+ } -+ } -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ if (returnTypeRef != null) { -+ String[] typeParameterNamesFromReturnType = parameterTypeToTypeParameterNamesMap.get(returnTypeRef.getText()); -+ if (typeParameterNamesFromReturnType != null) { -+ Collections.addAll(typeParameterNames, typeParameterNamesFromReturnType); -+ } -+ } -+ -+ return typeParameterNames.isEmpty() -+ ? new TextResult("""") -+ : new TextResult("" <"" + StringUtil.join(typeParameterNames, "", "") + "">""); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ return new LookupElement[0]; // do not offer the user any choices -+ } -+ } -+ -+ /** -+ * A JetNameValidator that always succeeds. -+ */ -+ private static class DummyJetNameValidator implements JetNameValidator { -+ private final Project project; -+ -+ public DummyJetNameValidator(Project project) { -+ this.project = project; -+ } -+ -+ @Nullable -+ @Override -+ public String validateName(String name) { -+ return name; -+ } -+ -+ @Override -+ public Project getProject() { -+ return project; -+ } -+ } -+ -+ /** -+ * Encapsulates a single type substitution of a JetType by another JetType. -+ */ -+ private static class TypeSubstitution { -+ private final JetType forType; -+ private final JetType byType; -+ -+ private TypeSubstitution(JetType forType, JetType byType) { -+ this.forType = forType; -+ this.byType = byType; -+ } -+ -+ private JetType getForType() { -+ return forType; -+ } -+ -+ private JetType getByType() { -+ return byType; -+ } -+ } -+ -+ private final String methodName; -+ private final TypeOrExpressionThereof ownerType; -+ private final TypeOrExpressionThereof returnType; -+ private final List parameters; -+ -+ private boolean isUnit; -+ private boolean isExtension; -+ private JetFile currentFile; -+ private JetFile containingFile; -+ private Editor currentFileEditor; -+ private Editor containingFileEditor; -+ private BindingContext currentFileContext; -+ private JetClass ownerClass; -+ private ClassDescriptor ownerClassDescriptor; -+ private TypeCandidate selectedReceiverType; -+ private Map typeParameterNameMap; -+ -+ public CreateMethodFromUsageFix(@NotNull PsiElement element, @NotNull TypeOrExpressionThereof ownerType, @NotNull String methodName, -+ @NotNull TypeOrExpressionThereof returnType, @NotNull List parameters) { -+ super(element); -+ this.methodName = methodName; -+ this.ownerType = ownerType; -+ this.returnType = returnType; -+ this.parameters = parameters; -+ } -+ -+ @NotNull -+ @Override -+ public String getText() { -+ return JetBundle.message(""create.method.from.usage"", methodName); -+ } -+ -+ @Override -+ public void invoke(@NotNull final Project project, Editor editor, PsiFile file) throws IncorrectOperationException { -+ assert file != null && file instanceof JetFile; -+ currentFile = (JetFile) file; -+ currentFileEditor = editor; -+ currentFileContext = AnalyzerFacadeWithCache.analyzeFileWithCache(currentFile).getBindingContext(); -+ -+ ownerType.computeTypeCandidates(currentFileContext); -+ TypeCandidate[] ownerTypeCandidates = ownerType.getTypeCandidates(); -+ assert ownerTypeCandidates.length > 0; -+ if (ownerTypeCandidates.length == 1 || ApplicationManager.getApplication().isUnitTestMode()) { -+ selectedReceiverType = ownerTypeCandidates[0]; -+ doInvoke(project); -+ } else { -+ // class selection -+ List options = new ArrayList(); -+ final Map optionToTypeMap = new HashMap(); -+ for (TypeCandidate ownerTypeCandidate : ownerTypeCandidates) { -+ ClassifierDescriptor possibleClassDescriptor = ownerTypeCandidate.getType().getConstructor().getDeclarationDescriptor(); -+ if (possibleClassDescriptor != null) { -+ String className = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(possibleClassDescriptor.getDefaultType()); -+ DeclarationDescriptor namespaceDescriptor = possibleClassDescriptor.getContainingDeclaration(); -+ String namespace = renderDescriptor(namespaceDescriptor, true); -+ String option = className + "" ("" + namespace + "")""; -+ options.add(option); -+ optionToTypeMap.put(option, ownerTypeCandidate); -+ } -+ } -+ -+ final JList list = new JBList(options);","Why not use TypeCandidate instances as list elements? This would make it possible to avoid having String → TypeCandidate map. -",Why is this needed? Looks like a duplicate file. -97,"@@ -0,0 +1,1391 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.codeInsight.lookup.LookupElement; -+import com.intellij.codeInsight.lookup.LookupElementBuilder; -+import com.intellij.codeInsight.template.*; -+import com.intellij.codeInsight.template.impl.TemplateImpl; -+import com.intellij.codeInsight.template.impl.Variable; -+import com.intellij.ide.fileTemplates.FileTemplate; -+import com.intellij.ide.fileTemplates.FileTemplateManager; -+import com.intellij.ide.util.PsiElementListCellRenderer; -+import com.intellij.openapi.application.ApplicationManager; -+import com.intellij.openapi.command.CommandProcessor; -+import com.intellij.openapi.editor.CaretModel; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.fileEditor.FileEditorManager; -+import com.intellij.openapi.progress.ProcessCanceledException; -+import com.intellij.openapi.project.Project; -+import com.intellij.openapi.ui.popup.PopupChooserBuilder; -+import com.intellij.openapi.util.TextRange; -+import com.intellij.openapi.util.text.StringUtil; -+import com.intellij.openapi.vfs.VirtualFile; -+import com.intellij.psi.PsiDocumentManager; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.PsiReference; -+import com.intellij.psi.search.SearchScope; -+import com.intellij.psi.util.PsiTreeUtil; -+import com.intellij.refactoring.psi.SearchUtils; -+import com.intellij.ui.components.JBList; -+import com.intellij.util.ArrayUtil; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NonNls; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.descriptors.*; -+import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1; -+import org.jetbrains.jet.lang.diagnostics.Errors; -+import org.jetbrains.jet.lang.psi.*; -+import org.jetbrains.jet.lang.resolve.BindingContext; -+import org.jetbrains.jet.lang.resolve.BindingContextUtils; -+import org.jetbrains.jet.lang.resolve.DescriptorUtils; -+import org.jetbrains.jet.lang.resolve.name.Name; -+import org.jetbrains.jet.lang.resolve.scopes.JetScope; -+import org.jetbrains.jet.lang.types.*; -+import org.jetbrains.jet.lang.types.checker.JetTypeChecker; -+import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; -+import org.jetbrains.jet.plugin.JetBundle; -+import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening; -+import org.jetbrains.jet.plugin.presentation.JetLightClassListCellRenderer; -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; -+import org.jetbrains.jet.plugin.refactoring.JetNameSuggester; -+import org.jetbrains.jet.plugin.refactoring.JetNameValidator; -+import org.jetbrains.jet.plugin.references.JetSimpleNameReference; -+import org.jetbrains.jet.renderer.DescriptorRenderer; -+ -+import javax.swing.*; -+import java.util.*; -+import java.util.regex.Matcher; -+import java.util.regex.Pattern; -+ -+public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { -+ private static final String TYPE_PARAMETER_LIST_VARIABLE_NAME = ""typeParameterList""; -+ private static final String TEMPLATE_FROM_USAGE_METHOD_BODY = ""New Kotlin Method Body.kt""; -+ private static final Pattern COMPONENT_FUNCTION_PATTERN = Pattern.compile(""^component(\\d+)$""); -+ -+ /** -+ * Represents a single choice for a type (e.g. parameter type or return type). -+ */ -+ private static class TypeCandidate { -+ private final JetType type; -+ private final TypeParameterDescriptor[] typeParameters; -+ private String renderedType; -+ private String[] typeParameterNames; -+ -+ public TypeCandidate(@NotNull JetType type) { -+ this.type = type; -+ Set typeParametersInType = getTypeParametersInType(type); -+ typeParameters = typeParametersInType.toArray(new TypeParameterDescriptor[typeParametersInType.size()]); -+ renderedType = renderTypeShort(type, Collections.emptyMap()); -+ } -+ -+ public TypeCandidate(@NotNull JetType type, @NotNull JetScope scope) { -+ this.type = type; -+ typeParameters = getTypeParameterNamesNotInScope(getTypeParametersInType(type), scope); -+ } -+ -+ public void render(@NotNull Map typeParameterNameMap) { -+ renderedType = renderTypeShort(type, typeParameterNameMap); -+ typeParameterNames = new String[typeParameters.length]; -+ int i = 0; -+ for (TypeParameterDescriptor typeParameter : typeParameters) { -+ typeParameterNames[i] = typeParameterNameMap.get(typeParameter); -+ i++; -+ } -+ } -+ -+ @NotNull JetType getType() { -+ return type; -+ } -+ -+ @NotNull -+ public String getRenderedType() { -+ assert renderedType != null : ""call render() first""; -+ return renderedType; -+ } -+ -+ @NotNull -+ public String[] getTypeParameterNames() { -+ assert typeParameterNames != null : ""call render() first""; -+ return typeParameterNames; -+ } -+ -+ @NotNull -+ public TypeParameterDescriptor[] getTypeParameters() { -+ return typeParameters; -+ } -+ } -+ -+ /** -+ * Represents a concrete type or a set of types yet to be inferred from an expression. -+ */ -+ private static class TypeOrExpressionThereof { -+ private final JetExpression expressionOfType; -+ private final JetType type; -+ private final Variance variance; -+ private TypeCandidate[] typeCandidates; -+ private String[] cachedNameCandidatesFromExpression; -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType) { -+ this(expressionOfType, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType, Variance variance) { -+ this(expressionOfType, null, variance); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type) { -+ this(type, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type, Variance variance) { -+ this(null, type, variance); -+ } -+ -+ private TypeOrExpressionThereof(@Nullable JetExpression expressionOfType, @Nullable JetType type, Variance variance) { -+ this.expressionOfType = expressionOfType; -+ this.type = type; -+ this.variance = variance; -+ } -+ -+ public boolean isType() { -+ return this.type != null; -+ } -+ -+ @NotNull -+ public JetType getType() { -+ assert this.type != null; -+ return this.type; -+ } -+ -+ @NotNull -+ private List getPossibleTypes(BindingContext context) { -+ List types = new ArrayList(); -+ if (isType()) { -+ assert type != null : ""!isType() means type == null && expressionOfType != null""; -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ for (JetType type : guessTypeForExpression(expressionOfType, context)) { -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } -+ } -+ return types; -+ } -+ -+ public void computeTypeCandidates(@NotNull BindingContext context) { -+ Collection types = getPossibleTypes(context); -+ -+ typeCandidates = new TypeCandidate[types.size()]; -+ int i = 0; -+ for (JetType type : types) { -+ typeCandidates[i] = new TypeCandidate(type); -+ i++; -+ } -+ } -+ -+ public void computeTypeCandidates( -+ @NotNull BindingContext context, -+ @NotNull TypeSubstitution[] substitutions, -+ @NotNull JetScope scope -+ ) { -+ List types = getPossibleTypes(context); -+ Collections.reverse(types); // reverse and reverse back later, so that things added below are added at the front -+ -+ Set newTypes = new LinkedHashSet(types); -+ for (TypeSubstitution substitution : substitutions) { // each substitution can be applied or not, so we offer all options -+ List toAdd = new ArrayList(); -+ List toRemove = new ArrayList(); -+ for (JetType type : newTypes) { -+ toAdd.add(substituteType(type, substitution, variance)); -+ // substitution.byType are type arguments, but they cannot already occur in the type before substitution -+ if (containsType(type, substitution.getByType())) { -+ toRemove.add(type); -+ } -+ } -+ newTypes.addAll(toAdd); -+ newTypes.removeAll(toRemove); -+ } -+ -+ if (newTypes.isEmpty()) { -+ newTypes.add(KotlinBuiltIns.getInstance().getAnyType()); -+ } -+ -+ typeCandidates = new TypeCandidate[newTypes.size()]; -+ int i = typeCandidates.length - 1; // reverse order (see explanation above) -+ for (JetType type : newTypes) { -+ typeCandidates[i] = new TypeCandidate(type, scope); -+ i--; -+ } -+ } -+ -+ @NotNull -+ public TypeCandidate[] getTypeCandidates() { -+ assert typeCandidates != null : ""call computeTypeCandidates() first""; -+ return typeCandidates; -+ } -+ -+ public void renderTypeCandidates(@NotNull Map typeParameterNameMap) { -+ for (TypeCandidate candidate : typeCandidates) { -+ candidate.render(typeParameterNameMap); -+ } -+ } -+ -+ @NotNull -+ public String[] getPossibleNamesFromExpression() { -+ if (cachedNameCandidatesFromExpression != null) return cachedNameCandidatesFromExpression; -+ if (isType()) { -+ cachedNameCandidatesFromExpression = ArrayUtil.EMPTY_STRING_ARRAY; -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ JetNameValidator dummyValidator = new DummyJetNameValidator(expressionOfType.getProject()); -+ cachedNameCandidatesFromExpression = JetNameSuggester.suggestNamesForExpression(expressionOfType, dummyValidator); -+ } -+ return cachedNameCandidatesFromExpression; -+ } -+ } -+ -+ /** -+ * Encapsulates information about a method parameter that is going to be created. -+ */ -+ private static class Parameter { -+ private final String preferredName; -+ private final TypeOrExpressionThereof type; -+ -+ public Parameter(@Nullable(""no preferred name"") String preferredName, TypeOrExpressionThereof type) { -+ this.preferredName = preferredName; -+ this.type = type; -+ } -+ -+ public String getPreferredName() { -+ return preferredName; -+ } -+ -+ public TypeOrExpressionThereof getType() { -+ return type; -+ } -+ } -+ -+ /** -+ * Special Expression for parameter names based on its type. -+ */ -+ private static class ParameterNameExpression extends Expression { -+ private final String[] names; -+ private final Map parameterTypeToNamesMap; -+ -+ public ParameterNameExpression(@NotNull String[] names, @NotNull Map parameterTypeToNamesMap) { -+ for (String name : names) { -+ assert name != null && !name.isEmpty(); -+ } -+ this.names = names; -+ this.parameterTypeToNamesMap = parameterTypeToNamesMap; -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ LookupElement[] lookupItems = calculateLookupItems(context); -+ if (lookupItems.length == 0) return new TextResult(""""); -+ -+ return new TextResult(lookupItems[0].getLookupString()); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ Set names = new LinkedHashSet(); -+ Collections.addAll(names, this.names); -+ -+ // find the parameter list -+ Project project = context.getProject(); -+ int offset = context.getStartOffset(); -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ Editor editor = context.getEditor(); -+ assert editor != null; -+ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); -+ assert file != null && file instanceof JetFile; -+ PsiElement elementAt = file.findElementAt(offset); -+ JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); -+ if (func == null) return new LookupElement[0]; -+ JetParameterList parameterList = func.getValueParameterList(); -+ assert parameterList != null; -+ -+ // add names based on selected type -+ JetParameter parameter = PsiTreeUtil.getParentOfType(elementAt, JetParameter.class); -+ if (parameter != null) { -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ String[] suggestedNamesBasedOnType = parameterTypeToNamesMap.get(parameterTypeRef.getText()); -+ if (suggestedNamesBasedOnType != null) { -+ Collections.addAll(names, suggestedNamesBasedOnType); -+ } -+ } -+ } -+ -+ // remember other parameter names for later use -+ Set parameterNames = new HashSet(); -+ for (JetParameter jetParameter : parameterList.getParameters()) { -+ if (jetParameter == parameter || jetParameter.getName() == null) continue; -+ parameterNames.add(jetParameter.getName()); -+ } -+ -+ // add fallback parameter name -+ if (names.isEmpty()) { -+ names.add(""arg""); -+ } -+ -+ // ensure there are no conflicts -+ List lookupElements = new ArrayList(); -+ for (String name : names) { -+ name = getNextAvailableName(name, parameterNames); -+ lookupElements.add(LookupElementBuilder.create(name)); -+ } -+ -+ // create and return -+ return lookupElements.toArray(new LookupElement[lookupElements.size()]); -+ } -+ } -+ -+ /** -+ * An Expression for type references. -+ */ -+ private static class TypeExpression extends Expression { -+ private final TypeOrExpressionThereof type; -+ private @NotNull LookupElement[] cachedLookupElements; -+ -+ public TypeExpression(@NotNull TypeOrExpressionThereof type) { -+ this.type = type; -+ TypeCandidate[] candidates = type.getTypeCandidates(); -+ cachedLookupElements = new LookupElement[candidates.length]; -+ for (int i = 0; i < candidates.length; i++) { -+ cachedLookupElements[i] = LookupElementBuilder.create(candidates[i], candidates[i].getRenderedType()); -+ } -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ LookupElement[] lookupItems = calculateLookupItems(context); -+ if (lookupItems.length == 0) return new TextResult(""""); -+ -+ return new TextResult(lookupItems[0].getLookupString()); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ return cachedLookupElements; -+ } -+ -+ @NotNull -+ public TypeOrExpressionThereof getType() { -+ return type; -+ } -+ -+ @Nullable(""can't be found"") -+ public JetType getTypeFromSelection(@NotNull String selection) { -+ TypeCandidate[] options = type.getTypeCandidates(); -+ for (TypeCandidate option : options) { -+ if (option.getRenderedType().equals(selection)) { -+ return option.getType(); -+ } -+ } -+ return null; -+ } -+ } -+ -+ /** -+ * A sort-of dummy Expression for parameter lists, to allow us to update the parameter list as the user makes selections. -+ */ -+ private static class TypeParameterListExpression extends Expression { -+ private final String[] typeParameterNamesFromReceiverType; -+ private final Map parameterTypeToTypeParameterNamesMap; -+ -+ public TypeParameterListExpression( -+ @NotNull String[] typeParameterNamesFromReceiverType, -+ @NotNull Map typeParametersMap -+ ) { -+ this.typeParameterNamesFromReceiverType = typeParameterNamesFromReceiverType; -+ this.parameterTypeToTypeParameterNamesMap = typeParametersMap; -+ } -+ -+ @NotNull -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ Project project = context.getProject(); -+ int offset = context.getStartOffset(); -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ Editor editor = context.getEditor(); -+ assert editor != null; -+ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); -+ assert file != null && file instanceof JetFile; -+ PsiElement elementAt = file.findElementAt(offset); -+ JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); -+ if (func == null) { -+ return new TextResult(""""); -+ } -+ List parameters = func.getValueParameters(); -+ -+ Set typeParameterNames = new LinkedHashSet(); -+ Collections.addAll(typeParameterNames, typeParameterNamesFromReceiverType); -+ for (JetParameter parameter : parameters) { -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ String[] typeParameterNamesFromParameter = parameterTypeToTypeParameterNamesMap.get(parameterTypeRef.getText()); -+ if (typeParameterNamesFromParameter != null) { -+ Collections.addAll(typeParameterNames, typeParameterNamesFromParameter); -+ } -+ } -+ } -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ if (returnTypeRef != null) { -+ String[] typeParameterNamesFromReturnType = parameterTypeToTypeParameterNamesMap.get(returnTypeRef.getText()); -+ if (typeParameterNamesFromReturnType != null) { -+ Collections.addAll(typeParameterNames, typeParameterNamesFromReturnType); -+ } -+ } -+ -+ return typeParameterNames.isEmpty() -+ ? new TextResult("""") -+ : new TextResult("" <"" + StringUtil.join(typeParameterNames, "", "") + "">""); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ return new LookupElement[0]; // do not offer the user any choices -+ } -+ } -+ -+ /** -+ * A JetNameValidator that always succeeds. -+ */ -+ private static class DummyJetNameValidator implements JetNameValidator { -+ private final Project project; -+ -+ public DummyJetNameValidator(Project project) { -+ this.project = project; -+ } -+ -+ @Nullable -+ @Override -+ public String validateName(String name) { -+ return name; -+ } -+ -+ @Override -+ public Project getProject() { -+ return project; -+ } -+ } -+ -+ /** -+ * Encapsulates a single type substitution of a JetType by another JetType. -+ */ -+ private static class TypeSubstitution { -+ private final JetType forType; -+ private final JetType byType; -+ -+ private TypeSubstitution(JetType forType, JetType byType) { -+ this.forType = forType; -+ this.byType = byType; -+ } -+ -+ private JetType getForType() { -+ return forType; -+ } -+ -+ private JetType getByType() { -+ return byType; -+ } -+ } -+ -+ private final String methodName; -+ private final TypeOrExpressionThereof ownerType; -+ private final TypeOrExpressionThereof returnType; -+ private final List parameters; -+ -+ private boolean isUnit; -+ private boolean isExtension; -+ private JetFile currentFile; -+ private JetFile containingFile; -+ private Editor currentFileEditor; -+ private Editor containingFileEditor; -+ private BindingContext currentFileContext; -+ private JetClass ownerClass; -+ private ClassDescriptor ownerClassDescriptor; -+ private TypeCandidate selectedReceiverType; -+ private Map typeParameterNameMap; -+ -+ public CreateMethodFromUsageFix(@NotNull PsiElement element, @NotNull TypeOrExpressionThereof ownerType, @NotNull String methodName, -+ @NotNull TypeOrExpressionThereof returnType, @NotNull List parameters) { -+ super(element); -+ this.methodName = methodName; -+ this.ownerType = ownerType; -+ this.returnType = returnType; -+ this.parameters = parameters; -+ } -+ -+ @NotNull -+ @Override -+ public String getText() { -+ return JetBundle.message(""create.method.from.usage"", methodName); -+ } -+ -+ @Override -+ public void invoke(@NotNull final Project project, Editor editor, PsiFile file) throws IncorrectOperationException { -+ assert file != null && file instanceof JetFile; -+ currentFile = (JetFile) file; -+ currentFileEditor = editor; -+ currentFileContext = AnalyzerFacadeWithCache.analyzeFileWithCache(currentFile).getBindingContext(); -+ -+ ownerType.computeTypeCandidates(currentFileContext); -+ TypeCandidate[] ownerTypeCandidates = ownerType.getTypeCandidates(); -+ assert ownerTypeCandidates.length > 0; -+ if (ownerTypeCandidates.length == 1 || ApplicationManager.getApplication().isUnitTestMode()) { -+ selectedReceiverType = ownerTypeCandidates[0]; -+ doInvoke(project); -+ } else { -+ // class selection -+ List options = new ArrayList(); -+ final Map optionToTypeMap = new HashMap(); -+ for (TypeCandidate ownerTypeCandidate : ownerTypeCandidates) { -+ ClassifierDescriptor possibleClassDescriptor = ownerTypeCandidate.getType().getConstructor().getDeclarationDescriptor(); -+ if (possibleClassDescriptor != null) { -+ String className = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(possibleClassDescriptor.getDefaultType()); -+ DeclarationDescriptor namespaceDescriptor = possibleClassDescriptor.getContainingDeclaration(); -+ String namespace = renderDescriptor(namespaceDescriptor, true); -+ String option = className + "" ("" + namespace + "")""; -+ options.add(option); -+ optionToTypeMap.put(option, ownerTypeCandidate); -+ } -+ } -+ -+ final JList list = new JBList(options); -+ PsiElementListCellRenderer renderer = new JetLightClassListCellRenderer(); -+ list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); -+ list.setCellRenderer(renderer); -+ PopupChooserBuilder builder = new PopupChooserBuilder(list); -+ renderer.installSpeedSearch(builder); -+ -+ Runnable runnable = new Runnable() { -+ @Override -+ public void run() { -+ int index = list.getSelectedIndex();","Why not check `getSelectedValue()` for null, if we access it anyway? -",Why is this needed? Looks like a duplicate file. -98,"@@ -0,0 +1,1391 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.codeInsight.lookup.LookupElement; -+import com.intellij.codeInsight.lookup.LookupElementBuilder; -+import com.intellij.codeInsight.template.*; -+import com.intellij.codeInsight.template.impl.TemplateImpl; -+import com.intellij.codeInsight.template.impl.Variable; -+import com.intellij.ide.fileTemplates.FileTemplate; -+import com.intellij.ide.fileTemplates.FileTemplateManager; -+import com.intellij.ide.util.PsiElementListCellRenderer; -+import com.intellij.openapi.application.ApplicationManager; -+import com.intellij.openapi.command.CommandProcessor; -+import com.intellij.openapi.editor.CaretModel; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.fileEditor.FileEditorManager; -+import com.intellij.openapi.progress.ProcessCanceledException; -+import com.intellij.openapi.project.Project; -+import com.intellij.openapi.ui.popup.PopupChooserBuilder; -+import com.intellij.openapi.util.TextRange; -+import com.intellij.openapi.util.text.StringUtil; -+import com.intellij.openapi.vfs.VirtualFile; -+import com.intellij.psi.PsiDocumentManager; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.PsiReference; -+import com.intellij.psi.search.SearchScope; -+import com.intellij.psi.util.PsiTreeUtil; -+import com.intellij.refactoring.psi.SearchUtils; -+import com.intellij.ui.components.JBList; -+import com.intellij.util.ArrayUtil; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NonNls; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.descriptors.*; -+import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1; -+import org.jetbrains.jet.lang.diagnostics.Errors; -+import org.jetbrains.jet.lang.psi.*; -+import org.jetbrains.jet.lang.resolve.BindingContext; -+import org.jetbrains.jet.lang.resolve.BindingContextUtils; -+import org.jetbrains.jet.lang.resolve.DescriptorUtils; -+import org.jetbrains.jet.lang.resolve.name.Name; -+import org.jetbrains.jet.lang.resolve.scopes.JetScope; -+import org.jetbrains.jet.lang.types.*; -+import org.jetbrains.jet.lang.types.checker.JetTypeChecker; -+import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; -+import org.jetbrains.jet.plugin.JetBundle; -+import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening; -+import org.jetbrains.jet.plugin.presentation.JetLightClassListCellRenderer; -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; -+import org.jetbrains.jet.plugin.refactoring.JetNameSuggester; -+import org.jetbrains.jet.plugin.refactoring.JetNameValidator; -+import org.jetbrains.jet.plugin.references.JetSimpleNameReference; -+import org.jetbrains.jet.renderer.DescriptorRenderer; -+ -+import javax.swing.*; -+import java.util.*; -+import java.util.regex.Matcher; -+import java.util.regex.Pattern; -+ -+public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { -+ private static final String TYPE_PARAMETER_LIST_VARIABLE_NAME = ""typeParameterList""; -+ private static final String TEMPLATE_FROM_USAGE_METHOD_BODY = ""New Kotlin Method Body.kt""; -+ private static final Pattern COMPONENT_FUNCTION_PATTERN = Pattern.compile(""^component(\\d+)$""); -+ -+ /** -+ * Represents a single choice for a type (e.g. parameter type or return type). -+ */ -+ private static class TypeCandidate { -+ private final JetType type; -+ private final TypeParameterDescriptor[] typeParameters; -+ private String renderedType; -+ private String[] typeParameterNames; -+ -+ public TypeCandidate(@NotNull JetType type) { -+ this.type = type; -+ Set typeParametersInType = getTypeParametersInType(type); -+ typeParameters = typeParametersInType.toArray(new TypeParameterDescriptor[typeParametersInType.size()]); -+ renderedType = renderTypeShort(type, Collections.emptyMap()); -+ } -+ -+ public TypeCandidate(@NotNull JetType type, @NotNull JetScope scope) { -+ this.type = type; -+ typeParameters = getTypeParameterNamesNotInScope(getTypeParametersInType(type), scope); -+ } -+ -+ public void render(@NotNull Map typeParameterNameMap) { -+ renderedType = renderTypeShort(type, typeParameterNameMap); -+ typeParameterNames = new String[typeParameters.length]; -+ int i = 0; -+ for (TypeParameterDescriptor typeParameter : typeParameters) { -+ typeParameterNames[i] = typeParameterNameMap.get(typeParameter); -+ i++; -+ } -+ } -+ -+ @NotNull JetType getType() { -+ return type; -+ } -+ -+ @NotNull -+ public String getRenderedType() { -+ assert renderedType != null : ""call render() first""; -+ return renderedType; -+ } -+ -+ @NotNull -+ public String[] getTypeParameterNames() { -+ assert typeParameterNames != null : ""call render() first""; -+ return typeParameterNames; -+ } -+ -+ @NotNull -+ public TypeParameterDescriptor[] getTypeParameters() { -+ return typeParameters; -+ } -+ } -+ -+ /** -+ * Represents a concrete type or a set of types yet to be inferred from an expression. -+ */ -+ private static class TypeOrExpressionThereof { -+ private final JetExpression expressionOfType; -+ private final JetType type; -+ private final Variance variance; -+ private TypeCandidate[] typeCandidates; -+ private String[] cachedNameCandidatesFromExpression; -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType) { -+ this(expressionOfType, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType, Variance variance) { -+ this(expressionOfType, null, variance); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type) { -+ this(type, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type, Variance variance) { -+ this(null, type, variance); -+ } -+ -+ private TypeOrExpressionThereof(@Nullable JetExpression expressionOfType, @Nullable JetType type, Variance variance) { -+ this.expressionOfType = expressionOfType; -+ this.type = type; -+ this.variance = variance; -+ } -+ -+ public boolean isType() { -+ return this.type != null; -+ } -+ -+ @NotNull -+ public JetType getType() { -+ assert this.type != null; -+ return this.type; -+ } -+ -+ @NotNull -+ private List getPossibleTypes(BindingContext context) { -+ List types = new ArrayList(); -+ if (isType()) { -+ assert type != null : ""!isType() means type == null && expressionOfType != null""; -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ for (JetType type : guessTypeForExpression(expressionOfType, context)) { -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } -+ } -+ return types; -+ } -+ -+ public void computeTypeCandidates(@NotNull BindingContext context) { -+ Collection types = getPossibleTypes(context); -+ -+ typeCandidates = new TypeCandidate[types.size()]; -+ int i = 0; -+ for (JetType type : types) { -+ typeCandidates[i] = new TypeCandidate(type); -+ i++; -+ } -+ } -+ -+ public void computeTypeCandidates( -+ @NotNull BindingContext context, -+ @NotNull TypeSubstitution[] substitutions, -+ @NotNull JetScope scope -+ ) { -+ List types = getPossibleTypes(context); -+ Collections.reverse(types); // reverse and reverse back later, so that things added below are added at the front -+ -+ Set newTypes = new LinkedHashSet(types); -+ for (TypeSubstitution substitution : substitutions) { // each substitution can be applied or not, so we offer all options -+ List toAdd = new ArrayList(); -+ List toRemove = new ArrayList(); -+ for (JetType type : newTypes) { -+ toAdd.add(substituteType(type, substitution, variance)); -+ // substitution.byType are type arguments, but they cannot already occur in the type before substitution -+ if (containsType(type, substitution.getByType())) { -+ toRemove.add(type); -+ } -+ } -+ newTypes.addAll(toAdd); -+ newTypes.removeAll(toRemove); -+ } -+ -+ if (newTypes.isEmpty()) { -+ newTypes.add(KotlinBuiltIns.getInstance().getAnyType()); -+ } -+ -+ typeCandidates = new TypeCandidate[newTypes.size()]; -+ int i = typeCandidates.length - 1; // reverse order (see explanation above) -+ for (JetType type : newTypes) { -+ typeCandidates[i] = new TypeCandidate(type, scope); -+ i--; -+ } -+ } -+ -+ @NotNull -+ public TypeCandidate[] getTypeCandidates() { -+ assert typeCandidates != null : ""call computeTypeCandidates() first""; -+ return typeCandidates; -+ } -+ -+ public void renderTypeCandidates(@NotNull Map typeParameterNameMap) { -+ for (TypeCandidate candidate : typeCandidates) { -+ candidate.render(typeParameterNameMap); -+ } -+ } -+ -+ @NotNull -+ public String[] getPossibleNamesFromExpression() { -+ if (cachedNameCandidatesFromExpression != null) return cachedNameCandidatesFromExpression; -+ if (isType()) { -+ cachedNameCandidatesFromExpression = ArrayUtil.EMPTY_STRING_ARRAY; -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ JetNameValidator dummyValidator = new DummyJetNameValidator(expressionOfType.getProject()); -+ cachedNameCandidatesFromExpression = JetNameSuggester.suggestNamesForExpression(expressionOfType, dummyValidator); -+ } -+ return cachedNameCandidatesFromExpression; -+ } -+ } -+ -+ /** -+ * Encapsulates information about a method parameter that is going to be created. -+ */ -+ private static class Parameter { -+ private final String preferredName; -+ private final TypeOrExpressionThereof type; -+ -+ public Parameter(@Nullable(""no preferred name"") String preferredName, TypeOrExpressionThereof type) { -+ this.preferredName = preferredName; -+ this.type = type; -+ } -+ -+ public String getPreferredName() { -+ return preferredName; -+ } -+ -+ public TypeOrExpressionThereof getType() { -+ return type; -+ } -+ } -+ -+ /** -+ * Special Expression for parameter names based on its type. -+ */ -+ private static class ParameterNameExpression extends Expression { -+ private final String[] names; -+ private final Map parameterTypeToNamesMap; -+ -+ public ParameterNameExpression(@NotNull String[] names, @NotNull Map parameterTypeToNamesMap) { -+ for (String name : names) { -+ assert name != null && !name.isEmpty(); -+ } -+ this.names = names; -+ this.parameterTypeToNamesMap = parameterTypeToNamesMap; -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ LookupElement[] lookupItems = calculateLookupItems(context); -+ if (lookupItems.length == 0) return new TextResult(""""); -+ -+ return new TextResult(lookupItems[0].getLookupString()); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ Set names = new LinkedHashSet(); -+ Collections.addAll(names, this.names); -+ -+ // find the parameter list -+ Project project = context.getProject(); -+ int offset = context.getStartOffset(); -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ Editor editor = context.getEditor(); -+ assert editor != null; -+ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); -+ assert file != null && file instanceof JetFile; -+ PsiElement elementAt = file.findElementAt(offset); -+ JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); -+ if (func == null) return new LookupElement[0]; -+ JetParameterList parameterList = func.getValueParameterList(); -+ assert parameterList != null; -+ -+ // add names based on selected type -+ JetParameter parameter = PsiTreeUtil.getParentOfType(elementAt, JetParameter.class); -+ if (parameter != null) { -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ String[] suggestedNamesBasedOnType = parameterTypeToNamesMap.get(parameterTypeRef.getText()); -+ if (suggestedNamesBasedOnType != null) { -+ Collections.addAll(names, suggestedNamesBasedOnType); -+ } -+ } -+ } -+ -+ // remember other parameter names for later use -+ Set parameterNames = new HashSet(); -+ for (JetParameter jetParameter : parameterList.getParameters()) { -+ if (jetParameter == parameter || jetParameter.getName() == null) continue; -+ parameterNames.add(jetParameter.getName()); -+ } -+ -+ // add fallback parameter name -+ if (names.isEmpty()) { -+ names.add(""arg""); -+ } -+ -+ // ensure there are no conflicts -+ List lookupElements = new ArrayList(); -+ for (String name : names) { -+ name = getNextAvailableName(name, parameterNames); -+ lookupElements.add(LookupElementBuilder.create(name)); -+ } -+ -+ // create and return -+ return lookupElements.toArray(new LookupElement[lookupElements.size()]); -+ } -+ } -+ -+ /** -+ * An Expression for type references. -+ */ -+ private static class TypeExpression extends Expression { -+ private final TypeOrExpressionThereof type; -+ private @NotNull LookupElement[] cachedLookupElements; -+ -+ public TypeExpression(@NotNull TypeOrExpressionThereof type) { -+ this.type = type; -+ TypeCandidate[] candidates = type.getTypeCandidates(); -+ cachedLookupElements = new LookupElement[candidates.length]; -+ for (int i = 0; i < candidates.length; i++) { -+ cachedLookupElements[i] = LookupElementBuilder.create(candidates[i], candidates[i].getRenderedType()); -+ } -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ LookupElement[] lookupItems = calculateLookupItems(context); -+ if (lookupItems.length == 0) return new TextResult(""""); -+ -+ return new TextResult(lookupItems[0].getLookupString()); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ return cachedLookupElements; -+ } -+ -+ @NotNull -+ public TypeOrExpressionThereof getType() { -+ return type; -+ } -+ -+ @Nullable(""can't be found"") -+ public JetType getTypeFromSelection(@NotNull String selection) { -+ TypeCandidate[] options = type.getTypeCandidates(); -+ for (TypeCandidate option : options) { -+ if (option.getRenderedType().equals(selection)) { -+ return option.getType(); -+ } -+ } -+ return null; -+ } -+ } -+ -+ /** -+ * A sort-of dummy Expression for parameter lists, to allow us to update the parameter list as the user makes selections. -+ */ -+ private static class TypeParameterListExpression extends Expression { -+ private final String[] typeParameterNamesFromReceiverType; -+ private final Map parameterTypeToTypeParameterNamesMap; -+ -+ public TypeParameterListExpression( -+ @NotNull String[] typeParameterNamesFromReceiverType, -+ @NotNull Map typeParametersMap -+ ) { -+ this.typeParameterNamesFromReceiverType = typeParameterNamesFromReceiverType; -+ this.parameterTypeToTypeParameterNamesMap = typeParametersMap; -+ } -+ -+ @NotNull -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ Project project = context.getProject(); -+ int offset = context.getStartOffset(); -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ Editor editor = context.getEditor(); -+ assert editor != null; -+ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); -+ assert file != null && file instanceof JetFile; -+ PsiElement elementAt = file.findElementAt(offset); -+ JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); -+ if (func == null) { -+ return new TextResult(""""); -+ } -+ List parameters = func.getValueParameters(); -+ -+ Set typeParameterNames = new LinkedHashSet(); -+ Collections.addAll(typeParameterNames, typeParameterNamesFromReceiverType); -+ for (JetParameter parameter : parameters) { -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ String[] typeParameterNamesFromParameter = parameterTypeToTypeParameterNamesMap.get(parameterTypeRef.getText()); -+ if (typeParameterNamesFromParameter != null) { -+ Collections.addAll(typeParameterNames, typeParameterNamesFromParameter); -+ } -+ } -+ } -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ if (returnTypeRef != null) { -+ String[] typeParameterNamesFromReturnType = parameterTypeToTypeParameterNamesMap.get(returnTypeRef.getText()); -+ if (typeParameterNamesFromReturnType != null) { -+ Collections.addAll(typeParameterNames, typeParameterNamesFromReturnType); -+ } -+ } -+ -+ return typeParameterNames.isEmpty() -+ ? new TextResult("""") -+ : new TextResult("" <"" + StringUtil.join(typeParameterNames, "", "") + "">""); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ return new LookupElement[0]; // do not offer the user any choices -+ } -+ } -+ -+ /** -+ * A JetNameValidator that always succeeds. -+ */ -+ private static class DummyJetNameValidator implements JetNameValidator { -+ private final Project project; -+ -+ public DummyJetNameValidator(Project project) { -+ this.project = project; -+ } -+ -+ @Nullable -+ @Override -+ public String validateName(String name) { -+ return name; -+ } -+ -+ @Override -+ public Project getProject() { -+ return project; -+ } -+ } -+ -+ /** -+ * Encapsulates a single type substitution of a JetType by another JetType. -+ */ -+ private static class TypeSubstitution { -+ private final JetType forType; -+ private final JetType byType; -+ -+ private TypeSubstitution(JetType forType, JetType byType) { -+ this.forType = forType; -+ this.byType = byType; -+ } -+ -+ private JetType getForType() { -+ return forType; -+ } -+ -+ private JetType getByType() { -+ return byType; -+ } -+ } -+ -+ private final String methodName; -+ private final TypeOrExpressionThereof ownerType; -+ private final TypeOrExpressionThereof returnType; -+ private final List parameters; -+ -+ private boolean isUnit; -+ private boolean isExtension; -+ private JetFile currentFile; -+ private JetFile containingFile; -+ private Editor currentFileEditor; -+ private Editor containingFileEditor; -+ private BindingContext currentFileContext; -+ private JetClass ownerClass; -+ private ClassDescriptor ownerClassDescriptor; -+ private TypeCandidate selectedReceiverType; -+ private Map typeParameterNameMap; -+ -+ public CreateMethodFromUsageFix(@NotNull PsiElement element, @NotNull TypeOrExpressionThereof ownerType, @NotNull String methodName, -+ @NotNull TypeOrExpressionThereof returnType, @NotNull List parameters) { -+ super(element); -+ this.methodName = methodName; -+ this.ownerType = ownerType; -+ this.returnType = returnType; -+ this.parameters = parameters; -+ } -+ -+ @NotNull -+ @Override -+ public String getText() { -+ return JetBundle.message(""create.method.from.usage"", methodName); -+ } -+ -+ @Override -+ public void invoke(@NotNull final Project project, Editor editor, PsiFile file) throws IncorrectOperationException { -+ assert file != null && file instanceof JetFile; -+ currentFile = (JetFile) file; -+ currentFileEditor = editor; -+ currentFileContext = AnalyzerFacadeWithCache.analyzeFileWithCache(currentFile).getBindingContext(); -+ -+ ownerType.computeTypeCandidates(currentFileContext); -+ TypeCandidate[] ownerTypeCandidates = ownerType.getTypeCandidates(); -+ assert ownerTypeCandidates.length > 0; -+ if (ownerTypeCandidates.length == 1 || ApplicationManager.getApplication().isUnitTestMode()) { -+ selectedReceiverType = ownerTypeCandidates[0]; -+ doInvoke(project); -+ } else { -+ // class selection -+ List options = new ArrayList(); -+ final Map optionToTypeMap = new HashMap(); -+ for (TypeCandidate ownerTypeCandidate : ownerTypeCandidates) { -+ ClassifierDescriptor possibleClassDescriptor = ownerTypeCandidate.getType().getConstructor().getDeclarationDescriptor(); -+ if (possibleClassDescriptor != null) { -+ String className = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(possibleClassDescriptor.getDefaultType()); -+ DeclarationDescriptor namespaceDescriptor = possibleClassDescriptor.getContainingDeclaration(); -+ String namespace = renderDescriptor(namespaceDescriptor, true); -+ String option = className + "" ("" + namespace + "")""; -+ options.add(option); -+ optionToTypeMap.put(option, ownerTypeCandidate); -+ } -+ } -+ -+ final JList list = new JBList(options); -+ PsiElementListCellRenderer renderer = new JetLightClassListCellRenderer(); -+ list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); -+ list.setCellRenderer(renderer); -+ PopupChooserBuilder builder = new PopupChooserBuilder(list); -+ renderer.installSpeedSearch(builder); -+ -+ Runnable runnable = new Runnable() { -+ @Override -+ public void run() { -+ int index = list.getSelectedIndex(); -+ if (index < 0) return; -+ String option = (String) list.getSelectedValue(); -+ selectedReceiverType = optionToTypeMap.get(option); -+ CommandProcessor.getInstance().executeCommand(project, new Runnable() { -+ @Override -+ public void run() { -+ doInvoke(project); -+ } -+ }, getText(), null); -+ } -+ }; -+ -+ builder.setTitle(JetBundle.message(""choose.target.class.or.trait.title"")) -+ .setItemChoosenCallback(runnable) -+ .createPopup() -+ .showInBestPositionFor(currentFileEditor); -+ } -+ } -+ -+ private void doInvoke(@NotNull final Project project) {","`doInvoke` is not a good name, because it doesn't explain how it differs from simple `invoke`. Rename it to `addFunctionToSelectedOwner` or something like that. -",Why is this needed? Looks like a duplicate file. -99,"@@ -0,0 +1,1391 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.codeInsight.lookup.LookupElement; -+import com.intellij.codeInsight.lookup.LookupElementBuilder; -+import com.intellij.codeInsight.template.*; -+import com.intellij.codeInsight.template.impl.TemplateImpl; -+import com.intellij.codeInsight.template.impl.Variable; -+import com.intellij.ide.fileTemplates.FileTemplate; -+import com.intellij.ide.fileTemplates.FileTemplateManager; -+import com.intellij.ide.util.PsiElementListCellRenderer; -+import com.intellij.openapi.application.ApplicationManager; -+import com.intellij.openapi.command.CommandProcessor; -+import com.intellij.openapi.editor.CaretModel; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.fileEditor.FileEditorManager; -+import com.intellij.openapi.progress.ProcessCanceledException; -+import com.intellij.openapi.project.Project; -+import com.intellij.openapi.ui.popup.PopupChooserBuilder; -+import com.intellij.openapi.util.TextRange; -+import com.intellij.openapi.util.text.StringUtil; -+import com.intellij.openapi.vfs.VirtualFile; -+import com.intellij.psi.PsiDocumentManager; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.PsiReference; -+import com.intellij.psi.search.SearchScope; -+import com.intellij.psi.util.PsiTreeUtil; -+import com.intellij.refactoring.psi.SearchUtils; -+import com.intellij.ui.components.JBList; -+import com.intellij.util.ArrayUtil; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NonNls; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.descriptors.*; -+import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1; -+import org.jetbrains.jet.lang.diagnostics.Errors; -+import org.jetbrains.jet.lang.psi.*; -+import org.jetbrains.jet.lang.resolve.BindingContext; -+import org.jetbrains.jet.lang.resolve.BindingContextUtils; -+import org.jetbrains.jet.lang.resolve.DescriptorUtils; -+import org.jetbrains.jet.lang.resolve.name.Name; -+import org.jetbrains.jet.lang.resolve.scopes.JetScope; -+import org.jetbrains.jet.lang.types.*; -+import org.jetbrains.jet.lang.types.checker.JetTypeChecker; -+import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; -+import org.jetbrains.jet.plugin.JetBundle; -+import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening; -+import org.jetbrains.jet.plugin.presentation.JetLightClassListCellRenderer; -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; -+import org.jetbrains.jet.plugin.refactoring.JetNameSuggester; -+import org.jetbrains.jet.plugin.refactoring.JetNameValidator; -+import org.jetbrains.jet.plugin.references.JetSimpleNameReference; -+import org.jetbrains.jet.renderer.DescriptorRenderer; -+ -+import javax.swing.*; -+import java.util.*; -+import java.util.regex.Matcher; -+import java.util.regex.Pattern; -+ -+public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { -+ private static final String TYPE_PARAMETER_LIST_VARIABLE_NAME = ""typeParameterList""; -+ private static final String TEMPLATE_FROM_USAGE_METHOD_BODY = ""New Kotlin Method Body.kt""; -+ private static final Pattern COMPONENT_FUNCTION_PATTERN = Pattern.compile(""^component(\\d+)$""); -+ -+ /** -+ * Represents a single choice for a type (e.g. parameter type or return type). -+ */ -+ private static class TypeCandidate { -+ private final JetType type; -+ private final TypeParameterDescriptor[] typeParameters; -+ private String renderedType; -+ private String[] typeParameterNames; -+ -+ public TypeCandidate(@NotNull JetType type) { -+ this.type = type; -+ Set typeParametersInType = getTypeParametersInType(type); -+ typeParameters = typeParametersInType.toArray(new TypeParameterDescriptor[typeParametersInType.size()]); -+ renderedType = renderTypeShort(type, Collections.emptyMap()); -+ } -+ -+ public TypeCandidate(@NotNull JetType type, @NotNull JetScope scope) { -+ this.type = type; -+ typeParameters = getTypeParameterNamesNotInScope(getTypeParametersInType(type), scope); -+ } -+ -+ public void render(@NotNull Map typeParameterNameMap) { -+ renderedType = renderTypeShort(type, typeParameterNameMap); -+ typeParameterNames = new String[typeParameters.length]; -+ int i = 0; -+ for (TypeParameterDescriptor typeParameter : typeParameters) { -+ typeParameterNames[i] = typeParameterNameMap.get(typeParameter); -+ i++; -+ } -+ } -+ -+ @NotNull JetType getType() { -+ return type; -+ } -+ -+ @NotNull -+ public String getRenderedType() { -+ assert renderedType != null : ""call render() first""; -+ return renderedType; -+ } -+ -+ @NotNull -+ public String[] getTypeParameterNames() { -+ assert typeParameterNames != null : ""call render() first""; -+ return typeParameterNames; -+ } -+ -+ @NotNull -+ public TypeParameterDescriptor[] getTypeParameters() { -+ return typeParameters; -+ } -+ } -+ -+ /** -+ * Represents a concrete type or a set of types yet to be inferred from an expression. -+ */ -+ private static class TypeOrExpressionThereof { -+ private final JetExpression expressionOfType; -+ private final JetType type; -+ private final Variance variance; -+ private TypeCandidate[] typeCandidates; -+ private String[] cachedNameCandidatesFromExpression; -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType) { -+ this(expressionOfType, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType, Variance variance) { -+ this(expressionOfType, null, variance); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type) { -+ this(type, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type, Variance variance) { -+ this(null, type, variance); -+ } -+ -+ private TypeOrExpressionThereof(@Nullable JetExpression expressionOfType, @Nullable JetType type, Variance variance) { -+ this.expressionOfType = expressionOfType; -+ this.type = type; -+ this.variance = variance; -+ } -+ -+ public boolean isType() { -+ return this.type != null; -+ } -+ -+ @NotNull -+ public JetType getType() { -+ assert this.type != null; -+ return this.type; -+ } -+ -+ @NotNull -+ private List getPossibleTypes(BindingContext context) { -+ List types = new ArrayList(); -+ if (isType()) { -+ assert type != null : ""!isType() means type == null && expressionOfType != null""; -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ for (JetType type : guessTypeForExpression(expressionOfType, context)) { -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } -+ } -+ return types; -+ } -+ -+ public void computeTypeCandidates(@NotNull BindingContext context) { -+ Collection types = getPossibleTypes(context); -+ -+ typeCandidates = new TypeCandidate[types.size()]; -+ int i = 0; -+ for (JetType type : types) { -+ typeCandidates[i] = new TypeCandidate(type); -+ i++; -+ } -+ } -+ -+ public void computeTypeCandidates( -+ @NotNull BindingContext context, -+ @NotNull TypeSubstitution[] substitutions, -+ @NotNull JetScope scope -+ ) { -+ List types = getPossibleTypes(context); -+ Collections.reverse(types); // reverse and reverse back later, so that things added below are added at the front -+ -+ Set newTypes = new LinkedHashSet(types); -+ for (TypeSubstitution substitution : substitutions) { // each substitution can be applied or not, so we offer all options -+ List toAdd = new ArrayList(); -+ List toRemove = new ArrayList(); -+ for (JetType type : newTypes) { -+ toAdd.add(substituteType(type, substitution, variance)); -+ // substitution.byType are type arguments, but they cannot already occur in the type before substitution -+ if (containsType(type, substitution.getByType())) { -+ toRemove.add(type); -+ } -+ } -+ newTypes.addAll(toAdd); -+ newTypes.removeAll(toRemove); -+ } -+ -+ if (newTypes.isEmpty()) { -+ newTypes.add(KotlinBuiltIns.getInstance().getAnyType()); -+ } -+ -+ typeCandidates = new TypeCandidate[newTypes.size()]; -+ int i = typeCandidates.length - 1; // reverse order (see explanation above) -+ for (JetType type : newTypes) { -+ typeCandidates[i] = new TypeCandidate(type, scope); -+ i--; -+ } -+ } -+ -+ @NotNull -+ public TypeCandidate[] getTypeCandidates() { -+ assert typeCandidates != null : ""call computeTypeCandidates() first""; -+ return typeCandidates; -+ } -+ -+ public void renderTypeCandidates(@NotNull Map typeParameterNameMap) { -+ for (TypeCandidate candidate : typeCandidates) { -+ candidate.render(typeParameterNameMap); -+ } -+ } -+ -+ @NotNull -+ public String[] getPossibleNamesFromExpression() { -+ if (cachedNameCandidatesFromExpression != null) return cachedNameCandidatesFromExpression; -+ if (isType()) { -+ cachedNameCandidatesFromExpression = ArrayUtil.EMPTY_STRING_ARRAY; -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ JetNameValidator dummyValidator = new DummyJetNameValidator(expressionOfType.getProject()); -+ cachedNameCandidatesFromExpression = JetNameSuggester.suggestNamesForExpression(expressionOfType, dummyValidator); -+ } -+ return cachedNameCandidatesFromExpression; -+ } -+ } -+ -+ /** -+ * Encapsulates information about a method parameter that is going to be created. -+ */ -+ private static class Parameter { -+ private final String preferredName; -+ private final TypeOrExpressionThereof type; -+ -+ public Parameter(@Nullable(""no preferred name"") String preferredName, TypeOrExpressionThereof type) { -+ this.preferredName = preferredName; -+ this.type = type; -+ } -+ -+ public String getPreferredName() { -+ return preferredName; -+ } -+ -+ public TypeOrExpressionThereof getType() { -+ return type; -+ } -+ } -+ -+ /** -+ * Special Expression for parameter names based on its type. -+ */ -+ private static class ParameterNameExpression extends Expression { -+ private final String[] names; -+ private final Map parameterTypeToNamesMap; -+ -+ public ParameterNameExpression(@NotNull String[] names, @NotNull Map parameterTypeToNamesMap) { -+ for (String name : names) { -+ assert name != null && !name.isEmpty(); -+ } -+ this.names = names; -+ this.parameterTypeToNamesMap = parameterTypeToNamesMap; -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ LookupElement[] lookupItems = calculateLookupItems(context); -+ if (lookupItems.length == 0) return new TextResult(""""); -+ -+ return new TextResult(lookupItems[0].getLookupString()); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ Set names = new LinkedHashSet(); -+ Collections.addAll(names, this.names); -+ -+ // find the parameter list -+ Project project = context.getProject(); -+ int offset = context.getStartOffset(); -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ Editor editor = context.getEditor(); -+ assert editor != null; -+ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); -+ assert file != null && file instanceof JetFile; -+ PsiElement elementAt = file.findElementAt(offset); -+ JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); -+ if (func == null) return new LookupElement[0]; -+ JetParameterList parameterList = func.getValueParameterList(); -+ assert parameterList != null; -+ -+ // add names based on selected type -+ JetParameter parameter = PsiTreeUtil.getParentOfType(elementAt, JetParameter.class); -+ if (parameter != null) { -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ String[] suggestedNamesBasedOnType = parameterTypeToNamesMap.get(parameterTypeRef.getText()); -+ if (suggestedNamesBasedOnType != null) { -+ Collections.addAll(names, suggestedNamesBasedOnType); -+ } -+ } -+ } -+ -+ // remember other parameter names for later use -+ Set parameterNames = new HashSet(); -+ for (JetParameter jetParameter : parameterList.getParameters()) { -+ if (jetParameter == parameter || jetParameter.getName() == null) continue; -+ parameterNames.add(jetParameter.getName()); -+ } -+ -+ // add fallback parameter name -+ if (names.isEmpty()) { -+ names.add(""arg""); -+ } -+ -+ // ensure there are no conflicts -+ List lookupElements = new ArrayList(); -+ for (String name : names) { -+ name = getNextAvailableName(name, parameterNames); -+ lookupElements.add(LookupElementBuilder.create(name)); -+ } -+ -+ // create and return -+ return lookupElements.toArray(new LookupElement[lookupElements.size()]); -+ } -+ } -+ -+ /** -+ * An Expression for type references. -+ */ -+ private static class TypeExpression extends Expression { -+ private final TypeOrExpressionThereof type; -+ private @NotNull LookupElement[] cachedLookupElements; -+ -+ public TypeExpression(@NotNull TypeOrExpressionThereof type) { -+ this.type = type; -+ TypeCandidate[] candidates = type.getTypeCandidates(); -+ cachedLookupElements = new LookupElement[candidates.length]; -+ for (int i = 0; i < candidates.length; i++) { -+ cachedLookupElements[i] = LookupElementBuilder.create(candidates[i], candidates[i].getRenderedType()); -+ } -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ LookupElement[] lookupItems = calculateLookupItems(context); -+ if (lookupItems.length == 0) return new TextResult(""""); -+ -+ return new TextResult(lookupItems[0].getLookupString()); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ return cachedLookupElements; -+ } -+ -+ @NotNull -+ public TypeOrExpressionThereof getType() { -+ return type; -+ } -+ -+ @Nullable(""can't be found"") -+ public JetType getTypeFromSelection(@NotNull String selection) { -+ TypeCandidate[] options = type.getTypeCandidates(); -+ for (TypeCandidate option : options) { -+ if (option.getRenderedType().equals(selection)) { -+ return option.getType(); -+ } -+ } -+ return null; -+ } -+ } -+ -+ /** -+ * A sort-of dummy Expression for parameter lists, to allow us to update the parameter list as the user makes selections. -+ */ -+ private static class TypeParameterListExpression extends Expression { -+ private final String[] typeParameterNamesFromReceiverType; -+ private final Map parameterTypeToTypeParameterNamesMap; -+ -+ public TypeParameterListExpression( -+ @NotNull String[] typeParameterNamesFromReceiverType, -+ @NotNull Map typeParametersMap -+ ) { -+ this.typeParameterNamesFromReceiverType = typeParameterNamesFromReceiverType; -+ this.parameterTypeToTypeParameterNamesMap = typeParametersMap; -+ } -+ -+ @NotNull -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ Project project = context.getProject(); -+ int offset = context.getStartOffset(); -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ Editor editor = context.getEditor(); -+ assert editor != null; -+ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); -+ assert file != null && file instanceof JetFile; -+ PsiElement elementAt = file.findElementAt(offset); -+ JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); -+ if (func == null) { -+ return new TextResult(""""); -+ } -+ List parameters = func.getValueParameters(); -+ -+ Set typeParameterNames = new LinkedHashSet(); -+ Collections.addAll(typeParameterNames, typeParameterNamesFromReceiverType); -+ for (JetParameter parameter : parameters) { -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ String[] typeParameterNamesFromParameter = parameterTypeToTypeParameterNamesMap.get(parameterTypeRef.getText()); -+ if (typeParameterNamesFromParameter != null) { -+ Collections.addAll(typeParameterNames, typeParameterNamesFromParameter); -+ } -+ } -+ } -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ if (returnTypeRef != null) { -+ String[] typeParameterNamesFromReturnType = parameterTypeToTypeParameterNamesMap.get(returnTypeRef.getText()); -+ if (typeParameterNamesFromReturnType != null) { -+ Collections.addAll(typeParameterNames, typeParameterNamesFromReturnType); -+ } -+ } -+ -+ return typeParameterNames.isEmpty() -+ ? new TextResult("""") -+ : new TextResult("" <"" + StringUtil.join(typeParameterNames, "", "") + "">""); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ return new LookupElement[0]; // do not offer the user any choices -+ } -+ } -+ -+ /** -+ * A JetNameValidator that always succeeds. -+ */ -+ private static class DummyJetNameValidator implements JetNameValidator { -+ private final Project project; -+ -+ public DummyJetNameValidator(Project project) { -+ this.project = project; -+ } -+ -+ @Nullable -+ @Override -+ public String validateName(String name) { -+ return name; -+ } -+ -+ @Override -+ public Project getProject() { -+ return project; -+ } -+ } -+ -+ /** -+ * Encapsulates a single type substitution of a JetType by another JetType. -+ */ -+ private static class TypeSubstitution { -+ private final JetType forType; -+ private final JetType byType; -+ -+ private TypeSubstitution(JetType forType, JetType byType) { -+ this.forType = forType; -+ this.byType = byType; -+ } -+ -+ private JetType getForType() { -+ return forType; -+ } -+ -+ private JetType getByType() { -+ return byType; -+ } -+ } -+ -+ private final String methodName; -+ private final TypeOrExpressionThereof ownerType; -+ private final TypeOrExpressionThereof returnType; -+ private final List parameters; -+ -+ private boolean isUnit; -+ private boolean isExtension; -+ private JetFile currentFile; -+ private JetFile containingFile; -+ private Editor currentFileEditor; -+ private Editor containingFileEditor; -+ private BindingContext currentFileContext; -+ private JetClass ownerClass; -+ private ClassDescriptor ownerClassDescriptor; -+ private TypeCandidate selectedReceiverType; -+ private Map typeParameterNameMap; -+ -+ public CreateMethodFromUsageFix(@NotNull PsiElement element, @NotNull TypeOrExpressionThereof ownerType, @NotNull String methodName, -+ @NotNull TypeOrExpressionThereof returnType, @NotNull List parameters) { -+ super(element); -+ this.methodName = methodName; -+ this.ownerType = ownerType; -+ this.returnType = returnType; -+ this.parameters = parameters; -+ } -+ -+ @NotNull -+ @Override -+ public String getText() { -+ return JetBundle.message(""create.method.from.usage"", methodName); -+ } -+ -+ @Override -+ public void invoke(@NotNull final Project project, Editor editor, PsiFile file) throws IncorrectOperationException { -+ assert file != null && file instanceof JetFile; -+ currentFile = (JetFile) file; -+ currentFileEditor = editor; -+ currentFileContext = AnalyzerFacadeWithCache.analyzeFileWithCache(currentFile).getBindingContext(); -+ -+ ownerType.computeTypeCandidates(currentFileContext); -+ TypeCandidate[] ownerTypeCandidates = ownerType.getTypeCandidates(); -+ assert ownerTypeCandidates.length > 0; -+ if (ownerTypeCandidates.length == 1 || ApplicationManager.getApplication().isUnitTestMode()) { -+ selectedReceiverType = ownerTypeCandidates[0]; -+ doInvoke(project); -+ } else { -+ // class selection -+ List options = new ArrayList(); -+ final Map optionToTypeMap = new HashMap(); -+ for (TypeCandidate ownerTypeCandidate : ownerTypeCandidates) { -+ ClassifierDescriptor possibleClassDescriptor = ownerTypeCandidate.getType().getConstructor().getDeclarationDescriptor(); -+ if (possibleClassDescriptor != null) { -+ String className = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(possibleClassDescriptor.getDefaultType()); -+ DeclarationDescriptor namespaceDescriptor = possibleClassDescriptor.getContainingDeclaration(); -+ String namespace = renderDescriptor(namespaceDescriptor, true); -+ String option = className + "" ("" + namespace + "")""; -+ options.add(option); -+ optionToTypeMap.put(option, ownerTypeCandidate); -+ } -+ } -+ -+ final JList list = new JBList(options); -+ PsiElementListCellRenderer renderer = new JetLightClassListCellRenderer(); -+ list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); -+ list.setCellRenderer(renderer); -+ PopupChooserBuilder builder = new PopupChooserBuilder(list); -+ renderer.installSpeedSearch(builder); -+ -+ Runnable runnable = new Runnable() { -+ @Override -+ public void run() { -+ int index = list.getSelectedIndex(); -+ if (index < 0) return; -+ String option = (String) list.getSelectedValue(); -+ selectedReceiverType = optionToTypeMap.get(option); -+ CommandProcessor.getInstance().executeCommand(project, new Runnable() { -+ @Override -+ public void run() { -+ doInvoke(project); -+ } -+ }, getText(), null); -+ } -+ }; -+ -+ builder.setTitle(JetBundle.message(""choose.target.class.or.trait.title"")) -+ .setItemChoosenCallback(runnable) -+ .createPopup() -+ .showInBestPositionFor(currentFileEditor); -+ } -+ } -+ -+ private void doInvoke(@NotNull final Project project) { -+ // gather relevant information -+ ClassifierDescriptor ownerTypeDescriptor = selectedReceiverType.getType().getConstructor().getDeclarationDescriptor(); -+ assert ownerTypeDescriptor != null && ownerTypeDescriptor instanceof ClassDescriptor; -+ ownerClassDescriptor = (ClassDescriptor) ownerTypeDescriptor; -+ JetType receiverType = ownerClassDescriptor.getDefaultType(); -+ PsiElement typeDeclaration = BindingContextUtils.classDescriptorToDeclaration(currentFileContext, ownerClassDescriptor);","It's class declaration, not type declaration. Please rename. -",Why is this needed? Looks like a duplicate file. -100,"@@ -0,0 +1,1391 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.codeInsight.lookup.LookupElement; -+import com.intellij.codeInsight.lookup.LookupElementBuilder; -+import com.intellij.codeInsight.template.*; -+import com.intellij.codeInsight.template.impl.TemplateImpl; -+import com.intellij.codeInsight.template.impl.Variable; -+import com.intellij.ide.fileTemplates.FileTemplate; -+import com.intellij.ide.fileTemplates.FileTemplateManager; -+import com.intellij.ide.util.PsiElementListCellRenderer; -+import com.intellij.openapi.application.ApplicationManager; -+import com.intellij.openapi.command.CommandProcessor; -+import com.intellij.openapi.editor.CaretModel; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.fileEditor.FileEditorManager; -+import com.intellij.openapi.progress.ProcessCanceledException; -+import com.intellij.openapi.project.Project; -+import com.intellij.openapi.ui.popup.PopupChooserBuilder; -+import com.intellij.openapi.util.TextRange; -+import com.intellij.openapi.util.text.StringUtil; -+import com.intellij.openapi.vfs.VirtualFile; -+import com.intellij.psi.PsiDocumentManager; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.PsiReference; -+import com.intellij.psi.search.SearchScope; -+import com.intellij.psi.util.PsiTreeUtil; -+import com.intellij.refactoring.psi.SearchUtils; -+import com.intellij.ui.components.JBList; -+import com.intellij.util.ArrayUtil; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NonNls; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.descriptors.*; -+import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1; -+import org.jetbrains.jet.lang.diagnostics.Errors; -+import org.jetbrains.jet.lang.psi.*; -+import org.jetbrains.jet.lang.resolve.BindingContext; -+import org.jetbrains.jet.lang.resolve.BindingContextUtils; -+import org.jetbrains.jet.lang.resolve.DescriptorUtils; -+import org.jetbrains.jet.lang.resolve.name.Name; -+import org.jetbrains.jet.lang.resolve.scopes.JetScope; -+import org.jetbrains.jet.lang.types.*; -+import org.jetbrains.jet.lang.types.checker.JetTypeChecker; -+import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; -+import org.jetbrains.jet.plugin.JetBundle; -+import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening; -+import org.jetbrains.jet.plugin.presentation.JetLightClassListCellRenderer; -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; -+import org.jetbrains.jet.plugin.refactoring.JetNameSuggester; -+import org.jetbrains.jet.plugin.refactoring.JetNameValidator; -+import org.jetbrains.jet.plugin.references.JetSimpleNameReference; -+import org.jetbrains.jet.renderer.DescriptorRenderer; -+ -+import javax.swing.*; -+import java.util.*; -+import java.util.regex.Matcher; -+import java.util.regex.Pattern; -+ -+public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { -+ private static final String TYPE_PARAMETER_LIST_VARIABLE_NAME = ""typeParameterList""; -+ private static final String TEMPLATE_FROM_USAGE_METHOD_BODY = ""New Kotlin Method Body.kt""; -+ private static final Pattern COMPONENT_FUNCTION_PATTERN = Pattern.compile(""^component(\\d+)$""); -+ -+ /** -+ * Represents a single choice for a type (e.g. parameter type or return type). -+ */ -+ private static class TypeCandidate { -+ private final JetType type; -+ private final TypeParameterDescriptor[] typeParameters; -+ private String renderedType; -+ private String[] typeParameterNames; -+ -+ public TypeCandidate(@NotNull JetType type) { -+ this.type = type; -+ Set typeParametersInType = getTypeParametersInType(type); -+ typeParameters = typeParametersInType.toArray(new TypeParameterDescriptor[typeParametersInType.size()]); -+ renderedType = renderTypeShort(type, Collections.emptyMap()); -+ } -+ -+ public TypeCandidate(@NotNull JetType type, @NotNull JetScope scope) { -+ this.type = type; -+ typeParameters = getTypeParameterNamesNotInScope(getTypeParametersInType(type), scope); -+ } -+ -+ public void render(@NotNull Map typeParameterNameMap) { -+ renderedType = renderTypeShort(type, typeParameterNameMap); -+ typeParameterNames = new String[typeParameters.length]; -+ int i = 0; -+ for (TypeParameterDescriptor typeParameter : typeParameters) { -+ typeParameterNames[i] = typeParameterNameMap.get(typeParameter); -+ i++; -+ } -+ } -+ -+ @NotNull JetType getType() { -+ return type; -+ } -+ -+ @NotNull -+ public String getRenderedType() { -+ assert renderedType != null : ""call render() first""; -+ return renderedType; -+ } -+ -+ @NotNull -+ public String[] getTypeParameterNames() { -+ assert typeParameterNames != null : ""call render() first""; -+ return typeParameterNames; -+ } -+ -+ @NotNull -+ public TypeParameterDescriptor[] getTypeParameters() { -+ return typeParameters; -+ } -+ } -+ -+ /** -+ * Represents a concrete type or a set of types yet to be inferred from an expression. -+ */ -+ private static class TypeOrExpressionThereof { -+ private final JetExpression expressionOfType; -+ private final JetType type; -+ private final Variance variance; -+ private TypeCandidate[] typeCandidates; -+ private String[] cachedNameCandidatesFromExpression; -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType) { -+ this(expressionOfType, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType, Variance variance) { -+ this(expressionOfType, null, variance); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type) { -+ this(type, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type, Variance variance) { -+ this(null, type, variance); -+ } -+ -+ private TypeOrExpressionThereof(@Nullable JetExpression expressionOfType, @Nullable JetType type, Variance variance) { -+ this.expressionOfType = expressionOfType; -+ this.type = type; -+ this.variance = variance; -+ } -+ -+ public boolean isType() { -+ return this.type != null; -+ } -+ -+ @NotNull -+ public JetType getType() { -+ assert this.type != null; -+ return this.type; -+ } -+ -+ @NotNull -+ private List getPossibleTypes(BindingContext context) { -+ List types = new ArrayList(); -+ if (isType()) { -+ assert type != null : ""!isType() means type == null && expressionOfType != null""; -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ for (JetType type : guessTypeForExpression(expressionOfType, context)) { -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } -+ } -+ return types; -+ } -+ -+ public void computeTypeCandidates(@NotNull BindingContext context) { -+ Collection types = getPossibleTypes(context); -+ -+ typeCandidates = new TypeCandidate[types.size()]; -+ int i = 0; -+ for (JetType type : types) { -+ typeCandidates[i] = new TypeCandidate(type); -+ i++; -+ } -+ } -+ -+ public void computeTypeCandidates( -+ @NotNull BindingContext context, -+ @NotNull TypeSubstitution[] substitutions, -+ @NotNull JetScope scope -+ ) { -+ List types = getPossibleTypes(context); -+ Collections.reverse(types); // reverse and reverse back later, so that things added below are added at the front -+ -+ Set newTypes = new LinkedHashSet(types); -+ for (TypeSubstitution substitution : substitutions) { // each substitution can be applied or not, so we offer all options -+ List toAdd = new ArrayList(); -+ List toRemove = new ArrayList(); -+ for (JetType type : newTypes) { -+ toAdd.add(substituteType(type, substitution, variance)); -+ // substitution.byType are type arguments, but they cannot already occur in the type before substitution -+ if (containsType(type, substitution.getByType())) { -+ toRemove.add(type); -+ } -+ } -+ newTypes.addAll(toAdd); -+ newTypes.removeAll(toRemove); -+ } -+ -+ if (newTypes.isEmpty()) { -+ newTypes.add(KotlinBuiltIns.getInstance().getAnyType()); -+ } -+ -+ typeCandidates = new TypeCandidate[newTypes.size()]; -+ int i = typeCandidates.length - 1; // reverse order (see explanation above) -+ for (JetType type : newTypes) { -+ typeCandidates[i] = new TypeCandidate(type, scope); -+ i--; -+ } -+ } -+ -+ @NotNull -+ public TypeCandidate[] getTypeCandidates() { -+ assert typeCandidates != null : ""call computeTypeCandidates() first""; -+ return typeCandidates; -+ } -+ -+ public void renderTypeCandidates(@NotNull Map typeParameterNameMap) { -+ for (TypeCandidate candidate : typeCandidates) { -+ candidate.render(typeParameterNameMap); -+ } -+ } -+ -+ @NotNull -+ public String[] getPossibleNamesFromExpression() { -+ if (cachedNameCandidatesFromExpression != null) return cachedNameCandidatesFromExpression; -+ if (isType()) { -+ cachedNameCandidatesFromExpression = ArrayUtil.EMPTY_STRING_ARRAY; -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ JetNameValidator dummyValidator = new DummyJetNameValidator(expressionOfType.getProject()); -+ cachedNameCandidatesFromExpression = JetNameSuggester.suggestNamesForExpression(expressionOfType, dummyValidator); -+ } -+ return cachedNameCandidatesFromExpression; -+ } -+ } -+ -+ /** -+ * Encapsulates information about a method parameter that is going to be created. -+ */ -+ private static class Parameter { -+ private final String preferredName; -+ private final TypeOrExpressionThereof type; -+ -+ public Parameter(@Nullable(""no preferred name"") String preferredName, TypeOrExpressionThereof type) { -+ this.preferredName = preferredName; -+ this.type = type; -+ } -+ -+ public String getPreferredName() { -+ return preferredName; -+ } -+ -+ public TypeOrExpressionThereof getType() { -+ return type; -+ } -+ } -+ -+ /** -+ * Special Expression for parameter names based on its type. -+ */ -+ private static class ParameterNameExpression extends Expression { -+ private final String[] names; -+ private final Map parameterTypeToNamesMap; -+ -+ public ParameterNameExpression(@NotNull String[] names, @NotNull Map parameterTypeToNamesMap) { -+ for (String name : names) { -+ assert name != null && !name.isEmpty(); -+ } -+ this.names = names; -+ this.parameterTypeToNamesMap = parameterTypeToNamesMap; -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ LookupElement[] lookupItems = calculateLookupItems(context); -+ if (lookupItems.length == 0) return new TextResult(""""); -+ -+ return new TextResult(lookupItems[0].getLookupString()); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ Set names = new LinkedHashSet(); -+ Collections.addAll(names, this.names); -+ -+ // find the parameter list -+ Project project = context.getProject(); -+ int offset = context.getStartOffset(); -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ Editor editor = context.getEditor(); -+ assert editor != null; -+ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); -+ assert file != null && file instanceof JetFile; -+ PsiElement elementAt = file.findElementAt(offset); -+ JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); -+ if (func == null) return new LookupElement[0]; -+ JetParameterList parameterList = func.getValueParameterList(); -+ assert parameterList != null; -+ -+ // add names based on selected type -+ JetParameter parameter = PsiTreeUtil.getParentOfType(elementAt, JetParameter.class); -+ if (parameter != null) { -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ String[] suggestedNamesBasedOnType = parameterTypeToNamesMap.get(parameterTypeRef.getText()); -+ if (suggestedNamesBasedOnType != null) { -+ Collections.addAll(names, suggestedNamesBasedOnType); -+ } -+ } -+ } -+ -+ // remember other parameter names for later use -+ Set parameterNames = new HashSet(); -+ for (JetParameter jetParameter : parameterList.getParameters()) { -+ if (jetParameter == parameter || jetParameter.getName() == null) continue; -+ parameterNames.add(jetParameter.getName()); -+ } -+ -+ // add fallback parameter name -+ if (names.isEmpty()) { -+ names.add(""arg""); -+ } -+ -+ // ensure there are no conflicts -+ List lookupElements = new ArrayList(); -+ for (String name : names) { -+ name = getNextAvailableName(name, parameterNames); -+ lookupElements.add(LookupElementBuilder.create(name)); -+ } -+ -+ // create and return -+ return lookupElements.toArray(new LookupElement[lookupElements.size()]); -+ } -+ } -+ -+ /** -+ * An Expression for type references. -+ */ -+ private static class TypeExpression extends Expression { -+ private final TypeOrExpressionThereof type; -+ private @NotNull LookupElement[] cachedLookupElements; -+ -+ public TypeExpression(@NotNull TypeOrExpressionThereof type) { -+ this.type = type; -+ TypeCandidate[] candidates = type.getTypeCandidates(); -+ cachedLookupElements = new LookupElement[candidates.length]; -+ for (int i = 0; i < candidates.length; i++) { -+ cachedLookupElements[i] = LookupElementBuilder.create(candidates[i], candidates[i].getRenderedType()); -+ } -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ LookupElement[] lookupItems = calculateLookupItems(context); -+ if (lookupItems.length == 0) return new TextResult(""""); -+ -+ return new TextResult(lookupItems[0].getLookupString()); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ return cachedLookupElements; -+ } -+ -+ @NotNull -+ public TypeOrExpressionThereof getType() { -+ return type; -+ } -+ -+ @Nullable(""can't be found"") -+ public JetType getTypeFromSelection(@NotNull String selection) { -+ TypeCandidate[] options = type.getTypeCandidates(); -+ for (TypeCandidate option : options) { -+ if (option.getRenderedType().equals(selection)) { -+ return option.getType(); -+ } -+ } -+ return null; -+ } -+ } -+ -+ /** -+ * A sort-of dummy Expression for parameter lists, to allow us to update the parameter list as the user makes selections. -+ */ -+ private static class TypeParameterListExpression extends Expression { -+ private final String[] typeParameterNamesFromReceiverType; -+ private final Map parameterTypeToTypeParameterNamesMap; -+ -+ public TypeParameterListExpression( -+ @NotNull String[] typeParameterNamesFromReceiverType, -+ @NotNull Map typeParametersMap -+ ) { -+ this.typeParameterNamesFromReceiverType = typeParameterNamesFromReceiverType; -+ this.parameterTypeToTypeParameterNamesMap = typeParametersMap; -+ } -+ -+ @NotNull -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ Project project = context.getProject(); -+ int offset = context.getStartOffset(); -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ Editor editor = context.getEditor(); -+ assert editor != null; -+ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); -+ assert file != null && file instanceof JetFile; -+ PsiElement elementAt = file.findElementAt(offset); -+ JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); -+ if (func == null) { -+ return new TextResult(""""); -+ } -+ List parameters = func.getValueParameters(); -+ -+ Set typeParameterNames = new LinkedHashSet(); -+ Collections.addAll(typeParameterNames, typeParameterNamesFromReceiverType); -+ for (JetParameter parameter : parameters) { -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ String[] typeParameterNamesFromParameter = parameterTypeToTypeParameterNamesMap.get(parameterTypeRef.getText()); -+ if (typeParameterNamesFromParameter != null) { -+ Collections.addAll(typeParameterNames, typeParameterNamesFromParameter); -+ } -+ } -+ } -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ if (returnTypeRef != null) { -+ String[] typeParameterNamesFromReturnType = parameterTypeToTypeParameterNamesMap.get(returnTypeRef.getText()); -+ if (typeParameterNamesFromReturnType != null) { -+ Collections.addAll(typeParameterNames, typeParameterNamesFromReturnType); -+ } -+ } -+ -+ return typeParameterNames.isEmpty() -+ ? new TextResult("""") -+ : new TextResult("" <"" + StringUtil.join(typeParameterNames, "", "") + "">""); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ return new LookupElement[0]; // do not offer the user any choices -+ } -+ } -+ -+ /** -+ * A JetNameValidator that always succeeds. -+ */ -+ private static class DummyJetNameValidator implements JetNameValidator { -+ private final Project project; -+ -+ public DummyJetNameValidator(Project project) { -+ this.project = project; -+ } -+ -+ @Nullable -+ @Override -+ public String validateName(String name) { -+ return name; -+ } -+ -+ @Override -+ public Project getProject() { -+ return project; -+ } -+ } -+ -+ /** -+ * Encapsulates a single type substitution of a JetType by another JetType. -+ */ -+ private static class TypeSubstitution { -+ private final JetType forType; -+ private final JetType byType; -+ -+ private TypeSubstitution(JetType forType, JetType byType) { -+ this.forType = forType; -+ this.byType = byType; -+ } -+ -+ private JetType getForType() { -+ return forType; -+ } -+ -+ private JetType getByType() { -+ return byType; -+ } -+ } -+ -+ private final String methodName; -+ private final TypeOrExpressionThereof ownerType; -+ private final TypeOrExpressionThereof returnType; -+ private final List parameters; -+ -+ private boolean isUnit; -+ private boolean isExtension; -+ private JetFile currentFile; -+ private JetFile containingFile; -+ private Editor currentFileEditor; -+ private Editor containingFileEditor; -+ private BindingContext currentFileContext; -+ private JetClass ownerClass; -+ private ClassDescriptor ownerClassDescriptor; -+ private TypeCandidate selectedReceiverType; -+ private Map typeParameterNameMap; -+ -+ public CreateMethodFromUsageFix(@NotNull PsiElement element, @NotNull TypeOrExpressionThereof ownerType, @NotNull String methodName, -+ @NotNull TypeOrExpressionThereof returnType, @NotNull List parameters) { -+ super(element); -+ this.methodName = methodName; -+ this.ownerType = ownerType; -+ this.returnType = returnType; -+ this.parameters = parameters; -+ } -+ -+ @NotNull -+ @Override -+ public String getText() { -+ return JetBundle.message(""create.method.from.usage"", methodName); -+ } -+ -+ @Override -+ public void invoke(@NotNull final Project project, Editor editor, PsiFile file) throws IncorrectOperationException { -+ assert file != null && file instanceof JetFile; -+ currentFile = (JetFile) file; -+ currentFileEditor = editor; -+ currentFileContext = AnalyzerFacadeWithCache.analyzeFileWithCache(currentFile).getBindingContext(); -+ -+ ownerType.computeTypeCandidates(currentFileContext); -+ TypeCandidate[] ownerTypeCandidates = ownerType.getTypeCandidates(); -+ assert ownerTypeCandidates.length > 0; -+ if (ownerTypeCandidates.length == 1 || ApplicationManager.getApplication().isUnitTestMode()) { -+ selectedReceiverType = ownerTypeCandidates[0]; -+ doInvoke(project); -+ } else { -+ // class selection -+ List options = new ArrayList(); -+ final Map optionToTypeMap = new HashMap(); -+ for (TypeCandidate ownerTypeCandidate : ownerTypeCandidates) { -+ ClassifierDescriptor possibleClassDescriptor = ownerTypeCandidate.getType().getConstructor().getDeclarationDescriptor(); -+ if (possibleClassDescriptor != null) { -+ String className = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(possibleClassDescriptor.getDefaultType()); -+ DeclarationDescriptor namespaceDescriptor = possibleClassDescriptor.getContainingDeclaration(); -+ String namespace = renderDescriptor(namespaceDescriptor, true); -+ String option = className + "" ("" + namespace + "")""; -+ options.add(option); -+ optionToTypeMap.put(option, ownerTypeCandidate); -+ } -+ } -+ -+ final JList list = new JBList(options); -+ PsiElementListCellRenderer renderer = new JetLightClassListCellRenderer(); -+ list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); -+ list.setCellRenderer(renderer); -+ PopupChooserBuilder builder = new PopupChooserBuilder(list); -+ renderer.installSpeedSearch(builder); -+ -+ Runnable runnable = new Runnable() { -+ @Override -+ public void run() { -+ int index = list.getSelectedIndex(); -+ if (index < 0) return; -+ String option = (String) list.getSelectedValue(); -+ selectedReceiverType = optionToTypeMap.get(option); -+ CommandProcessor.getInstance().executeCommand(project, new Runnable() { -+ @Override -+ public void run() { -+ doInvoke(project); -+ } -+ }, getText(), null); -+ } -+ }; -+ -+ builder.setTitle(JetBundle.message(""choose.target.class.or.trait.title"")) -+ .setItemChoosenCallback(runnable) -+ .createPopup() -+ .showInBestPositionFor(currentFileEditor); -+ } -+ } -+ -+ private void doInvoke(@NotNull final Project project) { -+ // gather relevant information -+ ClassifierDescriptor ownerTypeDescriptor = selectedReceiverType.getType().getConstructor().getDeclarationDescriptor(); -+ assert ownerTypeDescriptor != null && ownerTypeDescriptor instanceof ClassDescriptor; -+ ownerClassDescriptor = (ClassDescriptor) ownerTypeDescriptor; -+ JetType receiverType = ownerClassDescriptor.getDefaultType(); -+ PsiElement typeDeclaration = BindingContextUtils.classDescriptorToDeclaration(currentFileContext, ownerClassDescriptor); -+ if (typeDeclaration != null && typeDeclaration instanceof JetClass) {","Checking for null is redundant when checking for `instanceof`. -",Why is this needed? Looks like a duplicate file. -101,"@@ -0,0 +1,1391 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.codeInsight.lookup.LookupElement; -+import com.intellij.codeInsight.lookup.LookupElementBuilder; -+import com.intellij.codeInsight.template.*; -+import com.intellij.codeInsight.template.impl.TemplateImpl; -+import com.intellij.codeInsight.template.impl.Variable; -+import com.intellij.ide.fileTemplates.FileTemplate; -+import com.intellij.ide.fileTemplates.FileTemplateManager; -+import com.intellij.ide.util.PsiElementListCellRenderer; -+import com.intellij.openapi.application.ApplicationManager; -+import com.intellij.openapi.command.CommandProcessor; -+import com.intellij.openapi.editor.CaretModel; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.fileEditor.FileEditorManager; -+import com.intellij.openapi.progress.ProcessCanceledException; -+import com.intellij.openapi.project.Project; -+import com.intellij.openapi.ui.popup.PopupChooserBuilder; -+import com.intellij.openapi.util.TextRange; -+import com.intellij.openapi.util.text.StringUtil; -+import com.intellij.openapi.vfs.VirtualFile; -+import com.intellij.psi.PsiDocumentManager; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.PsiReference; -+import com.intellij.psi.search.SearchScope; -+import com.intellij.psi.util.PsiTreeUtil; -+import com.intellij.refactoring.psi.SearchUtils; -+import com.intellij.ui.components.JBList; -+import com.intellij.util.ArrayUtil; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NonNls; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.descriptors.*; -+import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1; -+import org.jetbrains.jet.lang.diagnostics.Errors; -+import org.jetbrains.jet.lang.psi.*; -+import org.jetbrains.jet.lang.resolve.BindingContext; -+import org.jetbrains.jet.lang.resolve.BindingContextUtils; -+import org.jetbrains.jet.lang.resolve.DescriptorUtils; -+import org.jetbrains.jet.lang.resolve.name.Name; -+import org.jetbrains.jet.lang.resolve.scopes.JetScope; -+import org.jetbrains.jet.lang.types.*; -+import org.jetbrains.jet.lang.types.checker.JetTypeChecker; -+import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; -+import org.jetbrains.jet.plugin.JetBundle; -+import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening; -+import org.jetbrains.jet.plugin.presentation.JetLightClassListCellRenderer; -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; -+import org.jetbrains.jet.plugin.refactoring.JetNameSuggester; -+import org.jetbrains.jet.plugin.refactoring.JetNameValidator; -+import org.jetbrains.jet.plugin.references.JetSimpleNameReference; -+import org.jetbrains.jet.renderer.DescriptorRenderer; -+ -+import javax.swing.*; -+import java.util.*; -+import java.util.regex.Matcher; -+import java.util.regex.Pattern; -+ -+public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { -+ private static final String TYPE_PARAMETER_LIST_VARIABLE_NAME = ""typeParameterList""; -+ private static final String TEMPLATE_FROM_USAGE_METHOD_BODY = ""New Kotlin Method Body.kt""; -+ private static final Pattern COMPONENT_FUNCTION_PATTERN = Pattern.compile(""^component(\\d+)$""); -+ -+ /** -+ * Represents a single choice for a type (e.g. parameter type or return type). -+ */ -+ private static class TypeCandidate { -+ private final JetType type; -+ private final TypeParameterDescriptor[] typeParameters; -+ private String renderedType; -+ private String[] typeParameterNames; -+ -+ public TypeCandidate(@NotNull JetType type) { -+ this.type = type; -+ Set typeParametersInType = getTypeParametersInType(type); -+ typeParameters = typeParametersInType.toArray(new TypeParameterDescriptor[typeParametersInType.size()]); -+ renderedType = renderTypeShort(type, Collections.emptyMap()); -+ } -+ -+ public TypeCandidate(@NotNull JetType type, @NotNull JetScope scope) { -+ this.type = type; -+ typeParameters = getTypeParameterNamesNotInScope(getTypeParametersInType(type), scope); -+ } -+ -+ public void render(@NotNull Map typeParameterNameMap) { -+ renderedType = renderTypeShort(type, typeParameterNameMap); -+ typeParameterNames = new String[typeParameters.length]; -+ int i = 0; -+ for (TypeParameterDescriptor typeParameter : typeParameters) { -+ typeParameterNames[i] = typeParameterNameMap.get(typeParameter); -+ i++; -+ } -+ } -+ -+ @NotNull JetType getType() { -+ return type; -+ } -+ -+ @NotNull -+ public String getRenderedType() { -+ assert renderedType != null : ""call render() first""; -+ return renderedType; -+ } -+ -+ @NotNull -+ public String[] getTypeParameterNames() { -+ assert typeParameterNames != null : ""call render() first""; -+ return typeParameterNames; -+ } -+ -+ @NotNull -+ public TypeParameterDescriptor[] getTypeParameters() { -+ return typeParameters; -+ } -+ } -+ -+ /** -+ * Represents a concrete type or a set of types yet to be inferred from an expression. -+ */ -+ private static class TypeOrExpressionThereof { -+ private final JetExpression expressionOfType; -+ private final JetType type; -+ private final Variance variance; -+ private TypeCandidate[] typeCandidates; -+ private String[] cachedNameCandidatesFromExpression; -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType) { -+ this(expressionOfType, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType, Variance variance) { -+ this(expressionOfType, null, variance); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type) { -+ this(type, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type, Variance variance) { -+ this(null, type, variance); -+ } -+ -+ private TypeOrExpressionThereof(@Nullable JetExpression expressionOfType, @Nullable JetType type, Variance variance) { -+ this.expressionOfType = expressionOfType; -+ this.type = type; -+ this.variance = variance; -+ } -+ -+ public boolean isType() { -+ return this.type != null; -+ } -+ -+ @NotNull -+ public JetType getType() { -+ assert this.type != null; -+ return this.type; -+ } -+ -+ @NotNull -+ private List getPossibleTypes(BindingContext context) { -+ List types = new ArrayList(); -+ if (isType()) { -+ assert type != null : ""!isType() means type == null && expressionOfType != null""; -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ for (JetType type : guessTypeForExpression(expressionOfType, context)) { -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } -+ } -+ return types; -+ } -+ -+ public void computeTypeCandidates(@NotNull BindingContext context) { -+ Collection types = getPossibleTypes(context); -+ -+ typeCandidates = new TypeCandidate[types.size()]; -+ int i = 0; -+ for (JetType type : types) { -+ typeCandidates[i] = new TypeCandidate(type); -+ i++; -+ } -+ } -+ -+ public void computeTypeCandidates( -+ @NotNull BindingContext context, -+ @NotNull TypeSubstitution[] substitutions, -+ @NotNull JetScope scope -+ ) { -+ List types = getPossibleTypes(context); -+ Collections.reverse(types); // reverse and reverse back later, so that things added below are added at the front -+ -+ Set newTypes = new LinkedHashSet(types); -+ for (TypeSubstitution substitution : substitutions) { // each substitution can be applied or not, so we offer all options -+ List toAdd = new ArrayList(); -+ List toRemove = new ArrayList(); -+ for (JetType type : newTypes) { -+ toAdd.add(substituteType(type, substitution, variance)); -+ // substitution.byType are type arguments, but they cannot already occur in the type before substitution -+ if (containsType(type, substitution.getByType())) { -+ toRemove.add(type); -+ } -+ } -+ newTypes.addAll(toAdd); -+ newTypes.removeAll(toRemove); -+ } -+ -+ if (newTypes.isEmpty()) { -+ newTypes.add(KotlinBuiltIns.getInstance().getAnyType()); -+ } -+ -+ typeCandidates = new TypeCandidate[newTypes.size()]; -+ int i = typeCandidates.length - 1; // reverse order (see explanation above) -+ for (JetType type : newTypes) { -+ typeCandidates[i] = new TypeCandidate(type, scope); -+ i--; -+ } -+ } -+ -+ @NotNull -+ public TypeCandidate[] getTypeCandidates() { -+ assert typeCandidates != null : ""call computeTypeCandidates() first""; -+ return typeCandidates; -+ } -+ -+ public void renderTypeCandidates(@NotNull Map typeParameterNameMap) { -+ for (TypeCandidate candidate : typeCandidates) { -+ candidate.render(typeParameterNameMap); -+ } -+ } -+ -+ @NotNull -+ public String[] getPossibleNamesFromExpression() { -+ if (cachedNameCandidatesFromExpression != null) return cachedNameCandidatesFromExpression; -+ if (isType()) { -+ cachedNameCandidatesFromExpression = ArrayUtil.EMPTY_STRING_ARRAY; -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ JetNameValidator dummyValidator = new DummyJetNameValidator(expressionOfType.getProject()); -+ cachedNameCandidatesFromExpression = JetNameSuggester.suggestNamesForExpression(expressionOfType, dummyValidator); -+ } -+ return cachedNameCandidatesFromExpression; -+ } -+ } -+ -+ /** -+ * Encapsulates information about a method parameter that is going to be created. -+ */ -+ private static class Parameter { -+ private final String preferredName; -+ private final TypeOrExpressionThereof type; -+ -+ public Parameter(@Nullable(""no preferred name"") String preferredName, TypeOrExpressionThereof type) { -+ this.preferredName = preferredName; -+ this.type = type; -+ } -+ -+ public String getPreferredName() { -+ return preferredName; -+ } -+ -+ public TypeOrExpressionThereof getType() { -+ return type; -+ } -+ } -+ -+ /** -+ * Special Expression for parameter names based on its type. -+ */ -+ private static class ParameterNameExpression extends Expression { -+ private final String[] names; -+ private final Map parameterTypeToNamesMap; -+ -+ public ParameterNameExpression(@NotNull String[] names, @NotNull Map parameterTypeToNamesMap) { -+ for (String name : names) { -+ assert name != null && !name.isEmpty(); -+ } -+ this.names = names; -+ this.parameterTypeToNamesMap = parameterTypeToNamesMap; -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ LookupElement[] lookupItems = calculateLookupItems(context); -+ if (lookupItems.length == 0) return new TextResult(""""); -+ -+ return new TextResult(lookupItems[0].getLookupString()); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ Set names = new LinkedHashSet(); -+ Collections.addAll(names, this.names); -+ -+ // find the parameter list -+ Project project = context.getProject(); -+ int offset = context.getStartOffset(); -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ Editor editor = context.getEditor(); -+ assert editor != null; -+ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); -+ assert file != null && file instanceof JetFile; -+ PsiElement elementAt = file.findElementAt(offset); -+ JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); -+ if (func == null) return new LookupElement[0]; -+ JetParameterList parameterList = func.getValueParameterList(); -+ assert parameterList != null; -+ -+ // add names based on selected type -+ JetParameter parameter = PsiTreeUtil.getParentOfType(elementAt, JetParameter.class); -+ if (parameter != null) { -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ String[] suggestedNamesBasedOnType = parameterTypeToNamesMap.get(parameterTypeRef.getText()); -+ if (suggestedNamesBasedOnType != null) { -+ Collections.addAll(names, suggestedNamesBasedOnType); -+ } -+ } -+ } -+ -+ // remember other parameter names for later use -+ Set parameterNames = new HashSet(); -+ for (JetParameter jetParameter : parameterList.getParameters()) { -+ if (jetParameter == parameter || jetParameter.getName() == null) continue; -+ parameterNames.add(jetParameter.getName()); -+ } -+ -+ // add fallback parameter name -+ if (names.isEmpty()) { -+ names.add(""arg""); -+ } -+ -+ // ensure there are no conflicts -+ List lookupElements = new ArrayList(); -+ for (String name : names) { -+ name = getNextAvailableName(name, parameterNames); -+ lookupElements.add(LookupElementBuilder.create(name)); -+ } -+ -+ // create and return -+ return lookupElements.toArray(new LookupElement[lookupElements.size()]); -+ } -+ } -+ -+ /** -+ * An Expression for type references. -+ */ -+ private static class TypeExpression extends Expression { -+ private final TypeOrExpressionThereof type; -+ private @NotNull LookupElement[] cachedLookupElements; -+ -+ public TypeExpression(@NotNull TypeOrExpressionThereof type) { -+ this.type = type; -+ TypeCandidate[] candidates = type.getTypeCandidates(); -+ cachedLookupElements = new LookupElement[candidates.length]; -+ for (int i = 0; i < candidates.length; i++) { -+ cachedLookupElements[i] = LookupElementBuilder.create(candidates[i], candidates[i].getRenderedType()); -+ } -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ LookupElement[] lookupItems = calculateLookupItems(context); -+ if (lookupItems.length == 0) return new TextResult(""""); -+ -+ return new TextResult(lookupItems[0].getLookupString()); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ return cachedLookupElements; -+ } -+ -+ @NotNull -+ public TypeOrExpressionThereof getType() { -+ return type; -+ } -+ -+ @Nullable(""can't be found"") -+ public JetType getTypeFromSelection(@NotNull String selection) { -+ TypeCandidate[] options = type.getTypeCandidates(); -+ for (TypeCandidate option : options) { -+ if (option.getRenderedType().equals(selection)) { -+ return option.getType(); -+ } -+ } -+ return null; -+ } -+ } -+ -+ /** -+ * A sort-of dummy Expression for parameter lists, to allow us to update the parameter list as the user makes selections. -+ */ -+ private static class TypeParameterListExpression extends Expression { -+ private final String[] typeParameterNamesFromReceiverType; -+ private final Map parameterTypeToTypeParameterNamesMap; -+ -+ public TypeParameterListExpression( -+ @NotNull String[] typeParameterNamesFromReceiverType, -+ @NotNull Map typeParametersMap -+ ) { -+ this.typeParameterNamesFromReceiverType = typeParameterNamesFromReceiverType; -+ this.parameterTypeToTypeParameterNamesMap = typeParametersMap; -+ } -+ -+ @NotNull -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ Project project = context.getProject(); -+ int offset = context.getStartOffset(); -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ Editor editor = context.getEditor(); -+ assert editor != null; -+ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); -+ assert file != null && file instanceof JetFile; -+ PsiElement elementAt = file.findElementAt(offset); -+ JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); -+ if (func == null) { -+ return new TextResult(""""); -+ } -+ List parameters = func.getValueParameters(); -+ -+ Set typeParameterNames = new LinkedHashSet(); -+ Collections.addAll(typeParameterNames, typeParameterNamesFromReceiverType); -+ for (JetParameter parameter : parameters) { -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ String[] typeParameterNamesFromParameter = parameterTypeToTypeParameterNamesMap.get(parameterTypeRef.getText()); -+ if (typeParameterNamesFromParameter != null) { -+ Collections.addAll(typeParameterNames, typeParameterNamesFromParameter); -+ } -+ } -+ } -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ if (returnTypeRef != null) { -+ String[] typeParameterNamesFromReturnType = parameterTypeToTypeParameterNamesMap.get(returnTypeRef.getText()); -+ if (typeParameterNamesFromReturnType != null) { -+ Collections.addAll(typeParameterNames, typeParameterNamesFromReturnType); -+ } -+ } -+ -+ return typeParameterNames.isEmpty() -+ ? new TextResult("""") -+ : new TextResult("" <"" + StringUtil.join(typeParameterNames, "", "") + "">""); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ return new LookupElement[0]; // do not offer the user any choices -+ } -+ } -+ -+ /** -+ * A JetNameValidator that always succeeds. -+ */ -+ private static class DummyJetNameValidator implements JetNameValidator { -+ private final Project project; -+ -+ public DummyJetNameValidator(Project project) { -+ this.project = project; -+ } -+ -+ @Nullable -+ @Override -+ public String validateName(String name) { -+ return name; -+ } -+ -+ @Override -+ public Project getProject() { -+ return project; -+ } -+ } -+ -+ /** -+ * Encapsulates a single type substitution of a JetType by another JetType. -+ */ -+ private static class TypeSubstitution { -+ private final JetType forType; -+ private final JetType byType; -+ -+ private TypeSubstitution(JetType forType, JetType byType) { -+ this.forType = forType; -+ this.byType = byType; -+ } -+ -+ private JetType getForType() { -+ return forType; -+ } -+ -+ private JetType getByType() { -+ return byType; -+ } -+ } -+ -+ private final String methodName; -+ private final TypeOrExpressionThereof ownerType; -+ private final TypeOrExpressionThereof returnType; -+ private final List parameters; -+ -+ private boolean isUnit; -+ private boolean isExtension; -+ private JetFile currentFile; -+ private JetFile containingFile; -+ private Editor currentFileEditor; -+ private Editor containingFileEditor; -+ private BindingContext currentFileContext; -+ private JetClass ownerClass; -+ private ClassDescriptor ownerClassDescriptor; -+ private TypeCandidate selectedReceiverType; -+ private Map typeParameterNameMap; -+ -+ public CreateMethodFromUsageFix(@NotNull PsiElement element, @NotNull TypeOrExpressionThereof ownerType, @NotNull String methodName, -+ @NotNull TypeOrExpressionThereof returnType, @NotNull List parameters) { -+ super(element); -+ this.methodName = methodName; -+ this.ownerType = ownerType; -+ this.returnType = returnType; -+ this.parameters = parameters; -+ } -+ -+ @NotNull -+ @Override -+ public String getText() { -+ return JetBundle.message(""create.method.from.usage"", methodName); -+ } -+ -+ @Override -+ public void invoke(@NotNull final Project project, Editor editor, PsiFile file) throws IncorrectOperationException { -+ assert file != null && file instanceof JetFile; -+ currentFile = (JetFile) file; -+ currentFileEditor = editor; -+ currentFileContext = AnalyzerFacadeWithCache.analyzeFileWithCache(currentFile).getBindingContext(); -+ -+ ownerType.computeTypeCandidates(currentFileContext); -+ TypeCandidate[] ownerTypeCandidates = ownerType.getTypeCandidates(); -+ assert ownerTypeCandidates.length > 0; -+ if (ownerTypeCandidates.length == 1 || ApplicationManager.getApplication().isUnitTestMode()) { -+ selectedReceiverType = ownerTypeCandidates[0]; -+ doInvoke(project); -+ } else { -+ // class selection -+ List options = new ArrayList(); -+ final Map optionToTypeMap = new HashMap(); -+ for (TypeCandidate ownerTypeCandidate : ownerTypeCandidates) { -+ ClassifierDescriptor possibleClassDescriptor = ownerTypeCandidate.getType().getConstructor().getDeclarationDescriptor(); -+ if (possibleClassDescriptor != null) { -+ String className = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(possibleClassDescriptor.getDefaultType()); -+ DeclarationDescriptor namespaceDescriptor = possibleClassDescriptor.getContainingDeclaration(); -+ String namespace = renderDescriptor(namespaceDescriptor, true); -+ String option = className + "" ("" + namespace + "")""; -+ options.add(option); -+ optionToTypeMap.put(option, ownerTypeCandidate); -+ } -+ } -+ -+ final JList list = new JBList(options); -+ PsiElementListCellRenderer renderer = new JetLightClassListCellRenderer(); -+ list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); -+ list.setCellRenderer(renderer); -+ PopupChooserBuilder builder = new PopupChooserBuilder(list); -+ renderer.installSpeedSearch(builder); -+ -+ Runnable runnable = new Runnable() { -+ @Override -+ public void run() { -+ int index = list.getSelectedIndex(); -+ if (index < 0) return; -+ String option = (String) list.getSelectedValue(); -+ selectedReceiverType = optionToTypeMap.get(option); -+ CommandProcessor.getInstance().executeCommand(project, new Runnable() { -+ @Override -+ public void run() { -+ doInvoke(project); -+ } -+ }, getText(), null); -+ } -+ }; -+ -+ builder.setTitle(JetBundle.message(""choose.target.class.or.trait.title"")) -+ .setItemChoosenCallback(runnable) -+ .createPopup() -+ .showInBestPositionFor(currentFileEditor); -+ } -+ } -+ -+ private void doInvoke(@NotNull final Project project) { -+ // gather relevant information -+ ClassifierDescriptor ownerTypeDescriptor = selectedReceiverType.getType().getConstructor().getDeclarationDescriptor(); -+ assert ownerTypeDescriptor != null && ownerTypeDescriptor instanceof ClassDescriptor; -+ ownerClassDescriptor = (ClassDescriptor) ownerTypeDescriptor; -+ JetType receiverType = ownerClassDescriptor.getDefaultType(); -+ PsiElement typeDeclaration = BindingContextUtils.classDescriptorToDeclaration(currentFileContext, ownerClassDescriptor); -+ if (typeDeclaration != null && typeDeclaration instanceof JetClass) { -+ ownerClass = (JetClass) typeDeclaration; -+ isExtension = !ownerClass.isWritable(); -+ } else { -+ isExtension = true; -+ } -+ isUnit = returnType.isType() && isUnit(returnType.getType()); -+ -+ JetScope scope; -+ if (isExtension) { -+ NamespaceDescriptor namespaceDescriptor = currentFileContext.get(BindingContext.FILE_TO_NAMESPACE, currentFile); -+ assert namespaceDescriptor != null; -+ scope = namespaceDescriptor.getMemberScope(); -+ } else { -+ assert ownerClassDescriptor instanceof MutableClassDescriptor; -+ scope = ((MutableClassDescriptor) ownerClassDescriptor).getScopeForMemberResolution();","This code relies on implementation details. What if actual type of `ownerClassDescriptor` is `LazyClassDescriptor`? Replace it with `receiverType.getMemberScope()` -",Why is this needed? Looks like a duplicate file. -102,"@@ -0,0 +1,1391 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.codeInsight.lookup.LookupElement; -+import com.intellij.codeInsight.lookup.LookupElementBuilder; -+import com.intellij.codeInsight.template.*; -+import com.intellij.codeInsight.template.impl.TemplateImpl; -+import com.intellij.codeInsight.template.impl.Variable; -+import com.intellij.ide.fileTemplates.FileTemplate; -+import com.intellij.ide.fileTemplates.FileTemplateManager; -+import com.intellij.ide.util.PsiElementListCellRenderer; -+import com.intellij.openapi.application.ApplicationManager; -+import com.intellij.openapi.command.CommandProcessor; -+import com.intellij.openapi.editor.CaretModel; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.fileEditor.FileEditorManager; -+import com.intellij.openapi.progress.ProcessCanceledException; -+import com.intellij.openapi.project.Project; -+import com.intellij.openapi.ui.popup.PopupChooserBuilder; -+import com.intellij.openapi.util.TextRange; -+import com.intellij.openapi.util.text.StringUtil; -+import com.intellij.openapi.vfs.VirtualFile; -+import com.intellij.psi.PsiDocumentManager; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.PsiReference; -+import com.intellij.psi.search.SearchScope; -+import com.intellij.psi.util.PsiTreeUtil; -+import com.intellij.refactoring.psi.SearchUtils; -+import com.intellij.ui.components.JBList; -+import com.intellij.util.ArrayUtil; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NonNls; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.descriptors.*; -+import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1; -+import org.jetbrains.jet.lang.diagnostics.Errors; -+import org.jetbrains.jet.lang.psi.*; -+import org.jetbrains.jet.lang.resolve.BindingContext; -+import org.jetbrains.jet.lang.resolve.BindingContextUtils; -+import org.jetbrains.jet.lang.resolve.DescriptorUtils; -+import org.jetbrains.jet.lang.resolve.name.Name; -+import org.jetbrains.jet.lang.resolve.scopes.JetScope; -+import org.jetbrains.jet.lang.types.*; -+import org.jetbrains.jet.lang.types.checker.JetTypeChecker; -+import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; -+import org.jetbrains.jet.plugin.JetBundle; -+import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening; -+import org.jetbrains.jet.plugin.presentation.JetLightClassListCellRenderer; -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; -+import org.jetbrains.jet.plugin.refactoring.JetNameSuggester; -+import org.jetbrains.jet.plugin.refactoring.JetNameValidator; -+import org.jetbrains.jet.plugin.references.JetSimpleNameReference; -+import org.jetbrains.jet.renderer.DescriptorRenderer; -+ -+import javax.swing.*; -+import java.util.*; -+import java.util.regex.Matcher; -+import java.util.regex.Pattern; -+ -+public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { -+ private static final String TYPE_PARAMETER_LIST_VARIABLE_NAME = ""typeParameterList""; -+ private static final String TEMPLATE_FROM_USAGE_METHOD_BODY = ""New Kotlin Method Body.kt""; -+ private static final Pattern COMPONENT_FUNCTION_PATTERN = Pattern.compile(""^component(\\d+)$""); -+ -+ /** -+ * Represents a single choice for a type (e.g. parameter type or return type). -+ */ -+ private static class TypeCandidate { -+ private final JetType type; -+ private final TypeParameterDescriptor[] typeParameters; -+ private String renderedType; -+ private String[] typeParameterNames; -+ -+ public TypeCandidate(@NotNull JetType type) { -+ this.type = type; -+ Set typeParametersInType = getTypeParametersInType(type); -+ typeParameters = typeParametersInType.toArray(new TypeParameterDescriptor[typeParametersInType.size()]); -+ renderedType = renderTypeShort(type, Collections.emptyMap()); -+ } -+ -+ public TypeCandidate(@NotNull JetType type, @NotNull JetScope scope) { -+ this.type = type; -+ typeParameters = getTypeParameterNamesNotInScope(getTypeParametersInType(type), scope); -+ } -+ -+ public void render(@NotNull Map typeParameterNameMap) { -+ renderedType = renderTypeShort(type, typeParameterNameMap); -+ typeParameterNames = new String[typeParameters.length]; -+ int i = 0; -+ for (TypeParameterDescriptor typeParameter : typeParameters) { -+ typeParameterNames[i] = typeParameterNameMap.get(typeParameter); -+ i++; -+ } -+ } -+ -+ @NotNull JetType getType() { -+ return type; -+ } -+ -+ @NotNull -+ public String getRenderedType() { -+ assert renderedType != null : ""call render() first""; -+ return renderedType; -+ } -+ -+ @NotNull -+ public String[] getTypeParameterNames() { -+ assert typeParameterNames != null : ""call render() first""; -+ return typeParameterNames; -+ } -+ -+ @NotNull -+ public TypeParameterDescriptor[] getTypeParameters() { -+ return typeParameters; -+ } -+ } -+ -+ /** -+ * Represents a concrete type or a set of types yet to be inferred from an expression. -+ */ -+ private static class TypeOrExpressionThereof { -+ private final JetExpression expressionOfType; -+ private final JetType type; -+ private final Variance variance; -+ private TypeCandidate[] typeCandidates; -+ private String[] cachedNameCandidatesFromExpression; -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType) { -+ this(expressionOfType, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType, Variance variance) { -+ this(expressionOfType, null, variance); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type) { -+ this(type, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type, Variance variance) { -+ this(null, type, variance); -+ } -+ -+ private TypeOrExpressionThereof(@Nullable JetExpression expressionOfType, @Nullable JetType type, Variance variance) { -+ this.expressionOfType = expressionOfType; -+ this.type = type; -+ this.variance = variance; -+ } -+ -+ public boolean isType() { -+ return this.type != null; -+ } -+ -+ @NotNull -+ public JetType getType() { -+ assert this.type != null; -+ return this.type; -+ } -+ -+ @NotNull -+ private List getPossibleTypes(BindingContext context) { -+ List types = new ArrayList(); -+ if (isType()) { -+ assert type != null : ""!isType() means type == null && expressionOfType != null""; -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ for (JetType type : guessTypeForExpression(expressionOfType, context)) { -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } -+ } -+ return types; -+ } -+ -+ public void computeTypeCandidates(@NotNull BindingContext context) { -+ Collection types = getPossibleTypes(context); -+ -+ typeCandidates = new TypeCandidate[types.size()]; -+ int i = 0; -+ for (JetType type : types) { -+ typeCandidates[i] = new TypeCandidate(type); -+ i++; -+ } -+ } -+ -+ public void computeTypeCandidates( -+ @NotNull BindingContext context, -+ @NotNull TypeSubstitution[] substitutions, -+ @NotNull JetScope scope -+ ) { -+ List types = getPossibleTypes(context); -+ Collections.reverse(types); // reverse and reverse back later, so that things added below are added at the front -+ -+ Set newTypes = new LinkedHashSet(types); -+ for (TypeSubstitution substitution : substitutions) { // each substitution can be applied or not, so we offer all options -+ List toAdd = new ArrayList(); -+ List toRemove = new ArrayList(); -+ for (JetType type : newTypes) { -+ toAdd.add(substituteType(type, substitution, variance)); -+ // substitution.byType are type arguments, but they cannot already occur in the type before substitution -+ if (containsType(type, substitution.getByType())) { -+ toRemove.add(type); -+ } -+ } -+ newTypes.addAll(toAdd); -+ newTypes.removeAll(toRemove); -+ } -+ -+ if (newTypes.isEmpty()) { -+ newTypes.add(KotlinBuiltIns.getInstance().getAnyType()); -+ } -+ -+ typeCandidates = new TypeCandidate[newTypes.size()]; -+ int i = typeCandidates.length - 1; // reverse order (see explanation above) -+ for (JetType type : newTypes) { -+ typeCandidates[i] = new TypeCandidate(type, scope); -+ i--; -+ } -+ } -+ -+ @NotNull -+ public TypeCandidate[] getTypeCandidates() { -+ assert typeCandidates != null : ""call computeTypeCandidates() first""; -+ return typeCandidates; -+ } -+ -+ public void renderTypeCandidates(@NotNull Map typeParameterNameMap) { -+ for (TypeCandidate candidate : typeCandidates) { -+ candidate.render(typeParameterNameMap); -+ } -+ } -+ -+ @NotNull -+ public String[] getPossibleNamesFromExpression() { -+ if (cachedNameCandidatesFromExpression != null) return cachedNameCandidatesFromExpression; -+ if (isType()) { -+ cachedNameCandidatesFromExpression = ArrayUtil.EMPTY_STRING_ARRAY; -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ JetNameValidator dummyValidator = new DummyJetNameValidator(expressionOfType.getProject()); -+ cachedNameCandidatesFromExpression = JetNameSuggester.suggestNamesForExpression(expressionOfType, dummyValidator); -+ } -+ return cachedNameCandidatesFromExpression; -+ } -+ } -+ -+ /** -+ * Encapsulates information about a method parameter that is going to be created. -+ */ -+ private static class Parameter { -+ private final String preferredName; -+ private final TypeOrExpressionThereof type; -+ -+ public Parameter(@Nullable(""no preferred name"") String preferredName, TypeOrExpressionThereof type) { -+ this.preferredName = preferredName; -+ this.type = type; -+ } -+ -+ public String getPreferredName() { -+ return preferredName; -+ } -+ -+ public TypeOrExpressionThereof getType() { -+ return type; -+ } -+ } -+ -+ /** -+ * Special Expression for parameter names based on its type. -+ */ -+ private static class ParameterNameExpression extends Expression { -+ private final String[] names; -+ private final Map parameterTypeToNamesMap; -+ -+ public ParameterNameExpression(@NotNull String[] names, @NotNull Map parameterTypeToNamesMap) { -+ for (String name : names) { -+ assert name != null && !name.isEmpty(); -+ } -+ this.names = names; -+ this.parameterTypeToNamesMap = parameterTypeToNamesMap; -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ LookupElement[] lookupItems = calculateLookupItems(context); -+ if (lookupItems.length == 0) return new TextResult(""""); -+ -+ return new TextResult(lookupItems[0].getLookupString()); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ Set names = new LinkedHashSet(); -+ Collections.addAll(names, this.names); -+ -+ // find the parameter list -+ Project project = context.getProject(); -+ int offset = context.getStartOffset(); -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ Editor editor = context.getEditor(); -+ assert editor != null; -+ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); -+ assert file != null && file instanceof JetFile; -+ PsiElement elementAt = file.findElementAt(offset); -+ JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); -+ if (func == null) return new LookupElement[0]; -+ JetParameterList parameterList = func.getValueParameterList(); -+ assert parameterList != null; -+ -+ // add names based on selected type -+ JetParameter parameter = PsiTreeUtil.getParentOfType(elementAt, JetParameter.class); -+ if (parameter != null) { -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ String[] suggestedNamesBasedOnType = parameterTypeToNamesMap.get(parameterTypeRef.getText()); -+ if (suggestedNamesBasedOnType != null) { -+ Collections.addAll(names, suggestedNamesBasedOnType); -+ } -+ } -+ } -+ -+ // remember other parameter names for later use -+ Set parameterNames = new HashSet(); -+ for (JetParameter jetParameter : parameterList.getParameters()) { -+ if (jetParameter == parameter || jetParameter.getName() == null) continue; -+ parameterNames.add(jetParameter.getName()); -+ } -+ -+ // add fallback parameter name -+ if (names.isEmpty()) { -+ names.add(""arg""); -+ } -+ -+ // ensure there are no conflicts -+ List lookupElements = new ArrayList(); -+ for (String name : names) { -+ name = getNextAvailableName(name, parameterNames); -+ lookupElements.add(LookupElementBuilder.create(name)); -+ } -+ -+ // create and return -+ return lookupElements.toArray(new LookupElement[lookupElements.size()]); -+ } -+ } -+ -+ /** -+ * An Expression for type references. -+ */ -+ private static class TypeExpression extends Expression { -+ private final TypeOrExpressionThereof type; -+ private @NotNull LookupElement[] cachedLookupElements; -+ -+ public TypeExpression(@NotNull TypeOrExpressionThereof type) { -+ this.type = type; -+ TypeCandidate[] candidates = type.getTypeCandidates(); -+ cachedLookupElements = new LookupElement[candidates.length]; -+ for (int i = 0; i < candidates.length; i++) { -+ cachedLookupElements[i] = LookupElementBuilder.create(candidates[i], candidates[i].getRenderedType()); -+ } -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ LookupElement[] lookupItems = calculateLookupItems(context); -+ if (lookupItems.length == 0) return new TextResult(""""); -+ -+ return new TextResult(lookupItems[0].getLookupString()); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ return cachedLookupElements; -+ } -+ -+ @NotNull -+ public TypeOrExpressionThereof getType() { -+ return type; -+ } -+ -+ @Nullable(""can't be found"") -+ public JetType getTypeFromSelection(@NotNull String selection) { -+ TypeCandidate[] options = type.getTypeCandidates(); -+ for (TypeCandidate option : options) { -+ if (option.getRenderedType().equals(selection)) { -+ return option.getType(); -+ } -+ } -+ return null; -+ } -+ } -+ -+ /** -+ * A sort-of dummy Expression for parameter lists, to allow us to update the parameter list as the user makes selections. -+ */ -+ private static class TypeParameterListExpression extends Expression { -+ private final String[] typeParameterNamesFromReceiverType; -+ private final Map parameterTypeToTypeParameterNamesMap; -+ -+ public TypeParameterListExpression( -+ @NotNull String[] typeParameterNamesFromReceiverType, -+ @NotNull Map typeParametersMap -+ ) { -+ this.typeParameterNamesFromReceiverType = typeParameterNamesFromReceiverType; -+ this.parameterTypeToTypeParameterNamesMap = typeParametersMap; -+ } -+ -+ @NotNull -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ Project project = context.getProject(); -+ int offset = context.getStartOffset(); -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ Editor editor = context.getEditor(); -+ assert editor != null; -+ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); -+ assert file != null && file instanceof JetFile; -+ PsiElement elementAt = file.findElementAt(offset); -+ JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); -+ if (func == null) { -+ return new TextResult(""""); -+ } -+ List parameters = func.getValueParameters(); -+ -+ Set typeParameterNames = new LinkedHashSet(); -+ Collections.addAll(typeParameterNames, typeParameterNamesFromReceiverType); -+ for (JetParameter parameter : parameters) { -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ String[] typeParameterNamesFromParameter = parameterTypeToTypeParameterNamesMap.get(parameterTypeRef.getText()); -+ if (typeParameterNamesFromParameter != null) { -+ Collections.addAll(typeParameterNames, typeParameterNamesFromParameter); -+ } -+ } -+ } -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ if (returnTypeRef != null) { -+ String[] typeParameterNamesFromReturnType = parameterTypeToTypeParameterNamesMap.get(returnTypeRef.getText()); -+ if (typeParameterNamesFromReturnType != null) { -+ Collections.addAll(typeParameterNames, typeParameterNamesFromReturnType); -+ } -+ } -+ -+ return typeParameterNames.isEmpty() -+ ? new TextResult("""") -+ : new TextResult("" <"" + StringUtil.join(typeParameterNames, "", "") + "">""); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ return new LookupElement[0]; // do not offer the user any choices -+ } -+ } -+ -+ /** -+ * A JetNameValidator that always succeeds. -+ */ -+ private static class DummyJetNameValidator implements JetNameValidator { -+ private final Project project; -+ -+ public DummyJetNameValidator(Project project) { -+ this.project = project; -+ } -+ -+ @Nullable -+ @Override -+ public String validateName(String name) { -+ return name; -+ } -+ -+ @Override -+ public Project getProject() { -+ return project; -+ } -+ } -+ -+ /** -+ * Encapsulates a single type substitution of a JetType by another JetType. -+ */ -+ private static class TypeSubstitution { -+ private final JetType forType; -+ private final JetType byType; -+ -+ private TypeSubstitution(JetType forType, JetType byType) { -+ this.forType = forType; -+ this.byType = byType; -+ } -+ -+ private JetType getForType() { -+ return forType; -+ } -+ -+ private JetType getByType() { -+ return byType; -+ } -+ } -+ -+ private final String methodName; -+ private final TypeOrExpressionThereof ownerType; -+ private final TypeOrExpressionThereof returnType; -+ private final List parameters; -+ -+ private boolean isUnit; -+ private boolean isExtension; -+ private JetFile currentFile; -+ private JetFile containingFile; -+ private Editor currentFileEditor; -+ private Editor containingFileEditor; -+ private BindingContext currentFileContext; -+ private JetClass ownerClass; -+ private ClassDescriptor ownerClassDescriptor; -+ private TypeCandidate selectedReceiverType; -+ private Map typeParameterNameMap; -+ -+ public CreateMethodFromUsageFix(@NotNull PsiElement element, @NotNull TypeOrExpressionThereof ownerType, @NotNull String methodName, -+ @NotNull TypeOrExpressionThereof returnType, @NotNull List parameters) { -+ super(element); -+ this.methodName = methodName; -+ this.ownerType = ownerType; -+ this.returnType = returnType; -+ this.parameters = parameters; -+ } -+ -+ @NotNull -+ @Override -+ public String getText() { -+ return JetBundle.message(""create.method.from.usage"", methodName); -+ } -+ -+ @Override -+ public void invoke(@NotNull final Project project, Editor editor, PsiFile file) throws IncorrectOperationException { -+ assert file != null && file instanceof JetFile; -+ currentFile = (JetFile) file; -+ currentFileEditor = editor; -+ currentFileContext = AnalyzerFacadeWithCache.analyzeFileWithCache(currentFile).getBindingContext(); -+ -+ ownerType.computeTypeCandidates(currentFileContext); -+ TypeCandidate[] ownerTypeCandidates = ownerType.getTypeCandidates(); -+ assert ownerTypeCandidates.length > 0; -+ if (ownerTypeCandidates.length == 1 || ApplicationManager.getApplication().isUnitTestMode()) { -+ selectedReceiverType = ownerTypeCandidates[0]; -+ doInvoke(project); -+ } else { -+ // class selection -+ List options = new ArrayList(); -+ final Map optionToTypeMap = new HashMap(); -+ for (TypeCandidate ownerTypeCandidate : ownerTypeCandidates) { -+ ClassifierDescriptor possibleClassDescriptor = ownerTypeCandidate.getType().getConstructor().getDeclarationDescriptor(); -+ if (possibleClassDescriptor != null) { -+ String className = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(possibleClassDescriptor.getDefaultType()); -+ DeclarationDescriptor namespaceDescriptor = possibleClassDescriptor.getContainingDeclaration(); -+ String namespace = renderDescriptor(namespaceDescriptor, true); -+ String option = className + "" ("" + namespace + "")""; -+ options.add(option); -+ optionToTypeMap.put(option, ownerTypeCandidate); -+ } -+ } -+ -+ final JList list = new JBList(options); -+ PsiElementListCellRenderer renderer = new JetLightClassListCellRenderer(); -+ list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); -+ list.setCellRenderer(renderer); -+ PopupChooserBuilder builder = new PopupChooserBuilder(list); -+ renderer.installSpeedSearch(builder); -+ -+ Runnable runnable = new Runnable() { -+ @Override -+ public void run() { -+ int index = list.getSelectedIndex(); -+ if (index < 0) return; -+ String option = (String) list.getSelectedValue(); -+ selectedReceiverType = optionToTypeMap.get(option); -+ CommandProcessor.getInstance().executeCommand(project, new Runnable() { -+ @Override -+ public void run() { -+ doInvoke(project); -+ } -+ }, getText(), null); -+ } -+ }; -+ -+ builder.setTitle(JetBundle.message(""choose.target.class.or.trait.title"")) -+ .setItemChoosenCallback(runnable) -+ .createPopup() -+ .showInBestPositionFor(currentFileEditor); -+ } -+ } -+ -+ private void doInvoke(@NotNull final Project project) { -+ // gather relevant information -+ ClassifierDescriptor ownerTypeDescriptor = selectedReceiverType.getType().getConstructor().getDeclarationDescriptor(); -+ assert ownerTypeDescriptor != null && ownerTypeDescriptor instanceof ClassDescriptor; -+ ownerClassDescriptor = (ClassDescriptor) ownerTypeDescriptor; -+ JetType receiverType = ownerClassDescriptor.getDefaultType(); -+ PsiElement typeDeclaration = BindingContextUtils.classDescriptorToDeclaration(currentFileContext, ownerClassDescriptor); -+ if (typeDeclaration != null && typeDeclaration instanceof JetClass) { -+ ownerClass = (JetClass) typeDeclaration; -+ isExtension = !ownerClass.isWritable(); -+ } else { -+ isExtension = true; -+ } -+ isUnit = returnType.isType() && isUnit(returnType.getType()); -+ -+ JetScope scope; -+ if (isExtension) { -+ NamespaceDescriptor namespaceDescriptor = currentFileContext.get(BindingContext.FILE_TO_NAMESPACE, currentFile); -+ assert namespaceDescriptor != null; -+ scope = namespaceDescriptor.getMemberScope(); -+ } else { -+ assert ownerClassDescriptor instanceof MutableClassDescriptor; -+ scope = ((MutableClassDescriptor) ownerClassDescriptor).getScopeForMemberResolution(); -+ } -+ -+ // figure out type substitutions for type parameters -+ List classTypeParameters = receiverType.getArguments(); -+ List ownerTypeArguments = selectedReceiverType.getType().getArguments(); -+ assert ownerTypeArguments.size() == classTypeParameters.size(); -+ TypeSubstitution[] substitutions = new TypeSubstitution[classTypeParameters.size()]; -+ for (int i = 0; i < substitutions.length; i++) { -+ substitutions[i] = new TypeSubstitution(ownerTypeArguments.get(i).getType(), classTypeParameters.get(i).getType()); -+ } -+ for (Parameter parameter : parameters) { -+ parameter.getType().computeTypeCandidates(currentFileContext, substitutions, scope); -+ } -+ if (!isUnit) { -+ returnType.computeTypeCandidates(currentFileContext, substitutions, scope); -+ } -+ -+ // now that we have done substitutions, we can throw it away -+ selectedReceiverType = new TypeCandidate(receiverType, scope); -+ -+ // figure out type parameter renames to avoid conflicts -+ typeParameterNameMap = getTypeParameterRenames(scope); -+ for (Parameter parameter : parameters) { -+ parameter.getType().renderTypeCandidates(typeParameterNameMap); -+ } -+ if (!isUnit) { -+ returnType.renderTypeCandidates(typeParameterNameMap); -+ } -+ selectedReceiverType.render(typeParameterNameMap); -+ -+ ApplicationManager.getApplication().runWriteAction(new Runnable() { -+ @Override -+ public void run() { -+ JetNamedFunction func = createFunctionSkeleton(project); -+ buildAndRunTemplate(project, func); -+ } -+ }); -+ } -+ -+ private JetNamedFunction createFunctionSkeleton(@NotNull Project project) {","`project` parameter is redundant, see above. -",Why is this needed? Looks like a duplicate file. -103,"@@ -0,0 +1,1391 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.codeInsight.lookup.LookupElement; -+import com.intellij.codeInsight.lookup.LookupElementBuilder; -+import com.intellij.codeInsight.template.*; -+import com.intellij.codeInsight.template.impl.TemplateImpl; -+import com.intellij.codeInsight.template.impl.Variable; -+import com.intellij.ide.fileTemplates.FileTemplate; -+import com.intellij.ide.fileTemplates.FileTemplateManager; -+import com.intellij.ide.util.PsiElementListCellRenderer; -+import com.intellij.openapi.application.ApplicationManager; -+import com.intellij.openapi.command.CommandProcessor; -+import com.intellij.openapi.editor.CaretModel; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.fileEditor.FileEditorManager; -+import com.intellij.openapi.progress.ProcessCanceledException; -+import com.intellij.openapi.project.Project; -+import com.intellij.openapi.ui.popup.PopupChooserBuilder; -+import com.intellij.openapi.util.TextRange; -+import com.intellij.openapi.util.text.StringUtil; -+import com.intellij.openapi.vfs.VirtualFile; -+import com.intellij.psi.PsiDocumentManager; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.PsiReference; -+import com.intellij.psi.search.SearchScope; -+import com.intellij.psi.util.PsiTreeUtil; -+import com.intellij.refactoring.psi.SearchUtils; -+import com.intellij.ui.components.JBList; -+import com.intellij.util.ArrayUtil; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NonNls; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.descriptors.*; -+import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1; -+import org.jetbrains.jet.lang.diagnostics.Errors; -+import org.jetbrains.jet.lang.psi.*; -+import org.jetbrains.jet.lang.resolve.BindingContext; -+import org.jetbrains.jet.lang.resolve.BindingContextUtils; -+import org.jetbrains.jet.lang.resolve.DescriptorUtils; -+import org.jetbrains.jet.lang.resolve.name.Name; -+import org.jetbrains.jet.lang.resolve.scopes.JetScope; -+import org.jetbrains.jet.lang.types.*; -+import org.jetbrains.jet.lang.types.checker.JetTypeChecker; -+import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; -+import org.jetbrains.jet.plugin.JetBundle; -+import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening; -+import org.jetbrains.jet.plugin.presentation.JetLightClassListCellRenderer; -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; -+import org.jetbrains.jet.plugin.refactoring.JetNameSuggester; -+import org.jetbrains.jet.plugin.refactoring.JetNameValidator; -+import org.jetbrains.jet.plugin.references.JetSimpleNameReference; -+import org.jetbrains.jet.renderer.DescriptorRenderer; -+ -+import javax.swing.*; -+import java.util.*; -+import java.util.regex.Matcher; -+import java.util.regex.Pattern; -+ -+public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { -+ private static final String TYPE_PARAMETER_LIST_VARIABLE_NAME = ""typeParameterList""; -+ private static final String TEMPLATE_FROM_USAGE_METHOD_BODY = ""New Kotlin Method Body.kt""; -+ private static final Pattern COMPONENT_FUNCTION_PATTERN = Pattern.compile(""^component(\\d+)$""); -+ -+ /** -+ * Represents a single choice for a type (e.g. parameter type or return type). -+ */ -+ private static class TypeCandidate { -+ private final JetType type; -+ private final TypeParameterDescriptor[] typeParameters; -+ private String renderedType; -+ private String[] typeParameterNames; -+ -+ public TypeCandidate(@NotNull JetType type) { -+ this.type = type; -+ Set typeParametersInType = getTypeParametersInType(type); -+ typeParameters = typeParametersInType.toArray(new TypeParameterDescriptor[typeParametersInType.size()]); -+ renderedType = renderTypeShort(type, Collections.emptyMap()); -+ } -+ -+ public TypeCandidate(@NotNull JetType type, @NotNull JetScope scope) { -+ this.type = type; -+ typeParameters = getTypeParameterNamesNotInScope(getTypeParametersInType(type), scope); -+ } -+ -+ public void render(@NotNull Map typeParameterNameMap) { -+ renderedType = renderTypeShort(type, typeParameterNameMap); -+ typeParameterNames = new String[typeParameters.length]; -+ int i = 0; -+ for (TypeParameterDescriptor typeParameter : typeParameters) { -+ typeParameterNames[i] = typeParameterNameMap.get(typeParameter); -+ i++; -+ } -+ } -+ -+ @NotNull JetType getType() { -+ return type; -+ } -+ -+ @NotNull -+ public String getRenderedType() { -+ assert renderedType != null : ""call render() first""; -+ return renderedType; -+ } -+ -+ @NotNull -+ public String[] getTypeParameterNames() { -+ assert typeParameterNames != null : ""call render() first""; -+ return typeParameterNames; -+ } -+ -+ @NotNull -+ public TypeParameterDescriptor[] getTypeParameters() { -+ return typeParameters; -+ } -+ } -+ -+ /** -+ * Represents a concrete type or a set of types yet to be inferred from an expression. -+ */ -+ private static class TypeOrExpressionThereof { -+ private final JetExpression expressionOfType; -+ private final JetType type; -+ private final Variance variance; -+ private TypeCandidate[] typeCandidates; -+ private String[] cachedNameCandidatesFromExpression; -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType) { -+ this(expressionOfType, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType, Variance variance) { -+ this(expressionOfType, null, variance); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type) { -+ this(type, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type, Variance variance) { -+ this(null, type, variance); -+ } -+ -+ private TypeOrExpressionThereof(@Nullable JetExpression expressionOfType, @Nullable JetType type, Variance variance) { -+ this.expressionOfType = expressionOfType; -+ this.type = type; -+ this.variance = variance; -+ } -+ -+ public boolean isType() { -+ return this.type != null; -+ } -+ -+ @NotNull -+ public JetType getType() { -+ assert this.type != null; -+ return this.type; -+ } -+ -+ @NotNull -+ private List getPossibleTypes(BindingContext context) { -+ List types = new ArrayList(); -+ if (isType()) { -+ assert type != null : ""!isType() means type == null && expressionOfType != null""; -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ for (JetType type : guessTypeForExpression(expressionOfType, context)) { -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } -+ } -+ return types; -+ } -+ -+ public void computeTypeCandidates(@NotNull BindingContext context) { -+ Collection types = getPossibleTypes(context); -+ -+ typeCandidates = new TypeCandidate[types.size()]; -+ int i = 0; -+ for (JetType type : types) { -+ typeCandidates[i] = new TypeCandidate(type); -+ i++; -+ } -+ } -+ -+ public void computeTypeCandidates( -+ @NotNull BindingContext context, -+ @NotNull TypeSubstitution[] substitutions, -+ @NotNull JetScope scope -+ ) { -+ List types = getPossibleTypes(context); -+ Collections.reverse(types); // reverse and reverse back later, so that things added below are added at the front -+ -+ Set newTypes = new LinkedHashSet(types); -+ for (TypeSubstitution substitution : substitutions) { // each substitution can be applied or not, so we offer all options -+ List toAdd = new ArrayList(); -+ List toRemove = new ArrayList(); -+ for (JetType type : newTypes) { -+ toAdd.add(substituteType(type, substitution, variance)); -+ // substitution.byType are type arguments, but they cannot already occur in the type before substitution -+ if (containsType(type, substitution.getByType())) { -+ toRemove.add(type); -+ } -+ } -+ newTypes.addAll(toAdd); -+ newTypes.removeAll(toRemove); -+ } -+ -+ if (newTypes.isEmpty()) { -+ newTypes.add(KotlinBuiltIns.getInstance().getAnyType()); -+ } -+ -+ typeCandidates = new TypeCandidate[newTypes.size()]; -+ int i = typeCandidates.length - 1; // reverse order (see explanation above) -+ for (JetType type : newTypes) { -+ typeCandidates[i] = new TypeCandidate(type, scope); -+ i--; -+ } -+ } -+ -+ @NotNull -+ public TypeCandidate[] getTypeCandidates() { -+ assert typeCandidates != null : ""call computeTypeCandidates() first""; -+ return typeCandidates; -+ } -+ -+ public void renderTypeCandidates(@NotNull Map typeParameterNameMap) { -+ for (TypeCandidate candidate : typeCandidates) { -+ candidate.render(typeParameterNameMap); -+ } -+ } -+ -+ @NotNull -+ public String[] getPossibleNamesFromExpression() { -+ if (cachedNameCandidatesFromExpression != null) return cachedNameCandidatesFromExpression; -+ if (isType()) { -+ cachedNameCandidatesFromExpression = ArrayUtil.EMPTY_STRING_ARRAY; -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ JetNameValidator dummyValidator = new DummyJetNameValidator(expressionOfType.getProject()); -+ cachedNameCandidatesFromExpression = JetNameSuggester.suggestNamesForExpression(expressionOfType, dummyValidator); -+ } -+ return cachedNameCandidatesFromExpression; -+ } -+ } -+ -+ /** -+ * Encapsulates information about a method parameter that is going to be created. -+ */ -+ private static class Parameter { -+ private final String preferredName; -+ private final TypeOrExpressionThereof type; -+ -+ public Parameter(@Nullable(""no preferred name"") String preferredName, TypeOrExpressionThereof type) { -+ this.preferredName = preferredName; -+ this.type = type; -+ } -+ -+ public String getPreferredName() { -+ return preferredName; -+ } -+ -+ public TypeOrExpressionThereof getType() { -+ return type; -+ } -+ } -+ -+ /** -+ * Special Expression for parameter names based on its type. -+ */ -+ private static class ParameterNameExpression extends Expression { -+ private final String[] names; -+ private final Map parameterTypeToNamesMap; -+ -+ public ParameterNameExpression(@NotNull String[] names, @NotNull Map parameterTypeToNamesMap) { -+ for (String name : names) { -+ assert name != null && !name.isEmpty(); -+ } -+ this.names = names; -+ this.parameterTypeToNamesMap = parameterTypeToNamesMap; -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ LookupElement[] lookupItems = calculateLookupItems(context); -+ if (lookupItems.length == 0) return new TextResult(""""); -+ -+ return new TextResult(lookupItems[0].getLookupString()); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ Set names = new LinkedHashSet(); -+ Collections.addAll(names, this.names); -+ -+ // find the parameter list -+ Project project = context.getProject(); -+ int offset = context.getStartOffset(); -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ Editor editor = context.getEditor(); -+ assert editor != null; -+ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); -+ assert file != null && file instanceof JetFile; -+ PsiElement elementAt = file.findElementAt(offset); -+ JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); -+ if (func == null) return new LookupElement[0]; -+ JetParameterList parameterList = func.getValueParameterList(); -+ assert parameterList != null; -+ -+ // add names based on selected type -+ JetParameter parameter = PsiTreeUtil.getParentOfType(elementAt, JetParameter.class); -+ if (parameter != null) { -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ String[] suggestedNamesBasedOnType = parameterTypeToNamesMap.get(parameterTypeRef.getText()); -+ if (suggestedNamesBasedOnType != null) { -+ Collections.addAll(names, suggestedNamesBasedOnType); -+ } -+ } -+ } -+ -+ // remember other parameter names for later use -+ Set parameterNames = new HashSet(); -+ for (JetParameter jetParameter : parameterList.getParameters()) { -+ if (jetParameter == parameter || jetParameter.getName() == null) continue; -+ parameterNames.add(jetParameter.getName()); -+ } -+ -+ // add fallback parameter name -+ if (names.isEmpty()) { -+ names.add(""arg""); -+ } -+ -+ // ensure there are no conflicts -+ List lookupElements = new ArrayList(); -+ for (String name : names) { -+ name = getNextAvailableName(name, parameterNames); -+ lookupElements.add(LookupElementBuilder.create(name)); -+ } -+ -+ // create and return -+ return lookupElements.toArray(new LookupElement[lookupElements.size()]); -+ } -+ } -+ -+ /** -+ * An Expression for type references. -+ */ -+ private static class TypeExpression extends Expression { -+ private final TypeOrExpressionThereof type; -+ private @NotNull LookupElement[] cachedLookupElements; -+ -+ public TypeExpression(@NotNull TypeOrExpressionThereof type) { -+ this.type = type; -+ TypeCandidate[] candidates = type.getTypeCandidates(); -+ cachedLookupElements = new LookupElement[candidates.length]; -+ for (int i = 0; i < candidates.length; i++) { -+ cachedLookupElements[i] = LookupElementBuilder.create(candidates[i], candidates[i].getRenderedType()); -+ } -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ LookupElement[] lookupItems = calculateLookupItems(context); -+ if (lookupItems.length == 0) return new TextResult(""""); -+ -+ return new TextResult(lookupItems[0].getLookupString()); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ return cachedLookupElements; -+ } -+ -+ @NotNull -+ public TypeOrExpressionThereof getType() { -+ return type; -+ } -+ -+ @Nullable(""can't be found"") -+ public JetType getTypeFromSelection(@NotNull String selection) { -+ TypeCandidate[] options = type.getTypeCandidates(); -+ for (TypeCandidate option : options) { -+ if (option.getRenderedType().equals(selection)) { -+ return option.getType(); -+ } -+ } -+ return null; -+ } -+ } -+ -+ /** -+ * A sort-of dummy Expression for parameter lists, to allow us to update the parameter list as the user makes selections. -+ */ -+ private static class TypeParameterListExpression extends Expression { -+ private final String[] typeParameterNamesFromReceiverType; -+ private final Map parameterTypeToTypeParameterNamesMap; -+ -+ public TypeParameterListExpression( -+ @NotNull String[] typeParameterNamesFromReceiverType, -+ @NotNull Map typeParametersMap -+ ) { -+ this.typeParameterNamesFromReceiverType = typeParameterNamesFromReceiverType; -+ this.parameterTypeToTypeParameterNamesMap = typeParametersMap; -+ } -+ -+ @NotNull -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ Project project = context.getProject(); -+ int offset = context.getStartOffset(); -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ Editor editor = context.getEditor(); -+ assert editor != null; -+ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); -+ assert file != null && file instanceof JetFile; -+ PsiElement elementAt = file.findElementAt(offset); -+ JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); -+ if (func == null) { -+ return new TextResult(""""); -+ } -+ List parameters = func.getValueParameters(); -+ -+ Set typeParameterNames = new LinkedHashSet(); -+ Collections.addAll(typeParameterNames, typeParameterNamesFromReceiverType); -+ for (JetParameter parameter : parameters) { -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ String[] typeParameterNamesFromParameter = parameterTypeToTypeParameterNamesMap.get(parameterTypeRef.getText()); -+ if (typeParameterNamesFromParameter != null) { -+ Collections.addAll(typeParameterNames, typeParameterNamesFromParameter); -+ } -+ } -+ } -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ if (returnTypeRef != null) { -+ String[] typeParameterNamesFromReturnType = parameterTypeToTypeParameterNamesMap.get(returnTypeRef.getText()); -+ if (typeParameterNamesFromReturnType != null) { -+ Collections.addAll(typeParameterNames, typeParameterNamesFromReturnType); -+ } -+ } -+ -+ return typeParameterNames.isEmpty() -+ ? new TextResult("""") -+ : new TextResult("" <"" + StringUtil.join(typeParameterNames, "", "") + "">""); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ return new LookupElement[0]; // do not offer the user any choices -+ } -+ } -+ -+ /** -+ * A JetNameValidator that always succeeds. -+ */ -+ private static class DummyJetNameValidator implements JetNameValidator { -+ private final Project project; -+ -+ public DummyJetNameValidator(Project project) { -+ this.project = project; -+ } -+ -+ @Nullable -+ @Override -+ public String validateName(String name) { -+ return name; -+ } -+ -+ @Override -+ public Project getProject() { -+ return project; -+ } -+ } -+ -+ /** -+ * Encapsulates a single type substitution of a JetType by another JetType. -+ */ -+ private static class TypeSubstitution { -+ private final JetType forType; -+ private final JetType byType; -+ -+ private TypeSubstitution(JetType forType, JetType byType) { -+ this.forType = forType; -+ this.byType = byType; -+ } -+ -+ private JetType getForType() { -+ return forType; -+ } -+ -+ private JetType getByType() { -+ return byType; -+ } -+ } -+ -+ private final String methodName; -+ private final TypeOrExpressionThereof ownerType; -+ private final TypeOrExpressionThereof returnType; -+ private final List parameters; -+ -+ private boolean isUnit; -+ private boolean isExtension; -+ private JetFile currentFile; -+ private JetFile containingFile; -+ private Editor currentFileEditor; -+ private Editor containingFileEditor; -+ private BindingContext currentFileContext; -+ private JetClass ownerClass; -+ private ClassDescriptor ownerClassDescriptor; -+ private TypeCandidate selectedReceiverType; -+ private Map typeParameterNameMap; -+ -+ public CreateMethodFromUsageFix(@NotNull PsiElement element, @NotNull TypeOrExpressionThereof ownerType, @NotNull String methodName, -+ @NotNull TypeOrExpressionThereof returnType, @NotNull List parameters) { -+ super(element); -+ this.methodName = methodName; -+ this.ownerType = ownerType; -+ this.returnType = returnType; -+ this.parameters = parameters; -+ } -+ -+ @NotNull -+ @Override -+ public String getText() { -+ return JetBundle.message(""create.method.from.usage"", methodName); -+ } -+ -+ @Override -+ public void invoke(@NotNull final Project project, Editor editor, PsiFile file) throws IncorrectOperationException { -+ assert file != null && file instanceof JetFile; -+ currentFile = (JetFile) file; -+ currentFileEditor = editor; -+ currentFileContext = AnalyzerFacadeWithCache.analyzeFileWithCache(currentFile).getBindingContext(); -+ -+ ownerType.computeTypeCandidates(currentFileContext); -+ TypeCandidate[] ownerTypeCandidates = ownerType.getTypeCandidates(); -+ assert ownerTypeCandidates.length > 0; -+ if (ownerTypeCandidates.length == 1 || ApplicationManager.getApplication().isUnitTestMode()) { -+ selectedReceiverType = ownerTypeCandidates[0]; -+ doInvoke(project); -+ } else { -+ // class selection -+ List options = new ArrayList(); -+ final Map optionToTypeMap = new HashMap(); -+ for (TypeCandidate ownerTypeCandidate : ownerTypeCandidates) { -+ ClassifierDescriptor possibleClassDescriptor = ownerTypeCandidate.getType().getConstructor().getDeclarationDescriptor(); -+ if (possibleClassDescriptor != null) { -+ String className = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(possibleClassDescriptor.getDefaultType()); -+ DeclarationDescriptor namespaceDescriptor = possibleClassDescriptor.getContainingDeclaration(); -+ String namespace = renderDescriptor(namespaceDescriptor, true); -+ String option = className + "" ("" + namespace + "")""; -+ options.add(option); -+ optionToTypeMap.put(option, ownerTypeCandidate); -+ } -+ } -+ -+ final JList list = new JBList(options); -+ PsiElementListCellRenderer renderer = new JetLightClassListCellRenderer(); -+ list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); -+ list.setCellRenderer(renderer); -+ PopupChooserBuilder builder = new PopupChooserBuilder(list); -+ renderer.installSpeedSearch(builder); -+ -+ Runnable runnable = new Runnable() { -+ @Override -+ public void run() { -+ int index = list.getSelectedIndex(); -+ if (index < 0) return; -+ String option = (String) list.getSelectedValue(); -+ selectedReceiverType = optionToTypeMap.get(option); -+ CommandProcessor.getInstance().executeCommand(project, new Runnable() { -+ @Override -+ public void run() { -+ doInvoke(project); -+ } -+ }, getText(), null); -+ } -+ }; -+ -+ builder.setTitle(JetBundle.message(""choose.target.class.or.trait.title"")) -+ .setItemChoosenCallback(runnable) -+ .createPopup() -+ .showInBestPositionFor(currentFileEditor); -+ } -+ } -+ -+ private void doInvoke(@NotNull final Project project) { -+ // gather relevant information -+ ClassifierDescriptor ownerTypeDescriptor = selectedReceiverType.getType().getConstructor().getDeclarationDescriptor(); -+ assert ownerTypeDescriptor != null && ownerTypeDescriptor instanceof ClassDescriptor; -+ ownerClassDescriptor = (ClassDescriptor) ownerTypeDescriptor; -+ JetType receiverType = ownerClassDescriptor.getDefaultType(); -+ PsiElement typeDeclaration = BindingContextUtils.classDescriptorToDeclaration(currentFileContext, ownerClassDescriptor); -+ if (typeDeclaration != null && typeDeclaration instanceof JetClass) { -+ ownerClass = (JetClass) typeDeclaration; -+ isExtension = !ownerClass.isWritable(); -+ } else { -+ isExtension = true; -+ } -+ isUnit = returnType.isType() && isUnit(returnType.getType()); -+ -+ JetScope scope; -+ if (isExtension) { -+ NamespaceDescriptor namespaceDescriptor = currentFileContext.get(BindingContext.FILE_TO_NAMESPACE, currentFile); -+ assert namespaceDescriptor != null; -+ scope = namespaceDescriptor.getMemberScope(); -+ } else { -+ assert ownerClassDescriptor instanceof MutableClassDescriptor; -+ scope = ((MutableClassDescriptor) ownerClassDescriptor).getScopeForMemberResolution(); -+ } -+ -+ // figure out type substitutions for type parameters -+ List classTypeParameters = receiverType.getArguments(); -+ List ownerTypeArguments = selectedReceiverType.getType().getArguments(); -+ assert ownerTypeArguments.size() == classTypeParameters.size(); -+ TypeSubstitution[] substitutions = new TypeSubstitution[classTypeParameters.size()]; -+ for (int i = 0; i < substitutions.length; i++) { -+ substitutions[i] = new TypeSubstitution(ownerTypeArguments.get(i).getType(), classTypeParameters.get(i).getType()); -+ } -+ for (Parameter parameter : parameters) { -+ parameter.getType().computeTypeCandidates(currentFileContext, substitutions, scope); -+ } -+ if (!isUnit) { -+ returnType.computeTypeCandidates(currentFileContext, substitutions, scope); -+ } -+ -+ // now that we have done substitutions, we can throw it away -+ selectedReceiverType = new TypeCandidate(receiverType, scope); -+ -+ // figure out type parameter renames to avoid conflicts -+ typeParameterNameMap = getTypeParameterRenames(scope); -+ for (Parameter parameter : parameters) { -+ parameter.getType().renderTypeCandidates(typeParameterNameMap); -+ } -+ if (!isUnit) { -+ returnType.renderTypeCandidates(typeParameterNameMap); -+ } -+ selectedReceiverType.render(typeParameterNameMap); -+ -+ ApplicationManager.getApplication().runWriteAction(new Runnable() { -+ @Override -+ public void run() { -+ JetNamedFunction func = createFunctionSkeleton(project); -+ buildAndRunTemplate(project, func); -+ } -+ }); -+ } -+ -+ private JetNamedFunction createFunctionSkeleton(@NotNull Project project) { -+ JetNamedFunction func; -+ String[] parameterStrings = new String[parameters.size()]; -+ for (int i = 0; i < parameterStrings.length; i++) { -+ parameterStrings[i] = ""p"" + i + "": Any""; -+ } -+ String parametersString = StringUtil.join(parameterStrings,"", ""); -+ String returnTypeString = isUnit ? """" : "": Any""; -+ if (isExtension) { // create as extension function -+ String ownerTypeString = selectedReceiverType.getRenderedType(); -+ String methodText = String.format(""fun %s.%s(%s)%s { }"", ownerTypeString, methodName, parametersString, returnTypeString); -+ func = JetPsiFactory.createFunction(project, methodText); -+ containingFile = currentFile; -+ containingFileEditor = currentFileEditor; -+ func = (JetNamedFunction) currentFile.add(func);","Return immediately to avoid reassignment. -",Why is this needed? Looks like a duplicate file. -104,"@@ -0,0 +1,1391 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.codeInsight.lookup.LookupElement; -+import com.intellij.codeInsight.lookup.LookupElementBuilder; -+import com.intellij.codeInsight.template.*; -+import com.intellij.codeInsight.template.impl.TemplateImpl; -+import com.intellij.codeInsight.template.impl.Variable; -+import com.intellij.ide.fileTemplates.FileTemplate; -+import com.intellij.ide.fileTemplates.FileTemplateManager; -+import com.intellij.ide.util.PsiElementListCellRenderer; -+import com.intellij.openapi.application.ApplicationManager; -+import com.intellij.openapi.command.CommandProcessor; -+import com.intellij.openapi.editor.CaretModel; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.fileEditor.FileEditorManager; -+import com.intellij.openapi.progress.ProcessCanceledException; -+import com.intellij.openapi.project.Project; -+import com.intellij.openapi.ui.popup.PopupChooserBuilder; -+import com.intellij.openapi.util.TextRange; -+import com.intellij.openapi.util.text.StringUtil; -+import com.intellij.openapi.vfs.VirtualFile; -+import com.intellij.psi.PsiDocumentManager; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.PsiReference; -+import com.intellij.psi.search.SearchScope; -+import com.intellij.psi.util.PsiTreeUtil; -+import com.intellij.refactoring.psi.SearchUtils; -+import com.intellij.ui.components.JBList; -+import com.intellij.util.ArrayUtil; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NonNls; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.descriptors.*; -+import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1; -+import org.jetbrains.jet.lang.diagnostics.Errors; -+import org.jetbrains.jet.lang.psi.*; -+import org.jetbrains.jet.lang.resolve.BindingContext; -+import org.jetbrains.jet.lang.resolve.BindingContextUtils; -+import org.jetbrains.jet.lang.resolve.DescriptorUtils; -+import org.jetbrains.jet.lang.resolve.name.Name; -+import org.jetbrains.jet.lang.resolve.scopes.JetScope; -+import org.jetbrains.jet.lang.types.*; -+import org.jetbrains.jet.lang.types.checker.JetTypeChecker; -+import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; -+import org.jetbrains.jet.plugin.JetBundle; -+import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening; -+import org.jetbrains.jet.plugin.presentation.JetLightClassListCellRenderer; -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; -+import org.jetbrains.jet.plugin.refactoring.JetNameSuggester; -+import org.jetbrains.jet.plugin.refactoring.JetNameValidator; -+import org.jetbrains.jet.plugin.references.JetSimpleNameReference; -+import org.jetbrains.jet.renderer.DescriptorRenderer; -+ -+import javax.swing.*; -+import java.util.*; -+import java.util.regex.Matcher; -+import java.util.regex.Pattern; -+ -+public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { -+ private static final String TYPE_PARAMETER_LIST_VARIABLE_NAME = ""typeParameterList""; -+ private static final String TEMPLATE_FROM_USAGE_METHOD_BODY = ""New Kotlin Method Body.kt""; -+ private static final Pattern COMPONENT_FUNCTION_PATTERN = Pattern.compile(""^component(\\d+)$""); -+ -+ /** -+ * Represents a single choice for a type (e.g. parameter type or return type). -+ */ -+ private static class TypeCandidate { -+ private final JetType type; -+ private final TypeParameterDescriptor[] typeParameters; -+ private String renderedType; -+ private String[] typeParameterNames; -+ -+ public TypeCandidate(@NotNull JetType type) { -+ this.type = type; -+ Set typeParametersInType = getTypeParametersInType(type); -+ typeParameters = typeParametersInType.toArray(new TypeParameterDescriptor[typeParametersInType.size()]); -+ renderedType = renderTypeShort(type, Collections.emptyMap()); -+ } -+ -+ public TypeCandidate(@NotNull JetType type, @NotNull JetScope scope) { -+ this.type = type; -+ typeParameters = getTypeParameterNamesNotInScope(getTypeParametersInType(type), scope); -+ } -+ -+ public void render(@NotNull Map typeParameterNameMap) { -+ renderedType = renderTypeShort(type, typeParameterNameMap); -+ typeParameterNames = new String[typeParameters.length]; -+ int i = 0; -+ for (TypeParameterDescriptor typeParameter : typeParameters) { -+ typeParameterNames[i] = typeParameterNameMap.get(typeParameter); -+ i++; -+ } -+ } -+ -+ @NotNull JetType getType() { -+ return type; -+ } -+ -+ @NotNull -+ public String getRenderedType() { -+ assert renderedType != null : ""call render() first""; -+ return renderedType; -+ } -+ -+ @NotNull -+ public String[] getTypeParameterNames() { -+ assert typeParameterNames != null : ""call render() first""; -+ return typeParameterNames; -+ } -+ -+ @NotNull -+ public TypeParameterDescriptor[] getTypeParameters() { -+ return typeParameters; -+ } -+ } -+ -+ /** -+ * Represents a concrete type or a set of types yet to be inferred from an expression. -+ */ -+ private static class TypeOrExpressionThereof { -+ private final JetExpression expressionOfType; -+ private final JetType type; -+ private final Variance variance; -+ private TypeCandidate[] typeCandidates; -+ private String[] cachedNameCandidatesFromExpression; -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType) { -+ this(expressionOfType, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType, Variance variance) { -+ this(expressionOfType, null, variance); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type) { -+ this(type, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type, Variance variance) { -+ this(null, type, variance); -+ } -+ -+ private TypeOrExpressionThereof(@Nullable JetExpression expressionOfType, @Nullable JetType type, Variance variance) { -+ this.expressionOfType = expressionOfType; -+ this.type = type; -+ this.variance = variance; -+ } -+ -+ public boolean isType() { -+ return this.type != null; -+ } -+ -+ @NotNull -+ public JetType getType() { -+ assert this.type != null; -+ return this.type; -+ } -+ -+ @NotNull -+ private List getPossibleTypes(BindingContext context) { -+ List types = new ArrayList(); -+ if (isType()) { -+ assert type != null : ""!isType() means type == null && expressionOfType != null""; -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ for (JetType type : guessTypeForExpression(expressionOfType, context)) { -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } -+ } -+ return types; -+ } -+ -+ public void computeTypeCandidates(@NotNull BindingContext context) { -+ Collection types = getPossibleTypes(context); -+ -+ typeCandidates = new TypeCandidate[types.size()]; -+ int i = 0; -+ for (JetType type : types) { -+ typeCandidates[i] = new TypeCandidate(type); -+ i++; -+ } -+ } -+ -+ public void computeTypeCandidates( -+ @NotNull BindingContext context, -+ @NotNull TypeSubstitution[] substitutions, -+ @NotNull JetScope scope -+ ) { -+ List types = getPossibleTypes(context); -+ Collections.reverse(types); // reverse and reverse back later, so that things added below are added at the front -+ -+ Set newTypes = new LinkedHashSet(types); -+ for (TypeSubstitution substitution : substitutions) { // each substitution can be applied or not, so we offer all options -+ List toAdd = new ArrayList(); -+ List toRemove = new ArrayList(); -+ for (JetType type : newTypes) { -+ toAdd.add(substituteType(type, substitution, variance)); -+ // substitution.byType are type arguments, but they cannot already occur in the type before substitution -+ if (containsType(type, substitution.getByType())) { -+ toRemove.add(type); -+ } -+ } -+ newTypes.addAll(toAdd); -+ newTypes.removeAll(toRemove); -+ } -+ -+ if (newTypes.isEmpty()) { -+ newTypes.add(KotlinBuiltIns.getInstance().getAnyType()); -+ } -+ -+ typeCandidates = new TypeCandidate[newTypes.size()]; -+ int i = typeCandidates.length - 1; // reverse order (see explanation above) -+ for (JetType type : newTypes) { -+ typeCandidates[i] = new TypeCandidate(type, scope); -+ i--; -+ } -+ } -+ -+ @NotNull -+ public TypeCandidate[] getTypeCandidates() { -+ assert typeCandidates != null : ""call computeTypeCandidates() first""; -+ return typeCandidates; -+ } -+ -+ public void renderTypeCandidates(@NotNull Map typeParameterNameMap) { -+ for (TypeCandidate candidate : typeCandidates) { -+ candidate.render(typeParameterNameMap); -+ } -+ } -+ -+ @NotNull -+ public String[] getPossibleNamesFromExpression() { -+ if (cachedNameCandidatesFromExpression != null) return cachedNameCandidatesFromExpression; -+ if (isType()) { -+ cachedNameCandidatesFromExpression = ArrayUtil.EMPTY_STRING_ARRAY; -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ JetNameValidator dummyValidator = new DummyJetNameValidator(expressionOfType.getProject()); -+ cachedNameCandidatesFromExpression = JetNameSuggester.suggestNamesForExpression(expressionOfType, dummyValidator); -+ } -+ return cachedNameCandidatesFromExpression; -+ } -+ } -+ -+ /** -+ * Encapsulates information about a method parameter that is going to be created. -+ */ -+ private static class Parameter { -+ private final String preferredName; -+ private final TypeOrExpressionThereof type; -+ -+ public Parameter(@Nullable(""no preferred name"") String preferredName, TypeOrExpressionThereof type) { -+ this.preferredName = preferredName; -+ this.type = type; -+ } -+ -+ public String getPreferredName() { -+ return preferredName; -+ } -+ -+ public TypeOrExpressionThereof getType() { -+ return type; -+ } -+ } -+ -+ /** -+ * Special Expression for parameter names based on its type. -+ */ -+ private static class ParameterNameExpression extends Expression { -+ private final String[] names; -+ private final Map parameterTypeToNamesMap; -+ -+ public ParameterNameExpression(@NotNull String[] names, @NotNull Map parameterTypeToNamesMap) { -+ for (String name : names) { -+ assert name != null && !name.isEmpty(); -+ } -+ this.names = names; -+ this.parameterTypeToNamesMap = parameterTypeToNamesMap; -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ LookupElement[] lookupItems = calculateLookupItems(context); -+ if (lookupItems.length == 0) return new TextResult(""""); -+ -+ return new TextResult(lookupItems[0].getLookupString()); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ Set names = new LinkedHashSet(); -+ Collections.addAll(names, this.names); -+ -+ // find the parameter list -+ Project project = context.getProject(); -+ int offset = context.getStartOffset(); -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ Editor editor = context.getEditor(); -+ assert editor != null; -+ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); -+ assert file != null && file instanceof JetFile; -+ PsiElement elementAt = file.findElementAt(offset); -+ JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); -+ if (func == null) return new LookupElement[0]; -+ JetParameterList parameterList = func.getValueParameterList(); -+ assert parameterList != null; -+ -+ // add names based on selected type -+ JetParameter parameter = PsiTreeUtil.getParentOfType(elementAt, JetParameter.class); -+ if (parameter != null) { -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ String[] suggestedNamesBasedOnType = parameterTypeToNamesMap.get(parameterTypeRef.getText()); -+ if (suggestedNamesBasedOnType != null) { -+ Collections.addAll(names, suggestedNamesBasedOnType); -+ } -+ } -+ } -+ -+ // remember other parameter names for later use -+ Set parameterNames = new HashSet(); -+ for (JetParameter jetParameter : parameterList.getParameters()) { -+ if (jetParameter == parameter || jetParameter.getName() == null) continue; -+ parameterNames.add(jetParameter.getName()); -+ } -+ -+ // add fallback parameter name -+ if (names.isEmpty()) { -+ names.add(""arg""); -+ } -+ -+ // ensure there are no conflicts -+ List lookupElements = new ArrayList(); -+ for (String name : names) { -+ name = getNextAvailableName(name, parameterNames); -+ lookupElements.add(LookupElementBuilder.create(name)); -+ } -+ -+ // create and return -+ return lookupElements.toArray(new LookupElement[lookupElements.size()]); -+ } -+ } -+ -+ /** -+ * An Expression for type references. -+ */ -+ private static class TypeExpression extends Expression { -+ private final TypeOrExpressionThereof type; -+ private @NotNull LookupElement[] cachedLookupElements; -+ -+ public TypeExpression(@NotNull TypeOrExpressionThereof type) { -+ this.type = type; -+ TypeCandidate[] candidates = type.getTypeCandidates(); -+ cachedLookupElements = new LookupElement[candidates.length]; -+ for (int i = 0; i < candidates.length; i++) { -+ cachedLookupElements[i] = LookupElementBuilder.create(candidates[i], candidates[i].getRenderedType()); -+ } -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ LookupElement[] lookupItems = calculateLookupItems(context); -+ if (lookupItems.length == 0) return new TextResult(""""); -+ -+ return new TextResult(lookupItems[0].getLookupString()); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ return cachedLookupElements; -+ } -+ -+ @NotNull -+ public TypeOrExpressionThereof getType() { -+ return type; -+ } -+ -+ @Nullable(""can't be found"") -+ public JetType getTypeFromSelection(@NotNull String selection) { -+ TypeCandidate[] options = type.getTypeCandidates(); -+ for (TypeCandidate option : options) { -+ if (option.getRenderedType().equals(selection)) { -+ return option.getType(); -+ } -+ } -+ return null; -+ } -+ } -+ -+ /** -+ * A sort-of dummy Expression for parameter lists, to allow us to update the parameter list as the user makes selections. -+ */ -+ private static class TypeParameterListExpression extends Expression { -+ private final String[] typeParameterNamesFromReceiverType; -+ private final Map parameterTypeToTypeParameterNamesMap; -+ -+ public TypeParameterListExpression( -+ @NotNull String[] typeParameterNamesFromReceiverType, -+ @NotNull Map typeParametersMap -+ ) { -+ this.typeParameterNamesFromReceiverType = typeParameterNamesFromReceiverType; -+ this.parameterTypeToTypeParameterNamesMap = typeParametersMap; -+ } -+ -+ @NotNull -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ Project project = context.getProject(); -+ int offset = context.getStartOffset(); -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ Editor editor = context.getEditor(); -+ assert editor != null; -+ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); -+ assert file != null && file instanceof JetFile; -+ PsiElement elementAt = file.findElementAt(offset); -+ JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); -+ if (func == null) { -+ return new TextResult(""""); -+ } -+ List parameters = func.getValueParameters(); -+ -+ Set typeParameterNames = new LinkedHashSet(); -+ Collections.addAll(typeParameterNames, typeParameterNamesFromReceiverType); -+ for (JetParameter parameter : parameters) { -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ String[] typeParameterNamesFromParameter = parameterTypeToTypeParameterNamesMap.get(parameterTypeRef.getText()); -+ if (typeParameterNamesFromParameter != null) { -+ Collections.addAll(typeParameterNames, typeParameterNamesFromParameter); -+ } -+ } -+ } -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ if (returnTypeRef != null) { -+ String[] typeParameterNamesFromReturnType = parameterTypeToTypeParameterNamesMap.get(returnTypeRef.getText()); -+ if (typeParameterNamesFromReturnType != null) { -+ Collections.addAll(typeParameterNames, typeParameterNamesFromReturnType); -+ } -+ } -+ -+ return typeParameterNames.isEmpty() -+ ? new TextResult("""") -+ : new TextResult("" <"" + StringUtil.join(typeParameterNames, "", "") + "">""); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ return new LookupElement[0]; // do not offer the user any choices -+ } -+ } -+ -+ /** -+ * A JetNameValidator that always succeeds. -+ */ -+ private static class DummyJetNameValidator implements JetNameValidator { -+ private final Project project; -+ -+ public DummyJetNameValidator(Project project) { -+ this.project = project; -+ } -+ -+ @Nullable -+ @Override -+ public String validateName(String name) { -+ return name; -+ } -+ -+ @Override -+ public Project getProject() { -+ return project; -+ } -+ } -+ -+ /** -+ * Encapsulates a single type substitution of a JetType by another JetType. -+ */ -+ private static class TypeSubstitution { -+ private final JetType forType; -+ private final JetType byType; -+ -+ private TypeSubstitution(JetType forType, JetType byType) { -+ this.forType = forType; -+ this.byType = byType; -+ } -+ -+ private JetType getForType() { -+ return forType; -+ } -+ -+ private JetType getByType() { -+ return byType; -+ } -+ } -+ -+ private final String methodName; -+ private final TypeOrExpressionThereof ownerType; -+ private final TypeOrExpressionThereof returnType; -+ private final List parameters; -+ -+ private boolean isUnit; -+ private boolean isExtension; -+ private JetFile currentFile; -+ private JetFile containingFile; -+ private Editor currentFileEditor; -+ private Editor containingFileEditor; -+ private BindingContext currentFileContext; -+ private JetClass ownerClass; -+ private ClassDescriptor ownerClassDescriptor; -+ private TypeCandidate selectedReceiverType; -+ private Map typeParameterNameMap; -+ -+ public CreateMethodFromUsageFix(@NotNull PsiElement element, @NotNull TypeOrExpressionThereof ownerType, @NotNull String methodName, -+ @NotNull TypeOrExpressionThereof returnType, @NotNull List parameters) { -+ super(element); -+ this.methodName = methodName; -+ this.ownerType = ownerType; -+ this.returnType = returnType; -+ this.parameters = parameters; -+ } -+ -+ @NotNull -+ @Override -+ public String getText() { -+ return JetBundle.message(""create.method.from.usage"", methodName); -+ } -+ -+ @Override -+ public void invoke(@NotNull final Project project, Editor editor, PsiFile file) throws IncorrectOperationException { -+ assert file != null && file instanceof JetFile; -+ currentFile = (JetFile) file; -+ currentFileEditor = editor; -+ currentFileContext = AnalyzerFacadeWithCache.analyzeFileWithCache(currentFile).getBindingContext(); -+ -+ ownerType.computeTypeCandidates(currentFileContext); -+ TypeCandidate[] ownerTypeCandidates = ownerType.getTypeCandidates(); -+ assert ownerTypeCandidates.length > 0; -+ if (ownerTypeCandidates.length == 1 || ApplicationManager.getApplication().isUnitTestMode()) { -+ selectedReceiverType = ownerTypeCandidates[0]; -+ doInvoke(project); -+ } else { -+ // class selection -+ List options = new ArrayList(); -+ final Map optionToTypeMap = new HashMap(); -+ for (TypeCandidate ownerTypeCandidate : ownerTypeCandidates) { -+ ClassifierDescriptor possibleClassDescriptor = ownerTypeCandidate.getType().getConstructor().getDeclarationDescriptor(); -+ if (possibleClassDescriptor != null) { -+ String className = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(possibleClassDescriptor.getDefaultType()); -+ DeclarationDescriptor namespaceDescriptor = possibleClassDescriptor.getContainingDeclaration(); -+ String namespace = renderDescriptor(namespaceDescriptor, true); -+ String option = className + "" ("" + namespace + "")""; -+ options.add(option); -+ optionToTypeMap.put(option, ownerTypeCandidate); -+ } -+ } -+ -+ final JList list = new JBList(options); -+ PsiElementListCellRenderer renderer = new JetLightClassListCellRenderer(); -+ list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); -+ list.setCellRenderer(renderer); -+ PopupChooserBuilder builder = new PopupChooserBuilder(list); -+ renderer.installSpeedSearch(builder); -+ -+ Runnable runnable = new Runnable() { -+ @Override -+ public void run() { -+ int index = list.getSelectedIndex(); -+ if (index < 0) return; -+ String option = (String) list.getSelectedValue(); -+ selectedReceiverType = optionToTypeMap.get(option); -+ CommandProcessor.getInstance().executeCommand(project, new Runnable() { -+ @Override -+ public void run() { -+ doInvoke(project); -+ } -+ }, getText(), null); -+ } -+ }; -+ -+ builder.setTitle(JetBundle.message(""choose.target.class.or.trait.title"")) -+ .setItemChoosenCallback(runnable) -+ .createPopup() -+ .showInBestPositionFor(currentFileEditor); -+ } -+ } -+ -+ private void doInvoke(@NotNull final Project project) { -+ // gather relevant information -+ ClassifierDescriptor ownerTypeDescriptor = selectedReceiverType.getType().getConstructor().getDeclarationDescriptor(); -+ assert ownerTypeDescriptor != null && ownerTypeDescriptor instanceof ClassDescriptor; -+ ownerClassDescriptor = (ClassDescriptor) ownerTypeDescriptor; -+ JetType receiverType = ownerClassDescriptor.getDefaultType(); -+ PsiElement typeDeclaration = BindingContextUtils.classDescriptorToDeclaration(currentFileContext, ownerClassDescriptor); -+ if (typeDeclaration != null && typeDeclaration instanceof JetClass) { -+ ownerClass = (JetClass) typeDeclaration; -+ isExtension = !ownerClass.isWritable(); -+ } else { -+ isExtension = true; -+ } -+ isUnit = returnType.isType() && isUnit(returnType.getType()); -+ -+ JetScope scope; -+ if (isExtension) { -+ NamespaceDescriptor namespaceDescriptor = currentFileContext.get(BindingContext.FILE_TO_NAMESPACE, currentFile); -+ assert namespaceDescriptor != null; -+ scope = namespaceDescriptor.getMemberScope(); -+ } else { -+ assert ownerClassDescriptor instanceof MutableClassDescriptor; -+ scope = ((MutableClassDescriptor) ownerClassDescriptor).getScopeForMemberResolution(); -+ } -+ -+ // figure out type substitutions for type parameters -+ List classTypeParameters = receiverType.getArguments(); -+ List ownerTypeArguments = selectedReceiverType.getType().getArguments(); -+ assert ownerTypeArguments.size() == classTypeParameters.size(); -+ TypeSubstitution[] substitutions = new TypeSubstitution[classTypeParameters.size()]; -+ for (int i = 0; i < substitutions.length; i++) { -+ substitutions[i] = new TypeSubstitution(ownerTypeArguments.get(i).getType(), classTypeParameters.get(i).getType()); -+ } -+ for (Parameter parameter : parameters) { -+ parameter.getType().computeTypeCandidates(currentFileContext, substitutions, scope); -+ } -+ if (!isUnit) { -+ returnType.computeTypeCandidates(currentFileContext, substitutions, scope); -+ } -+ -+ // now that we have done substitutions, we can throw it away -+ selectedReceiverType = new TypeCandidate(receiverType, scope); -+ -+ // figure out type parameter renames to avoid conflicts -+ typeParameterNameMap = getTypeParameterRenames(scope); -+ for (Parameter parameter : parameters) { -+ parameter.getType().renderTypeCandidates(typeParameterNameMap); -+ } -+ if (!isUnit) { -+ returnType.renderTypeCandidates(typeParameterNameMap); -+ } -+ selectedReceiverType.render(typeParameterNameMap); -+ -+ ApplicationManager.getApplication().runWriteAction(new Runnable() { -+ @Override -+ public void run() { -+ JetNamedFunction func = createFunctionSkeleton(project); -+ buildAndRunTemplate(project, func); -+ } -+ }); -+ } -+ -+ private JetNamedFunction createFunctionSkeleton(@NotNull Project project) { -+ JetNamedFunction func; -+ String[] parameterStrings = new String[parameters.size()]; -+ for (int i = 0; i < parameterStrings.length; i++) { -+ parameterStrings[i] = ""p"" + i + "": Any""; -+ } -+ String parametersString = StringUtil.join(parameterStrings,"", ""); -+ String returnTypeString = isUnit ? """" : "": Any""; -+ if (isExtension) { // create as extension function -+ String ownerTypeString = selectedReceiverType.getRenderedType(); -+ String methodText = String.format(""fun %s.%s(%s)%s { }"", ownerTypeString, methodName, parametersString, returnTypeString); -+ func = JetPsiFactory.createFunction(project, methodText); -+ containingFile = currentFile; -+ containingFileEditor = currentFileEditor; -+ func = (JetNamedFunction) currentFile.add(func); -+ } else { // create as method -+ String methodText = String.format(""fun %s(%s)%s { }"", methodName, parametersString, returnTypeString); -+ func = JetPsiFactory.createFunction(project, methodText); -+ PsiFile classContainingFile = ownerClass.getContainingFile(); -+ assert classContainingFile instanceof JetFile; -+ containingFile = (JetFile) classContainingFile; -+ -+ VirtualFile virtualFile = containingFile.getVirtualFile(); -+ assert virtualFile != null; -+ FileEditorManager fileEditorManager = FileEditorManager.getInstance(project); -+ fileEditorManager.openFile(virtualFile, true); -+ containingFileEditor = fileEditorManager.getSelectedTextEditor(); -+ -+ JetClassBody classBody = ownerClass.getBody(); -+ if (classBody == null) { -+ classBody = (JetClassBody) ownerClass.add(JetPsiFactory.createEmptyClassBody(project)); -+ ownerClass.addBefore(JetPsiFactory.createWhiteSpace(project), classBody); -+ } -+ PsiElement rBrace = classBody.getRBrace(); -+ assert rBrace != null; -+ func = (JetNamedFunction) classBody.addBefore(func, rBrace);","Return immediately to avoid reassignment. -",Why is this needed? Looks like a duplicate file. -105,"@@ -0,0 +1,1391 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.codeInsight.lookup.LookupElement; -+import com.intellij.codeInsight.lookup.LookupElementBuilder; -+import com.intellij.codeInsight.template.*; -+import com.intellij.codeInsight.template.impl.TemplateImpl; -+import com.intellij.codeInsight.template.impl.Variable; -+import com.intellij.ide.fileTemplates.FileTemplate; -+import com.intellij.ide.fileTemplates.FileTemplateManager; -+import com.intellij.ide.util.PsiElementListCellRenderer; -+import com.intellij.openapi.application.ApplicationManager; -+import com.intellij.openapi.command.CommandProcessor; -+import com.intellij.openapi.editor.CaretModel; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.fileEditor.FileEditorManager; -+import com.intellij.openapi.progress.ProcessCanceledException; -+import com.intellij.openapi.project.Project; -+import com.intellij.openapi.ui.popup.PopupChooserBuilder; -+import com.intellij.openapi.util.TextRange; -+import com.intellij.openapi.util.text.StringUtil; -+import com.intellij.openapi.vfs.VirtualFile; -+import com.intellij.psi.PsiDocumentManager; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.PsiReference; -+import com.intellij.psi.search.SearchScope; -+import com.intellij.psi.util.PsiTreeUtil; -+import com.intellij.refactoring.psi.SearchUtils; -+import com.intellij.ui.components.JBList; -+import com.intellij.util.ArrayUtil; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NonNls; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.descriptors.*; -+import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1; -+import org.jetbrains.jet.lang.diagnostics.Errors; -+import org.jetbrains.jet.lang.psi.*; -+import org.jetbrains.jet.lang.resolve.BindingContext; -+import org.jetbrains.jet.lang.resolve.BindingContextUtils; -+import org.jetbrains.jet.lang.resolve.DescriptorUtils; -+import org.jetbrains.jet.lang.resolve.name.Name; -+import org.jetbrains.jet.lang.resolve.scopes.JetScope; -+import org.jetbrains.jet.lang.types.*; -+import org.jetbrains.jet.lang.types.checker.JetTypeChecker; -+import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; -+import org.jetbrains.jet.plugin.JetBundle; -+import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening; -+import org.jetbrains.jet.plugin.presentation.JetLightClassListCellRenderer; -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; -+import org.jetbrains.jet.plugin.refactoring.JetNameSuggester; -+import org.jetbrains.jet.plugin.refactoring.JetNameValidator; -+import org.jetbrains.jet.plugin.references.JetSimpleNameReference; -+import org.jetbrains.jet.renderer.DescriptorRenderer; -+ -+import javax.swing.*; -+import java.util.*; -+import java.util.regex.Matcher; -+import java.util.regex.Pattern; -+ -+public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { -+ private static final String TYPE_PARAMETER_LIST_VARIABLE_NAME = ""typeParameterList""; -+ private static final String TEMPLATE_FROM_USAGE_METHOD_BODY = ""New Kotlin Method Body.kt""; -+ private static final Pattern COMPONENT_FUNCTION_PATTERN = Pattern.compile(""^component(\\d+)$""); -+ -+ /** -+ * Represents a single choice for a type (e.g. parameter type or return type). -+ */ -+ private static class TypeCandidate { -+ private final JetType type; -+ private final TypeParameterDescriptor[] typeParameters; -+ private String renderedType; -+ private String[] typeParameterNames; -+ -+ public TypeCandidate(@NotNull JetType type) { -+ this.type = type; -+ Set typeParametersInType = getTypeParametersInType(type); -+ typeParameters = typeParametersInType.toArray(new TypeParameterDescriptor[typeParametersInType.size()]); -+ renderedType = renderTypeShort(type, Collections.emptyMap()); -+ } -+ -+ public TypeCandidate(@NotNull JetType type, @NotNull JetScope scope) { -+ this.type = type; -+ typeParameters = getTypeParameterNamesNotInScope(getTypeParametersInType(type), scope); -+ } -+ -+ public void render(@NotNull Map typeParameterNameMap) { -+ renderedType = renderTypeShort(type, typeParameterNameMap); -+ typeParameterNames = new String[typeParameters.length]; -+ int i = 0; -+ for (TypeParameterDescriptor typeParameter : typeParameters) { -+ typeParameterNames[i] = typeParameterNameMap.get(typeParameter); -+ i++; -+ } -+ } -+ -+ @NotNull JetType getType() { -+ return type; -+ } -+ -+ @NotNull -+ public String getRenderedType() { -+ assert renderedType != null : ""call render() first""; -+ return renderedType; -+ } -+ -+ @NotNull -+ public String[] getTypeParameterNames() { -+ assert typeParameterNames != null : ""call render() first""; -+ return typeParameterNames; -+ } -+ -+ @NotNull -+ public TypeParameterDescriptor[] getTypeParameters() { -+ return typeParameters; -+ } -+ } -+ -+ /** -+ * Represents a concrete type or a set of types yet to be inferred from an expression. -+ */ -+ private static class TypeOrExpressionThereof { -+ private final JetExpression expressionOfType; -+ private final JetType type; -+ private final Variance variance; -+ private TypeCandidate[] typeCandidates; -+ private String[] cachedNameCandidatesFromExpression; -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType) { -+ this(expressionOfType, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType, Variance variance) { -+ this(expressionOfType, null, variance); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type) { -+ this(type, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type, Variance variance) { -+ this(null, type, variance); -+ } -+ -+ private TypeOrExpressionThereof(@Nullable JetExpression expressionOfType, @Nullable JetType type, Variance variance) { -+ this.expressionOfType = expressionOfType; -+ this.type = type; -+ this.variance = variance; -+ } -+ -+ public boolean isType() { -+ return this.type != null; -+ } -+ -+ @NotNull -+ public JetType getType() { -+ assert this.type != null; -+ return this.type; -+ } -+ -+ @NotNull -+ private List getPossibleTypes(BindingContext context) { -+ List types = new ArrayList(); -+ if (isType()) { -+ assert type != null : ""!isType() means type == null && expressionOfType != null""; -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ for (JetType type : guessTypeForExpression(expressionOfType, context)) { -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } -+ } -+ return types; -+ } -+ -+ public void computeTypeCandidates(@NotNull BindingContext context) { -+ Collection types = getPossibleTypes(context); -+ -+ typeCandidates = new TypeCandidate[types.size()]; -+ int i = 0; -+ for (JetType type : types) { -+ typeCandidates[i] = new TypeCandidate(type); -+ i++; -+ } -+ } -+ -+ public void computeTypeCandidates( -+ @NotNull BindingContext context, -+ @NotNull TypeSubstitution[] substitutions, -+ @NotNull JetScope scope -+ ) { -+ List types = getPossibleTypes(context); -+ Collections.reverse(types); // reverse and reverse back later, so that things added below are added at the front -+ -+ Set newTypes = new LinkedHashSet(types); -+ for (TypeSubstitution substitution : substitutions) { // each substitution can be applied or not, so we offer all options -+ List toAdd = new ArrayList(); -+ List toRemove = new ArrayList(); -+ for (JetType type : newTypes) { -+ toAdd.add(substituteType(type, substitution, variance)); -+ // substitution.byType are type arguments, but they cannot already occur in the type before substitution -+ if (containsType(type, substitution.getByType())) { -+ toRemove.add(type); -+ } -+ } -+ newTypes.addAll(toAdd); -+ newTypes.removeAll(toRemove); -+ } -+ -+ if (newTypes.isEmpty()) { -+ newTypes.add(KotlinBuiltIns.getInstance().getAnyType()); -+ } -+ -+ typeCandidates = new TypeCandidate[newTypes.size()]; -+ int i = typeCandidates.length - 1; // reverse order (see explanation above) -+ for (JetType type : newTypes) { -+ typeCandidates[i] = new TypeCandidate(type, scope); -+ i--; -+ } -+ } -+ -+ @NotNull -+ public TypeCandidate[] getTypeCandidates() { -+ assert typeCandidates != null : ""call computeTypeCandidates() first""; -+ return typeCandidates; -+ } -+ -+ public void renderTypeCandidates(@NotNull Map typeParameterNameMap) { -+ for (TypeCandidate candidate : typeCandidates) { -+ candidate.render(typeParameterNameMap); -+ } -+ } -+ -+ @NotNull -+ public String[] getPossibleNamesFromExpression() { -+ if (cachedNameCandidatesFromExpression != null) return cachedNameCandidatesFromExpression; -+ if (isType()) { -+ cachedNameCandidatesFromExpression = ArrayUtil.EMPTY_STRING_ARRAY; -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ JetNameValidator dummyValidator = new DummyJetNameValidator(expressionOfType.getProject()); -+ cachedNameCandidatesFromExpression = JetNameSuggester.suggestNamesForExpression(expressionOfType, dummyValidator); -+ } -+ return cachedNameCandidatesFromExpression; -+ } -+ } -+ -+ /** -+ * Encapsulates information about a method parameter that is going to be created. -+ */ -+ private static class Parameter { -+ private final String preferredName; -+ private final TypeOrExpressionThereof type; -+ -+ public Parameter(@Nullable(""no preferred name"") String preferredName, TypeOrExpressionThereof type) { -+ this.preferredName = preferredName; -+ this.type = type; -+ } -+ -+ public String getPreferredName() { -+ return preferredName; -+ } -+ -+ public TypeOrExpressionThereof getType() { -+ return type; -+ } -+ } -+ -+ /** -+ * Special Expression for parameter names based on its type. -+ */ -+ private static class ParameterNameExpression extends Expression { -+ private final String[] names; -+ private final Map parameterTypeToNamesMap; -+ -+ public ParameterNameExpression(@NotNull String[] names, @NotNull Map parameterTypeToNamesMap) { -+ for (String name : names) { -+ assert name != null && !name.isEmpty(); -+ } -+ this.names = names; -+ this.parameterTypeToNamesMap = parameterTypeToNamesMap; -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ LookupElement[] lookupItems = calculateLookupItems(context); -+ if (lookupItems.length == 0) return new TextResult(""""); -+ -+ return new TextResult(lookupItems[0].getLookupString()); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ Set names = new LinkedHashSet(); -+ Collections.addAll(names, this.names); -+ -+ // find the parameter list -+ Project project = context.getProject(); -+ int offset = context.getStartOffset(); -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ Editor editor = context.getEditor(); -+ assert editor != null; -+ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); -+ assert file != null && file instanceof JetFile; -+ PsiElement elementAt = file.findElementAt(offset); -+ JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); -+ if (func == null) return new LookupElement[0]; -+ JetParameterList parameterList = func.getValueParameterList(); -+ assert parameterList != null; -+ -+ // add names based on selected type -+ JetParameter parameter = PsiTreeUtil.getParentOfType(elementAt, JetParameter.class); -+ if (parameter != null) { -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ String[] suggestedNamesBasedOnType = parameterTypeToNamesMap.get(parameterTypeRef.getText()); -+ if (suggestedNamesBasedOnType != null) { -+ Collections.addAll(names, suggestedNamesBasedOnType); -+ } -+ } -+ } -+ -+ // remember other parameter names for later use -+ Set parameterNames = new HashSet(); -+ for (JetParameter jetParameter : parameterList.getParameters()) { -+ if (jetParameter == parameter || jetParameter.getName() == null) continue; -+ parameterNames.add(jetParameter.getName()); -+ } -+ -+ // add fallback parameter name -+ if (names.isEmpty()) { -+ names.add(""arg""); -+ } -+ -+ // ensure there are no conflicts -+ List lookupElements = new ArrayList(); -+ for (String name : names) { -+ name = getNextAvailableName(name, parameterNames); -+ lookupElements.add(LookupElementBuilder.create(name)); -+ } -+ -+ // create and return -+ return lookupElements.toArray(new LookupElement[lookupElements.size()]); -+ } -+ } -+ -+ /** -+ * An Expression for type references. -+ */ -+ private static class TypeExpression extends Expression { -+ private final TypeOrExpressionThereof type; -+ private @NotNull LookupElement[] cachedLookupElements; -+ -+ public TypeExpression(@NotNull TypeOrExpressionThereof type) { -+ this.type = type; -+ TypeCandidate[] candidates = type.getTypeCandidates(); -+ cachedLookupElements = new LookupElement[candidates.length]; -+ for (int i = 0; i < candidates.length; i++) { -+ cachedLookupElements[i] = LookupElementBuilder.create(candidates[i], candidates[i].getRenderedType()); -+ } -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ LookupElement[] lookupItems = calculateLookupItems(context); -+ if (lookupItems.length == 0) return new TextResult(""""); -+ -+ return new TextResult(lookupItems[0].getLookupString()); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ return cachedLookupElements; -+ } -+ -+ @NotNull -+ public TypeOrExpressionThereof getType() { -+ return type; -+ } -+ -+ @Nullable(""can't be found"") -+ public JetType getTypeFromSelection(@NotNull String selection) { -+ TypeCandidate[] options = type.getTypeCandidates(); -+ for (TypeCandidate option : options) { -+ if (option.getRenderedType().equals(selection)) { -+ return option.getType(); -+ } -+ } -+ return null; -+ } -+ } -+ -+ /** -+ * A sort-of dummy Expression for parameter lists, to allow us to update the parameter list as the user makes selections. -+ */ -+ private static class TypeParameterListExpression extends Expression { -+ private final String[] typeParameterNamesFromReceiverType; -+ private final Map parameterTypeToTypeParameterNamesMap; -+ -+ public TypeParameterListExpression( -+ @NotNull String[] typeParameterNamesFromReceiverType, -+ @NotNull Map typeParametersMap -+ ) { -+ this.typeParameterNamesFromReceiverType = typeParameterNamesFromReceiverType; -+ this.parameterTypeToTypeParameterNamesMap = typeParametersMap; -+ } -+ -+ @NotNull -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ Project project = context.getProject(); -+ int offset = context.getStartOffset(); -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ Editor editor = context.getEditor(); -+ assert editor != null; -+ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); -+ assert file != null && file instanceof JetFile; -+ PsiElement elementAt = file.findElementAt(offset); -+ JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); -+ if (func == null) { -+ return new TextResult(""""); -+ } -+ List parameters = func.getValueParameters(); -+ -+ Set typeParameterNames = new LinkedHashSet(); -+ Collections.addAll(typeParameterNames, typeParameterNamesFromReceiverType); -+ for (JetParameter parameter : parameters) { -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ String[] typeParameterNamesFromParameter = parameterTypeToTypeParameterNamesMap.get(parameterTypeRef.getText()); -+ if (typeParameterNamesFromParameter != null) { -+ Collections.addAll(typeParameterNames, typeParameterNamesFromParameter); -+ } -+ } -+ } -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ if (returnTypeRef != null) { -+ String[] typeParameterNamesFromReturnType = parameterTypeToTypeParameterNamesMap.get(returnTypeRef.getText()); -+ if (typeParameterNamesFromReturnType != null) { -+ Collections.addAll(typeParameterNames, typeParameterNamesFromReturnType); -+ } -+ } -+ -+ return typeParameterNames.isEmpty() -+ ? new TextResult("""") -+ : new TextResult("" <"" + StringUtil.join(typeParameterNames, "", "") + "">""); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ return new LookupElement[0]; // do not offer the user any choices -+ } -+ } -+ -+ /** -+ * A JetNameValidator that always succeeds. -+ */ -+ private static class DummyJetNameValidator implements JetNameValidator { -+ private final Project project; -+ -+ public DummyJetNameValidator(Project project) { -+ this.project = project; -+ } -+ -+ @Nullable -+ @Override -+ public String validateName(String name) { -+ return name; -+ } -+ -+ @Override -+ public Project getProject() { -+ return project; -+ } -+ } -+ -+ /** -+ * Encapsulates a single type substitution of a JetType by another JetType. -+ */ -+ private static class TypeSubstitution { -+ private final JetType forType; -+ private final JetType byType; -+ -+ private TypeSubstitution(JetType forType, JetType byType) { -+ this.forType = forType; -+ this.byType = byType; -+ } -+ -+ private JetType getForType() { -+ return forType; -+ } -+ -+ private JetType getByType() { -+ return byType; -+ } -+ } -+ -+ private final String methodName; -+ private final TypeOrExpressionThereof ownerType; -+ private final TypeOrExpressionThereof returnType; -+ private final List parameters; -+ -+ private boolean isUnit; -+ private boolean isExtension; -+ private JetFile currentFile; -+ private JetFile containingFile; -+ private Editor currentFileEditor; -+ private Editor containingFileEditor; -+ private BindingContext currentFileContext; -+ private JetClass ownerClass; -+ private ClassDescriptor ownerClassDescriptor; -+ private TypeCandidate selectedReceiverType; -+ private Map typeParameterNameMap; -+ -+ public CreateMethodFromUsageFix(@NotNull PsiElement element, @NotNull TypeOrExpressionThereof ownerType, @NotNull String methodName, -+ @NotNull TypeOrExpressionThereof returnType, @NotNull List parameters) { -+ super(element); -+ this.methodName = methodName; -+ this.ownerType = ownerType; -+ this.returnType = returnType; -+ this.parameters = parameters; -+ } -+ -+ @NotNull -+ @Override -+ public String getText() { -+ return JetBundle.message(""create.method.from.usage"", methodName); -+ } -+ -+ @Override -+ public void invoke(@NotNull final Project project, Editor editor, PsiFile file) throws IncorrectOperationException { -+ assert file != null && file instanceof JetFile; -+ currentFile = (JetFile) file; -+ currentFileEditor = editor; -+ currentFileContext = AnalyzerFacadeWithCache.analyzeFileWithCache(currentFile).getBindingContext(); -+ -+ ownerType.computeTypeCandidates(currentFileContext); -+ TypeCandidate[] ownerTypeCandidates = ownerType.getTypeCandidates(); -+ assert ownerTypeCandidates.length > 0; -+ if (ownerTypeCandidates.length == 1 || ApplicationManager.getApplication().isUnitTestMode()) { -+ selectedReceiverType = ownerTypeCandidates[0]; -+ doInvoke(project); -+ } else { -+ // class selection -+ List options = new ArrayList(); -+ final Map optionToTypeMap = new HashMap(); -+ for (TypeCandidate ownerTypeCandidate : ownerTypeCandidates) { -+ ClassifierDescriptor possibleClassDescriptor = ownerTypeCandidate.getType().getConstructor().getDeclarationDescriptor(); -+ if (possibleClassDescriptor != null) { -+ String className = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(possibleClassDescriptor.getDefaultType()); -+ DeclarationDescriptor namespaceDescriptor = possibleClassDescriptor.getContainingDeclaration(); -+ String namespace = renderDescriptor(namespaceDescriptor, true); -+ String option = className + "" ("" + namespace + "")""; -+ options.add(option); -+ optionToTypeMap.put(option, ownerTypeCandidate); -+ } -+ } -+ -+ final JList list = new JBList(options); -+ PsiElementListCellRenderer renderer = new JetLightClassListCellRenderer(); -+ list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); -+ list.setCellRenderer(renderer); -+ PopupChooserBuilder builder = new PopupChooserBuilder(list); -+ renderer.installSpeedSearch(builder); -+ -+ Runnable runnable = new Runnable() { -+ @Override -+ public void run() { -+ int index = list.getSelectedIndex(); -+ if (index < 0) return; -+ String option = (String) list.getSelectedValue(); -+ selectedReceiverType = optionToTypeMap.get(option); -+ CommandProcessor.getInstance().executeCommand(project, new Runnable() { -+ @Override -+ public void run() { -+ doInvoke(project); -+ } -+ }, getText(), null); -+ } -+ }; -+ -+ builder.setTitle(JetBundle.message(""choose.target.class.or.trait.title"")) -+ .setItemChoosenCallback(runnable) -+ .createPopup() -+ .showInBestPositionFor(currentFileEditor); -+ } -+ } -+ -+ private void doInvoke(@NotNull final Project project) { -+ // gather relevant information -+ ClassifierDescriptor ownerTypeDescriptor = selectedReceiverType.getType().getConstructor().getDeclarationDescriptor(); -+ assert ownerTypeDescriptor != null && ownerTypeDescriptor instanceof ClassDescriptor; -+ ownerClassDescriptor = (ClassDescriptor) ownerTypeDescriptor; -+ JetType receiverType = ownerClassDescriptor.getDefaultType(); -+ PsiElement typeDeclaration = BindingContextUtils.classDescriptorToDeclaration(currentFileContext, ownerClassDescriptor); -+ if (typeDeclaration != null && typeDeclaration instanceof JetClass) { -+ ownerClass = (JetClass) typeDeclaration; -+ isExtension = !ownerClass.isWritable(); -+ } else { -+ isExtension = true; -+ } -+ isUnit = returnType.isType() && isUnit(returnType.getType()); -+ -+ JetScope scope; -+ if (isExtension) { -+ NamespaceDescriptor namespaceDescriptor = currentFileContext.get(BindingContext.FILE_TO_NAMESPACE, currentFile); -+ assert namespaceDescriptor != null; -+ scope = namespaceDescriptor.getMemberScope(); -+ } else { -+ assert ownerClassDescriptor instanceof MutableClassDescriptor; -+ scope = ((MutableClassDescriptor) ownerClassDescriptor).getScopeForMemberResolution(); -+ } -+ -+ // figure out type substitutions for type parameters -+ List classTypeParameters = receiverType.getArguments(); -+ List ownerTypeArguments = selectedReceiverType.getType().getArguments(); -+ assert ownerTypeArguments.size() == classTypeParameters.size(); -+ TypeSubstitution[] substitutions = new TypeSubstitution[classTypeParameters.size()]; -+ for (int i = 0; i < substitutions.length; i++) { -+ substitutions[i] = new TypeSubstitution(ownerTypeArguments.get(i).getType(), classTypeParameters.get(i).getType()); -+ } -+ for (Parameter parameter : parameters) { -+ parameter.getType().computeTypeCandidates(currentFileContext, substitutions, scope); -+ } -+ if (!isUnit) { -+ returnType.computeTypeCandidates(currentFileContext, substitutions, scope); -+ } -+ -+ // now that we have done substitutions, we can throw it away -+ selectedReceiverType = new TypeCandidate(receiverType, scope); -+ -+ // figure out type parameter renames to avoid conflicts -+ typeParameterNameMap = getTypeParameterRenames(scope); -+ for (Parameter parameter : parameters) { -+ parameter.getType().renderTypeCandidates(typeParameterNameMap); -+ } -+ if (!isUnit) { -+ returnType.renderTypeCandidates(typeParameterNameMap); -+ } -+ selectedReceiverType.render(typeParameterNameMap); -+ -+ ApplicationManager.getApplication().runWriteAction(new Runnable() { -+ @Override -+ public void run() { -+ JetNamedFunction func = createFunctionSkeleton(project); -+ buildAndRunTemplate(project, func); -+ } -+ }); -+ } -+ -+ private JetNamedFunction createFunctionSkeleton(@NotNull Project project) { -+ JetNamedFunction func; -+ String[] parameterStrings = new String[parameters.size()]; -+ for (int i = 0; i < parameterStrings.length; i++) { -+ parameterStrings[i] = ""p"" + i + "": Any""; -+ } -+ String parametersString = StringUtil.join(parameterStrings,"", ""); -+ String returnTypeString = isUnit ? """" : "": Any""; -+ if (isExtension) { // create as extension function -+ String ownerTypeString = selectedReceiverType.getRenderedType(); -+ String methodText = String.format(""fun %s.%s(%s)%s { }"", ownerTypeString, methodName, parametersString, returnTypeString); -+ func = JetPsiFactory.createFunction(project, methodText); -+ containingFile = currentFile; -+ containingFileEditor = currentFileEditor; -+ func = (JetNamedFunction) currentFile.add(func); -+ } else { // create as method -+ String methodText = String.format(""fun %s(%s)%s { }"", methodName, parametersString, returnTypeString); -+ func = JetPsiFactory.createFunction(project, methodText); -+ PsiFile classContainingFile = ownerClass.getContainingFile(); -+ assert classContainingFile instanceof JetFile; -+ containingFile = (JetFile) classContainingFile; -+ -+ VirtualFile virtualFile = containingFile.getVirtualFile(); -+ assert virtualFile != null; -+ FileEditorManager fileEditorManager = FileEditorManager.getInstance(project); -+ fileEditorManager.openFile(virtualFile, true); -+ containingFileEditor = fileEditorManager.getSelectedTextEditor(); -+ -+ JetClassBody classBody = ownerClass.getBody(); -+ if (classBody == null) { -+ classBody = (JetClassBody) ownerClass.add(JetPsiFactory.createEmptyClassBody(project)); -+ ownerClass.addBefore(JetPsiFactory.createWhiteSpace(project), classBody); -+ } -+ PsiElement rBrace = classBody.getRBrace(); -+ assert rBrace != null; -+ func = (JetNamedFunction) classBody.addBefore(func, rBrace); -+ } -+ -+ return func; -+ } -+ -+ private void buildAndRunTemplate(@NotNull final Project project, @NotNull JetNamedFunction func) { -+ JetParameterList parameterList = func.getValueParameterList(); -+ assert parameterList != null; -+ -+ // build templates -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(containingFileEditor.getDocument()); -+ -+ CaretModel caretModel = containingFileEditor.getCaretModel(); -+ caretModel.moveToOffset(containingFile.getNode().getStartOffset()); -+ -+ TemplateBuilderImpl builder = new TemplateBuilderImpl(containingFile); -+ final TypeExpression returnTypeExpression = isUnit ? null : setupReturnTypeTemplate(builder, func); -+ final TypeExpression[] parameterTypeExpressions = setupParameterTypeTemplates(project, builder, parameterList); -+ -+ // add a segment for the parameter list -+ // Note: because TemplateBuilderImpl does not have a replaceElement overload that takes in both a TextRange and alwaysStopAt, we -+ // need to create the segment first and then hack the Expression into the template later. We use this template to update the type -+ // parameter list as the user makes selections in the parameter types, and we need alwaysStopAt to be false so the user can't tab to -+ // it. -+ TypeParameterListExpression expression = setupTypeParameterListTemplate(builder, func); -+ -+ // the template built by TemplateBuilderImpl is ordered by element position, but we want types to be first, so hack it -+ final TemplateImpl template = (TemplateImpl) builder.buildInlineTemplate(); -+ ArrayList variables = template.getVariables(); -+ for (int i = 0; i < parameters.size(); i++) { -+ Collections.swap(variables, i * 2, i * 2 + 1); -+ } -+ -+ // fix up the template to include the expression for the type parameter list -+ variables.add(new Variable(TYPE_PARAMETER_LIST_VARIABLE_NAME, expression, expression, false, true)); -+ -+ // run the template -+ TemplateManager.getInstance(project).startTemplate(containingFileEditor, template, new TemplateEditingAdapter() { -+ @Override -+ public void templateFinished(Template _, boolean brokenOff) {","Don't use such names, please. Even if parameter is not used. -",Why is this needed? Looks like a duplicate file. -106,"@@ -0,0 +1,1391 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.codeInsight.lookup.LookupElement; -+import com.intellij.codeInsight.lookup.LookupElementBuilder; -+import com.intellij.codeInsight.template.*; -+import com.intellij.codeInsight.template.impl.TemplateImpl; -+import com.intellij.codeInsight.template.impl.Variable; -+import com.intellij.ide.fileTemplates.FileTemplate; -+import com.intellij.ide.fileTemplates.FileTemplateManager; -+import com.intellij.ide.util.PsiElementListCellRenderer; -+import com.intellij.openapi.application.ApplicationManager; -+import com.intellij.openapi.command.CommandProcessor; -+import com.intellij.openapi.editor.CaretModel; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.fileEditor.FileEditorManager; -+import com.intellij.openapi.progress.ProcessCanceledException; -+import com.intellij.openapi.project.Project; -+import com.intellij.openapi.ui.popup.PopupChooserBuilder; -+import com.intellij.openapi.util.TextRange; -+import com.intellij.openapi.util.text.StringUtil; -+import com.intellij.openapi.vfs.VirtualFile; -+import com.intellij.psi.PsiDocumentManager; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.PsiReference; -+import com.intellij.psi.search.SearchScope; -+import com.intellij.psi.util.PsiTreeUtil; -+import com.intellij.refactoring.psi.SearchUtils; -+import com.intellij.ui.components.JBList; -+import com.intellij.util.ArrayUtil; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NonNls; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.descriptors.*; -+import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1; -+import org.jetbrains.jet.lang.diagnostics.Errors; -+import org.jetbrains.jet.lang.psi.*; -+import org.jetbrains.jet.lang.resolve.BindingContext; -+import org.jetbrains.jet.lang.resolve.BindingContextUtils; -+import org.jetbrains.jet.lang.resolve.DescriptorUtils; -+import org.jetbrains.jet.lang.resolve.name.Name; -+import org.jetbrains.jet.lang.resolve.scopes.JetScope; -+import org.jetbrains.jet.lang.types.*; -+import org.jetbrains.jet.lang.types.checker.JetTypeChecker; -+import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; -+import org.jetbrains.jet.plugin.JetBundle; -+import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening; -+import org.jetbrains.jet.plugin.presentation.JetLightClassListCellRenderer; -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; -+import org.jetbrains.jet.plugin.refactoring.JetNameSuggester; -+import org.jetbrains.jet.plugin.refactoring.JetNameValidator; -+import org.jetbrains.jet.plugin.references.JetSimpleNameReference; -+import org.jetbrains.jet.renderer.DescriptorRenderer; -+ -+import javax.swing.*; -+import java.util.*; -+import java.util.regex.Matcher; -+import java.util.regex.Pattern; -+ -+public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { -+ private static final String TYPE_PARAMETER_LIST_VARIABLE_NAME = ""typeParameterList""; -+ private static final String TEMPLATE_FROM_USAGE_METHOD_BODY = ""New Kotlin Method Body.kt""; -+ private static final Pattern COMPONENT_FUNCTION_PATTERN = Pattern.compile(""^component(\\d+)$""); -+ -+ /** -+ * Represents a single choice for a type (e.g. parameter type or return type). -+ */ -+ private static class TypeCandidate { -+ private final JetType type; -+ private final TypeParameterDescriptor[] typeParameters; -+ private String renderedType; -+ private String[] typeParameterNames; -+ -+ public TypeCandidate(@NotNull JetType type) { -+ this.type = type; -+ Set typeParametersInType = getTypeParametersInType(type); -+ typeParameters = typeParametersInType.toArray(new TypeParameterDescriptor[typeParametersInType.size()]); -+ renderedType = renderTypeShort(type, Collections.emptyMap()); -+ } -+ -+ public TypeCandidate(@NotNull JetType type, @NotNull JetScope scope) { -+ this.type = type; -+ typeParameters = getTypeParameterNamesNotInScope(getTypeParametersInType(type), scope); -+ } -+ -+ public void render(@NotNull Map typeParameterNameMap) { -+ renderedType = renderTypeShort(type, typeParameterNameMap); -+ typeParameterNames = new String[typeParameters.length]; -+ int i = 0; -+ for (TypeParameterDescriptor typeParameter : typeParameters) { -+ typeParameterNames[i] = typeParameterNameMap.get(typeParameter); -+ i++; -+ } -+ } -+ -+ @NotNull JetType getType() { -+ return type; -+ } -+ -+ @NotNull -+ public String getRenderedType() { -+ assert renderedType != null : ""call render() first""; -+ return renderedType; -+ } -+ -+ @NotNull -+ public String[] getTypeParameterNames() { -+ assert typeParameterNames != null : ""call render() first""; -+ return typeParameterNames; -+ } -+ -+ @NotNull -+ public TypeParameterDescriptor[] getTypeParameters() { -+ return typeParameters; -+ } -+ } -+ -+ /** -+ * Represents a concrete type or a set of types yet to be inferred from an expression. -+ */ -+ private static class TypeOrExpressionThereof { -+ private final JetExpression expressionOfType; -+ private final JetType type; -+ private final Variance variance; -+ private TypeCandidate[] typeCandidates; -+ private String[] cachedNameCandidatesFromExpression; -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType) { -+ this(expressionOfType, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType, Variance variance) { -+ this(expressionOfType, null, variance); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type) { -+ this(type, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type, Variance variance) { -+ this(null, type, variance); -+ } -+ -+ private TypeOrExpressionThereof(@Nullable JetExpression expressionOfType, @Nullable JetType type, Variance variance) { -+ this.expressionOfType = expressionOfType; -+ this.type = type; -+ this.variance = variance; -+ } -+ -+ public boolean isType() { -+ return this.type != null; -+ } -+ -+ @NotNull -+ public JetType getType() { -+ assert this.type != null; -+ return this.type; -+ } -+ -+ @NotNull -+ private List getPossibleTypes(BindingContext context) { -+ List types = new ArrayList(); -+ if (isType()) { -+ assert type != null : ""!isType() means type == null && expressionOfType != null""; -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ for (JetType type : guessTypeForExpression(expressionOfType, context)) { -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } -+ } -+ return types; -+ } -+ -+ public void computeTypeCandidates(@NotNull BindingContext context) { -+ Collection types = getPossibleTypes(context); -+ -+ typeCandidates = new TypeCandidate[types.size()]; -+ int i = 0; -+ for (JetType type : types) { -+ typeCandidates[i] = new TypeCandidate(type); -+ i++; -+ } -+ } -+ -+ public void computeTypeCandidates( -+ @NotNull BindingContext context, -+ @NotNull TypeSubstitution[] substitutions, -+ @NotNull JetScope scope -+ ) { -+ List types = getPossibleTypes(context); -+ Collections.reverse(types); // reverse and reverse back later, so that things added below are added at the front -+ -+ Set newTypes = new LinkedHashSet(types); -+ for (TypeSubstitution substitution : substitutions) { // each substitution can be applied or not, so we offer all options -+ List toAdd = new ArrayList(); -+ List toRemove = new ArrayList(); -+ for (JetType type : newTypes) { -+ toAdd.add(substituteType(type, substitution, variance)); -+ // substitution.byType are type arguments, but they cannot already occur in the type before substitution -+ if (containsType(type, substitution.getByType())) { -+ toRemove.add(type); -+ } -+ } -+ newTypes.addAll(toAdd); -+ newTypes.removeAll(toRemove); -+ } -+ -+ if (newTypes.isEmpty()) { -+ newTypes.add(KotlinBuiltIns.getInstance().getAnyType()); -+ } -+ -+ typeCandidates = new TypeCandidate[newTypes.size()]; -+ int i = typeCandidates.length - 1; // reverse order (see explanation above) -+ for (JetType type : newTypes) { -+ typeCandidates[i] = new TypeCandidate(type, scope); -+ i--; -+ } -+ } -+ -+ @NotNull -+ public TypeCandidate[] getTypeCandidates() { -+ assert typeCandidates != null : ""call computeTypeCandidates() first""; -+ return typeCandidates; -+ } -+ -+ public void renderTypeCandidates(@NotNull Map typeParameterNameMap) { -+ for (TypeCandidate candidate : typeCandidates) { -+ candidate.render(typeParameterNameMap); -+ } -+ } -+ -+ @NotNull -+ public String[] getPossibleNamesFromExpression() { -+ if (cachedNameCandidatesFromExpression != null) return cachedNameCandidatesFromExpression; -+ if (isType()) { -+ cachedNameCandidatesFromExpression = ArrayUtil.EMPTY_STRING_ARRAY; -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ JetNameValidator dummyValidator = new DummyJetNameValidator(expressionOfType.getProject()); -+ cachedNameCandidatesFromExpression = JetNameSuggester.suggestNamesForExpression(expressionOfType, dummyValidator); -+ } -+ return cachedNameCandidatesFromExpression; -+ } -+ } -+ -+ /** -+ * Encapsulates information about a method parameter that is going to be created. -+ */ -+ private static class Parameter { -+ private final String preferredName; -+ private final TypeOrExpressionThereof type; -+ -+ public Parameter(@Nullable(""no preferred name"") String preferredName, TypeOrExpressionThereof type) { -+ this.preferredName = preferredName; -+ this.type = type; -+ } -+ -+ public String getPreferredName() { -+ return preferredName; -+ } -+ -+ public TypeOrExpressionThereof getType() { -+ return type; -+ } -+ } -+ -+ /** -+ * Special Expression for parameter names based on its type. -+ */ -+ private static class ParameterNameExpression extends Expression { -+ private final String[] names; -+ private final Map parameterTypeToNamesMap; -+ -+ public ParameterNameExpression(@NotNull String[] names, @NotNull Map parameterTypeToNamesMap) { -+ for (String name : names) { -+ assert name != null && !name.isEmpty(); -+ } -+ this.names = names; -+ this.parameterTypeToNamesMap = parameterTypeToNamesMap; -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ LookupElement[] lookupItems = calculateLookupItems(context); -+ if (lookupItems.length == 0) return new TextResult(""""); -+ -+ return new TextResult(lookupItems[0].getLookupString()); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ Set names = new LinkedHashSet(); -+ Collections.addAll(names, this.names); -+ -+ // find the parameter list -+ Project project = context.getProject(); -+ int offset = context.getStartOffset(); -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ Editor editor = context.getEditor(); -+ assert editor != null; -+ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); -+ assert file != null && file instanceof JetFile; -+ PsiElement elementAt = file.findElementAt(offset); -+ JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); -+ if (func == null) return new LookupElement[0]; -+ JetParameterList parameterList = func.getValueParameterList(); -+ assert parameterList != null; -+ -+ // add names based on selected type -+ JetParameter parameter = PsiTreeUtil.getParentOfType(elementAt, JetParameter.class); -+ if (parameter != null) { -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ String[] suggestedNamesBasedOnType = parameterTypeToNamesMap.get(parameterTypeRef.getText()); -+ if (suggestedNamesBasedOnType != null) { -+ Collections.addAll(names, suggestedNamesBasedOnType); -+ } -+ } -+ } -+ -+ // remember other parameter names for later use -+ Set parameterNames = new HashSet(); -+ for (JetParameter jetParameter : parameterList.getParameters()) { -+ if (jetParameter == parameter || jetParameter.getName() == null) continue; -+ parameterNames.add(jetParameter.getName()); -+ } -+ -+ // add fallback parameter name -+ if (names.isEmpty()) { -+ names.add(""arg""); -+ } -+ -+ // ensure there are no conflicts -+ List lookupElements = new ArrayList(); -+ for (String name : names) { -+ name = getNextAvailableName(name, parameterNames); -+ lookupElements.add(LookupElementBuilder.create(name)); -+ } -+ -+ // create and return -+ return lookupElements.toArray(new LookupElement[lookupElements.size()]); -+ } -+ } -+ -+ /** -+ * An Expression for type references. -+ */ -+ private static class TypeExpression extends Expression { -+ private final TypeOrExpressionThereof type; -+ private @NotNull LookupElement[] cachedLookupElements; -+ -+ public TypeExpression(@NotNull TypeOrExpressionThereof type) { -+ this.type = type; -+ TypeCandidate[] candidates = type.getTypeCandidates(); -+ cachedLookupElements = new LookupElement[candidates.length]; -+ for (int i = 0; i < candidates.length; i++) { -+ cachedLookupElements[i] = LookupElementBuilder.create(candidates[i], candidates[i].getRenderedType()); -+ } -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ LookupElement[] lookupItems = calculateLookupItems(context); -+ if (lookupItems.length == 0) return new TextResult(""""); -+ -+ return new TextResult(lookupItems[0].getLookupString()); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ return cachedLookupElements; -+ } -+ -+ @NotNull -+ public TypeOrExpressionThereof getType() { -+ return type; -+ } -+ -+ @Nullable(""can't be found"") -+ public JetType getTypeFromSelection(@NotNull String selection) { -+ TypeCandidate[] options = type.getTypeCandidates(); -+ for (TypeCandidate option : options) { -+ if (option.getRenderedType().equals(selection)) { -+ return option.getType(); -+ } -+ } -+ return null; -+ } -+ } -+ -+ /** -+ * A sort-of dummy Expression for parameter lists, to allow us to update the parameter list as the user makes selections. -+ */ -+ private static class TypeParameterListExpression extends Expression { -+ private final String[] typeParameterNamesFromReceiverType; -+ private final Map parameterTypeToTypeParameterNamesMap; -+ -+ public TypeParameterListExpression( -+ @NotNull String[] typeParameterNamesFromReceiverType, -+ @NotNull Map typeParametersMap -+ ) { -+ this.typeParameterNamesFromReceiverType = typeParameterNamesFromReceiverType; -+ this.parameterTypeToTypeParameterNamesMap = typeParametersMap; -+ } -+ -+ @NotNull -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ Project project = context.getProject(); -+ int offset = context.getStartOffset(); -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ Editor editor = context.getEditor(); -+ assert editor != null; -+ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); -+ assert file != null && file instanceof JetFile; -+ PsiElement elementAt = file.findElementAt(offset); -+ JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); -+ if (func == null) { -+ return new TextResult(""""); -+ } -+ List parameters = func.getValueParameters(); -+ -+ Set typeParameterNames = new LinkedHashSet(); -+ Collections.addAll(typeParameterNames, typeParameterNamesFromReceiverType); -+ for (JetParameter parameter : parameters) { -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ String[] typeParameterNamesFromParameter = parameterTypeToTypeParameterNamesMap.get(parameterTypeRef.getText()); -+ if (typeParameterNamesFromParameter != null) { -+ Collections.addAll(typeParameterNames, typeParameterNamesFromParameter); -+ } -+ } -+ } -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ if (returnTypeRef != null) { -+ String[] typeParameterNamesFromReturnType = parameterTypeToTypeParameterNamesMap.get(returnTypeRef.getText()); -+ if (typeParameterNamesFromReturnType != null) { -+ Collections.addAll(typeParameterNames, typeParameterNamesFromReturnType); -+ } -+ } -+ -+ return typeParameterNames.isEmpty() -+ ? new TextResult("""") -+ : new TextResult("" <"" + StringUtil.join(typeParameterNames, "", "") + "">""); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ return new LookupElement[0]; // do not offer the user any choices -+ } -+ } -+ -+ /** -+ * A JetNameValidator that always succeeds. -+ */ -+ private static class DummyJetNameValidator implements JetNameValidator { -+ private final Project project; -+ -+ public DummyJetNameValidator(Project project) { -+ this.project = project; -+ } -+ -+ @Nullable -+ @Override -+ public String validateName(String name) { -+ return name; -+ } -+ -+ @Override -+ public Project getProject() { -+ return project; -+ } -+ } -+ -+ /** -+ * Encapsulates a single type substitution of a JetType by another JetType. -+ */ -+ private static class TypeSubstitution { -+ private final JetType forType; -+ private final JetType byType; -+ -+ private TypeSubstitution(JetType forType, JetType byType) { -+ this.forType = forType; -+ this.byType = byType; -+ } -+ -+ private JetType getForType() { -+ return forType; -+ } -+ -+ private JetType getByType() { -+ return byType; -+ } -+ } -+ -+ private final String methodName; -+ private final TypeOrExpressionThereof ownerType; -+ private final TypeOrExpressionThereof returnType; -+ private final List parameters; -+ -+ private boolean isUnit; -+ private boolean isExtension; -+ private JetFile currentFile; -+ private JetFile containingFile; -+ private Editor currentFileEditor; -+ private Editor containingFileEditor; -+ private BindingContext currentFileContext; -+ private JetClass ownerClass; -+ private ClassDescriptor ownerClassDescriptor; -+ private TypeCandidate selectedReceiverType; -+ private Map typeParameterNameMap; -+ -+ public CreateMethodFromUsageFix(@NotNull PsiElement element, @NotNull TypeOrExpressionThereof ownerType, @NotNull String methodName, -+ @NotNull TypeOrExpressionThereof returnType, @NotNull List parameters) { -+ super(element); -+ this.methodName = methodName; -+ this.ownerType = ownerType; -+ this.returnType = returnType; -+ this.parameters = parameters; -+ } -+ -+ @NotNull -+ @Override -+ public String getText() { -+ return JetBundle.message(""create.method.from.usage"", methodName); -+ } -+ -+ @Override -+ public void invoke(@NotNull final Project project, Editor editor, PsiFile file) throws IncorrectOperationException { -+ assert file != null && file instanceof JetFile; -+ currentFile = (JetFile) file; -+ currentFileEditor = editor; -+ currentFileContext = AnalyzerFacadeWithCache.analyzeFileWithCache(currentFile).getBindingContext(); -+ -+ ownerType.computeTypeCandidates(currentFileContext); -+ TypeCandidate[] ownerTypeCandidates = ownerType.getTypeCandidates(); -+ assert ownerTypeCandidates.length > 0; -+ if (ownerTypeCandidates.length == 1 || ApplicationManager.getApplication().isUnitTestMode()) { -+ selectedReceiverType = ownerTypeCandidates[0]; -+ doInvoke(project); -+ } else { -+ // class selection -+ List options = new ArrayList(); -+ final Map optionToTypeMap = new HashMap(); -+ for (TypeCandidate ownerTypeCandidate : ownerTypeCandidates) { -+ ClassifierDescriptor possibleClassDescriptor = ownerTypeCandidate.getType().getConstructor().getDeclarationDescriptor(); -+ if (possibleClassDescriptor != null) { -+ String className = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(possibleClassDescriptor.getDefaultType()); -+ DeclarationDescriptor namespaceDescriptor = possibleClassDescriptor.getContainingDeclaration(); -+ String namespace = renderDescriptor(namespaceDescriptor, true); -+ String option = className + "" ("" + namespace + "")""; -+ options.add(option); -+ optionToTypeMap.put(option, ownerTypeCandidate); -+ } -+ } -+ -+ final JList list = new JBList(options); -+ PsiElementListCellRenderer renderer = new JetLightClassListCellRenderer(); -+ list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); -+ list.setCellRenderer(renderer); -+ PopupChooserBuilder builder = new PopupChooserBuilder(list); -+ renderer.installSpeedSearch(builder); -+ -+ Runnable runnable = new Runnable() { -+ @Override -+ public void run() { -+ int index = list.getSelectedIndex(); -+ if (index < 0) return; -+ String option = (String) list.getSelectedValue(); -+ selectedReceiverType = optionToTypeMap.get(option); -+ CommandProcessor.getInstance().executeCommand(project, new Runnable() { -+ @Override -+ public void run() { -+ doInvoke(project); -+ } -+ }, getText(), null); -+ } -+ }; -+ -+ builder.setTitle(JetBundle.message(""choose.target.class.or.trait.title"")) -+ .setItemChoosenCallback(runnable) -+ .createPopup() -+ .showInBestPositionFor(currentFileEditor); -+ } -+ } -+ -+ private void doInvoke(@NotNull final Project project) { -+ // gather relevant information -+ ClassifierDescriptor ownerTypeDescriptor = selectedReceiverType.getType().getConstructor().getDeclarationDescriptor(); -+ assert ownerTypeDescriptor != null && ownerTypeDescriptor instanceof ClassDescriptor; -+ ownerClassDescriptor = (ClassDescriptor) ownerTypeDescriptor; -+ JetType receiverType = ownerClassDescriptor.getDefaultType(); -+ PsiElement typeDeclaration = BindingContextUtils.classDescriptorToDeclaration(currentFileContext, ownerClassDescriptor); -+ if (typeDeclaration != null && typeDeclaration instanceof JetClass) { -+ ownerClass = (JetClass) typeDeclaration; -+ isExtension = !ownerClass.isWritable(); -+ } else { -+ isExtension = true; -+ } -+ isUnit = returnType.isType() && isUnit(returnType.getType()); -+ -+ JetScope scope; -+ if (isExtension) { -+ NamespaceDescriptor namespaceDescriptor = currentFileContext.get(BindingContext.FILE_TO_NAMESPACE, currentFile); -+ assert namespaceDescriptor != null; -+ scope = namespaceDescriptor.getMemberScope(); -+ } else { -+ assert ownerClassDescriptor instanceof MutableClassDescriptor; -+ scope = ((MutableClassDescriptor) ownerClassDescriptor).getScopeForMemberResolution(); -+ } -+ -+ // figure out type substitutions for type parameters -+ List classTypeParameters = receiverType.getArguments(); -+ List ownerTypeArguments = selectedReceiverType.getType().getArguments(); -+ assert ownerTypeArguments.size() == classTypeParameters.size(); -+ TypeSubstitution[] substitutions = new TypeSubstitution[classTypeParameters.size()]; -+ for (int i = 0; i < substitutions.length; i++) { -+ substitutions[i] = new TypeSubstitution(ownerTypeArguments.get(i).getType(), classTypeParameters.get(i).getType()); -+ } -+ for (Parameter parameter : parameters) { -+ parameter.getType().computeTypeCandidates(currentFileContext, substitutions, scope); -+ } -+ if (!isUnit) { -+ returnType.computeTypeCandidates(currentFileContext, substitutions, scope); -+ } -+ -+ // now that we have done substitutions, we can throw it away -+ selectedReceiverType = new TypeCandidate(receiverType, scope); -+ -+ // figure out type parameter renames to avoid conflicts -+ typeParameterNameMap = getTypeParameterRenames(scope); -+ for (Parameter parameter : parameters) { -+ parameter.getType().renderTypeCandidates(typeParameterNameMap); -+ } -+ if (!isUnit) { -+ returnType.renderTypeCandidates(typeParameterNameMap); -+ } -+ selectedReceiverType.render(typeParameterNameMap); -+ -+ ApplicationManager.getApplication().runWriteAction(new Runnable() { -+ @Override -+ public void run() { -+ JetNamedFunction func = createFunctionSkeleton(project); -+ buildAndRunTemplate(project, func); -+ } -+ }); -+ } -+ -+ private JetNamedFunction createFunctionSkeleton(@NotNull Project project) { -+ JetNamedFunction func; -+ String[] parameterStrings = new String[parameters.size()]; -+ for (int i = 0; i < parameterStrings.length; i++) { -+ parameterStrings[i] = ""p"" + i + "": Any""; -+ } -+ String parametersString = StringUtil.join(parameterStrings,"", ""); -+ String returnTypeString = isUnit ? """" : "": Any""; -+ if (isExtension) { // create as extension function -+ String ownerTypeString = selectedReceiverType.getRenderedType(); -+ String methodText = String.format(""fun %s.%s(%s)%s { }"", ownerTypeString, methodName, parametersString, returnTypeString); -+ func = JetPsiFactory.createFunction(project, methodText); -+ containingFile = currentFile; -+ containingFileEditor = currentFileEditor; -+ func = (JetNamedFunction) currentFile.add(func); -+ } else { // create as method -+ String methodText = String.format(""fun %s(%s)%s { }"", methodName, parametersString, returnTypeString); -+ func = JetPsiFactory.createFunction(project, methodText); -+ PsiFile classContainingFile = ownerClass.getContainingFile(); -+ assert classContainingFile instanceof JetFile; -+ containingFile = (JetFile) classContainingFile; -+ -+ VirtualFile virtualFile = containingFile.getVirtualFile(); -+ assert virtualFile != null; -+ FileEditorManager fileEditorManager = FileEditorManager.getInstance(project); -+ fileEditorManager.openFile(virtualFile, true); -+ containingFileEditor = fileEditorManager.getSelectedTextEditor(); -+ -+ JetClassBody classBody = ownerClass.getBody(); -+ if (classBody == null) { -+ classBody = (JetClassBody) ownerClass.add(JetPsiFactory.createEmptyClassBody(project)); -+ ownerClass.addBefore(JetPsiFactory.createWhiteSpace(project), classBody); -+ } -+ PsiElement rBrace = classBody.getRBrace(); -+ assert rBrace != null; -+ func = (JetNamedFunction) classBody.addBefore(func, rBrace); -+ } -+ -+ return func; -+ } -+ -+ private void buildAndRunTemplate(@NotNull final Project project, @NotNull JetNamedFunction func) { -+ JetParameterList parameterList = func.getValueParameterList(); -+ assert parameterList != null; -+ -+ // build templates -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(containingFileEditor.getDocument()); -+ -+ CaretModel caretModel = containingFileEditor.getCaretModel(); -+ caretModel.moveToOffset(containingFile.getNode().getStartOffset()); -+ -+ TemplateBuilderImpl builder = new TemplateBuilderImpl(containingFile); -+ final TypeExpression returnTypeExpression = isUnit ? null : setupReturnTypeTemplate(builder, func); -+ final TypeExpression[] parameterTypeExpressions = setupParameterTypeTemplates(project, builder, parameterList); -+ -+ // add a segment for the parameter list -+ // Note: because TemplateBuilderImpl does not have a replaceElement overload that takes in both a TextRange and alwaysStopAt, we -+ // need to create the segment first and then hack the Expression into the template later. We use this template to update the type -+ // parameter list as the user makes selections in the parameter types, and we need alwaysStopAt to be false so the user can't tab to -+ // it. -+ TypeParameterListExpression expression = setupTypeParameterListTemplate(builder, func); -+ -+ // the template built by TemplateBuilderImpl is ordered by element position, but we want types to be first, so hack it -+ final TemplateImpl template = (TemplateImpl) builder.buildInlineTemplate(); -+ ArrayList variables = template.getVariables(); -+ for (int i = 0; i < parameters.size(); i++) { -+ Collections.swap(variables, i * 2, i * 2 + 1); -+ } -+ -+ // fix up the template to include the expression for the type parameter list -+ variables.add(new Variable(TYPE_PARAMETER_LIST_VARIABLE_NAME, expression, expression, false, true)); -+ -+ // run the template -+ TemplateManager.getInstance(project).startTemplate(containingFileEditor, template, new TemplateEditingAdapter() { -+ @Override -+ public void templateFinished(Template _, boolean brokenOff) { -+ // file templates -+ int offset = template.getSegmentOffset(0); -+ final JetNamedFunction func = PsiTreeUtil.findElementOfClassAtOffset(containingFile, offset, JetNamedFunction.class, false); -+ assert func != null; -+ final List typeRefsToShorten = new ArrayList(); -+ -+ ApplicationManager.getApplication().runWriteAction(new Runnable() { -+ @Override -+ public void run() { -+ // file templates -+ setupFunctionBody(project, func); -+ -+ // change short type names to fully qualified ones (to be shortened below) -+ setupTypeReferencesForShortening(project, func, typeRefsToShorten, parameterTypeExpressions, returnTypeExpression); -+ } -+ }); -+ -+ ReferenceToClassesShortening.compactReferenceToClasses(typeRefsToShorten); -+ } -+ }); -+ } -+ -+ private Map getTypeParameterRenames(JetScope scope) { -+ TypeParameterDescriptor[] receiverTypeParametersNotInScope = selectedReceiverType.getTypeParameters(); -+ Set allTypeParametersNotInScope = new LinkedHashSet(); -+ allTypeParametersNotInScope.addAll(Arrays.asList(receiverTypeParametersNotInScope)); -+ -+ for (Parameter parameter : parameters) { -+ TypeCandidate[] parameterTypeCandidates = parameter.getType().getTypeCandidates(); -+ for (TypeCandidate parameterTypeCandidate : parameterTypeCandidates) { -+ allTypeParametersNotInScope.addAll(Arrays.asList(parameterTypeCandidate.getTypeParameters())); -+ } -+ } -+ -+ if (!isUnit) { -+ TypeCandidate[] returnTypeCandidates = returnType.getTypeCandidates(); -+ for (TypeCandidate returnTypeCandidate : returnTypeCandidates) { -+ allTypeParametersNotInScope.addAll(Arrays.asList(returnTypeCandidate.getTypeParameters())); -+ } -+ } -+ -+ List typeParameters = new ArrayList(allTypeParametersNotInScope); -+ List typeParameterNames = new ArrayList(); -+ for (TypeParameterDescriptor typeParameter : typeParameters) { -+ typeParameterNames.add(getNextAvailableName(typeParameter.getName().getName(), typeParameterNames, scope)); -+ } -+ assert typeParameters.size() == typeParameterNames.size(); -+ Map typeParameterNameMap = new HashMap(); -+ for (int i = 0; i < typeParameters.size(); i++) { -+ typeParameterNameMap.put(typeParameters.get(i), typeParameterNames.get(i)); -+ } -+ -+ return typeParameterNameMap; -+ } -+ -+ private void setupTypeReferencesForShortening( -+ @NotNull Project project, -+ @NotNull JetNamedFunction func, -+ @NotNull List typeRefsToShorten, -+ @NotNull TypeExpression[] parameterTypeExpressions, -+ @Nullable TypeExpression returnTypeExpression -+ ) { -+ if (isExtension) { -+ JetTypeReference receiverTypeRef = -+ JetPsiFactory.createType(project, renderTypeLong(selectedReceiverType.getType(), typeParameterNameMap)); -+ replaceWithLongerName(project, receiverTypeRef, selectedReceiverType.getType()); -+ -+ receiverTypeRef = func.getReceiverTypeRef(); -+ if (receiverTypeRef != null) { -+ typeRefsToShorten.add(receiverTypeRef); -+ } -+ } -+ -+ if (!isUnit) { -+ assert returnTypeExpression != null; -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ if (returnTypeRef != null) { -+ JetType returnType = returnTypeExpression.getTypeFromSelection(returnTypeRef.getText()); -+ if (returnType != null) { // user selected a given type -+ replaceWithLongerName(project, returnTypeRef, returnType); -+ returnTypeRef = func.getReturnTypeRef(); -+ assert returnTypeRef != null; -+ typeRefsToShorten.add(returnTypeRef); -+ } -+ } -+ } -+ -+ List valueParameters = func.getValueParameters(); -+ List parameterIndicesToShorten = new ArrayList(); -+ assert valueParameters.size() == parameterTypeExpressions.length; -+ for (int i = 0; i < valueParameters.size(); i++) { -+ JetParameter parameter = valueParameters.get(i); -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ JetType parameterType = parameterTypeExpressions[i].getTypeFromSelection(parameterTypeRef.getText()); -+ if (parameterType != null) { -+ replaceWithLongerName(project, parameterTypeRef, parameterType); -+ parameterIndicesToShorten.add(i); -+ } -+ } -+ } -+ valueParameters = func.getValueParameters(); -+ for (int i : parameterIndicesToShorten) { -+ JetTypeReference parameterTypeRef = valueParameters.get(i).getTypeReference(); -+ if (parameterTypeRef != null) { -+ typeRefsToShorten.add(parameterTypeRef); -+ } -+ } -+ } -+ -+ private void setupFunctionBody(@NotNull Project project, @NotNull JetNamedFunction func) { -+ FileTemplate fileTemplate = FileTemplateManager.getInstance().getCodeTemplate(TEMPLATE_FROM_USAGE_METHOD_BODY); -+ Properties properties = new Properties(); -+ if (isUnit) { -+ properties.setProperty(FileTemplate.ATTRIBUTE_RETURN_TYPE, ""Unit""); -+ } else { -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ assert returnTypeRef != null; -+ properties.setProperty(FileTemplate.ATTRIBUTE_RETURN_TYPE, returnTypeRef.getText()); -+ } -+ properties.setProperty(FileTemplate.ATTRIBUTE_CLASS_NAME, DescriptorUtils.getFQName(ownerClassDescriptor).getFqName()); -+ properties.setProperty(FileTemplate.ATTRIBUTE_SIMPLE_CLASS_NAME, ownerClassDescriptor.getName().getName()); -+ properties.setProperty(FileTemplate.ATTRIBUTE_METHOD_NAME, methodName); -+ -+ @NonNls String bodyText; -+ try { -+ bodyText = fileTemplate.getText(properties); -+ } catch (ProcessCanceledException e) { -+ throw e; -+ } catch (Exception e) { -+ throw new IncorrectOperationException(""Failed to parse file template"", e); -+ } -+ JetExpression newBodyExpression = JetPsiFactory.createFunctionBody(project, bodyText); -+ JetExpression oldBodyExpression = func.getBodyExpression(); -+ assert oldBodyExpression != null; -+ oldBodyExpression.replace(newBodyExpression); -+ } -+ -+ @NotNull -+ private TypeExpression setupReturnTypeTemplate(@NotNull TemplateBuilder builder, @NotNull JetNamedFunction func) { -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ assert returnTypeRef != null; -+ TypeExpression returnTypeExpression = new TypeExpression(returnType); -+ builder.replaceElement(returnTypeRef, returnTypeExpression); -+ return returnTypeExpression; -+ } -+ -+ @NotNull -+ private TypeParameterListExpression setupTypeParameterListTemplate(@NotNull TemplateBuilderImpl builder, @NotNull JetNamedFunction func) { -+ Map typeParameterMap = new HashMap(); -+ String[] receiverTypeParameterNames = selectedReceiverType.getTypeParameterNames(); -+ -+ for (Parameter parameter : parameters) { -+ TypeCandidate[] parameterTypeCandidates = parameter.getType().getTypeCandidates(); -+ for (TypeCandidate parameterTypeCandidate : parameterTypeCandidates) { -+ typeParameterMap.put(parameterTypeCandidate.getRenderedType(), parameterTypeCandidate.getTypeParameterNames()); -+ } -+ } -+ -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ if (returnTypeRef != null) { -+ TypeCandidate[] returnTypeCandidates = returnType.getTypeCandidates(); -+ for (TypeCandidate returnTypeCandidate : returnTypeCandidates) { -+ typeParameterMap.put(returnTypeCandidate.getRenderedType(), returnTypeCandidate.getTypeParameterNames()); -+ } -+ } -+ -+ builder.replaceElement(func, TextRange.create(3, 3), TYPE_PARAMETER_LIST_VARIABLE_NAME, null, false); // ((3, 3) is after ""fun"") -+ return new TypeParameterListExpression(receiverTypeParameterNames, typeParameterMap); -+ } -+ -+ private TypeExpression[] setupParameterTypeTemplates(@NotNull Project project, @NotNull TemplateBuilder builder, -+ @NotNull JetParameterList parameterList) { -+ List jetParameters = parameterList.getParameters(); -+ assert jetParameters.size() == parameters.size(); -+ TypeExpression[] parameterTypeExpressions = new TypeExpression[parameters.size()]; -+ JetNameValidator dummyValidator = new DummyJetNameValidator(project); -+ for (int i = 0; i < parameters.size(); i++) { -+ Parameter parameter = parameters.get(i); -+ JetParameter jetParameter = jetParameters.get(i); -+ -+ // add parameter type to the template -+ parameterTypeExpressions[i] = new TypeExpression(parameter.getType()); -+ JetTypeReference parameterTypeRef = jetParameter.getTypeReference(); -+ assert parameterTypeRef != null; -+ builder.replaceElement(parameterTypeRef, parameterTypeExpressions[i]); -+ -+ // add parameter name to the template -+ String[] possibleNamesFromExpression = parameter.getType().getPossibleNamesFromExpression(); -+ String preferredName = parameter.getPreferredName(); -+ String[] possibleNames; -+ if (preferredName != null) { -+ possibleNames = new String[possibleNamesFromExpression.length + 1]; -+ possibleNames[0] = preferredName; -+ System.arraycopy(possibleNamesFromExpression, 0, possibleNames, 1, possibleNamesFromExpression.length); -+ } else { -+ possibleNames = possibleNamesFromExpression; -+ } -+ -+ // figure out suggested names for each type option -+ Map parameterTypeToNamesMap = new HashMap(); -+ for (TypeCandidate typeCandidate : parameter.getType().getTypeCandidates()) { -+ String[] suggestedNames = JetNameSuggester.suggestNamesForType(typeCandidate.getType(), dummyValidator); -+ parameterTypeToNamesMap.put(typeCandidate.getRenderedType(), suggestedNames); -+ } -+ -+ // add expression to builder -+ Expression parameterNameExpression = new ParameterNameExpression(possibleNames, parameterTypeToNamesMap); -+ PsiElement parameterNameIdentifier = jetParameter.getNameIdentifier(); -+ assert parameterNameIdentifier != null; -+ builder.replaceElement(parameterNameIdentifier, parameterNameExpression); -+ } -+ return parameterTypeExpressions; -+ } -+ -+ private void replaceWithLongerName(@NotNull Project project, @NotNull JetTypeReference typeRef, @NotNull JetType type) { -+ JetTypeReference fullyQualifiedReceiverTypeRef = JetPsiFactory.createType(project, renderTypeLong(type, typeParameterNameMap)); -+ typeRef.replace(fullyQualifiedReceiverTypeRef); -+ } -+ -+ @NotNull -+ private static JetType substituteType(@NotNull JetType type, @NotNull TypeSubstitution substitution, @NotNull Variance variance) {","I don't understand what does this method do, but I feel that it can be replaced with using already existing `TypeSubstitutor` mechanism. Please check it. -",Why is this needed? Looks like a duplicate file. -107,"@@ -0,0 +1,1391 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.codeInsight.lookup.LookupElement; -+import com.intellij.codeInsight.lookup.LookupElementBuilder; -+import com.intellij.codeInsight.template.*; -+import com.intellij.codeInsight.template.impl.TemplateImpl; -+import com.intellij.codeInsight.template.impl.Variable; -+import com.intellij.ide.fileTemplates.FileTemplate; -+import com.intellij.ide.fileTemplates.FileTemplateManager; -+import com.intellij.ide.util.PsiElementListCellRenderer; -+import com.intellij.openapi.application.ApplicationManager; -+import com.intellij.openapi.command.CommandProcessor; -+import com.intellij.openapi.editor.CaretModel; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.fileEditor.FileEditorManager; -+import com.intellij.openapi.progress.ProcessCanceledException; -+import com.intellij.openapi.project.Project; -+import com.intellij.openapi.ui.popup.PopupChooserBuilder; -+import com.intellij.openapi.util.TextRange; -+import com.intellij.openapi.util.text.StringUtil; -+import com.intellij.openapi.vfs.VirtualFile; -+import com.intellij.psi.PsiDocumentManager; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.PsiReference; -+import com.intellij.psi.search.SearchScope; -+import com.intellij.psi.util.PsiTreeUtil; -+import com.intellij.refactoring.psi.SearchUtils; -+import com.intellij.ui.components.JBList; -+import com.intellij.util.ArrayUtil; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NonNls; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.descriptors.*; -+import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1; -+import org.jetbrains.jet.lang.diagnostics.Errors; -+import org.jetbrains.jet.lang.psi.*; -+import org.jetbrains.jet.lang.resolve.BindingContext; -+import org.jetbrains.jet.lang.resolve.BindingContextUtils; -+import org.jetbrains.jet.lang.resolve.DescriptorUtils; -+import org.jetbrains.jet.lang.resolve.name.Name; -+import org.jetbrains.jet.lang.resolve.scopes.JetScope; -+import org.jetbrains.jet.lang.types.*; -+import org.jetbrains.jet.lang.types.checker.JetTypeChecker; -+import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; -+import org.jetbrains.jet.plugin.JetBundle; -+import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening; -+import org.jetbrains.jet.plugin.presentation.JetLightClassListCellRenderer; -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; -+import org.jetbrains.jet.plugin.refactoring.JetNameSuggester; -+import org.jetbrains.jet.plugin.refactoring.JetNameValidator; -+import org.jetbrains.jet.plugin.references.JetSimpleNameReference; -+import org.jetbrains.jet.renderer.DescriptorRenderer; -+ -+import javax.swing.*; -+import java.util.*; -+import java.util.regex.Matcher; -+import java.util.regex.Pattern; -+ -+public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { -+ private static final String TYPE_PARAMETER_LIST_VARIABLE_NAME = ""typeParameterList""; -+ private static final String TEMPLATE_FROM_USAGE_METHOD_BODY = ""New Kotlin Method Body.kt""; -+ private static final Pattern COMPONENT_FUNCTION_PATTERN = Pattern.compile(""^component(\\d+)$""); -+ -+ /** -+ * Represents a single choice for a type (e.g. parameter type or return type). -+ */ -+ private static class TypeCandidate { -+ private final JetType type; -+ private final TypeParameterDescriptor[] typeParameters; -+ private String renderedType; -+ private String[] typeParameterNames; -+ -+ public TypeCandidate(@NotNull JetType type) { -+ this.type = type; -+ Set typeParametersInType = getTypeParametersInType(type); -+ typeParameters = typeParametersInType.toArray(new TypeParameterDescriptor[typeParametersInType.size()]); -+ renderedType = renderTypeShort(type, Collections.emptyMap()); -+ } -+ -+ public TypeCandidate(@NotNull JetType type, @NotNull JetScope scope) { -+ this.type = type; -+ typeParameters = getTypeParameterNamesNotInScope(getTypeParametersInType(type), scope); -+ } -+ -+ public void render(@NotNull Map typeParameterNameMap) { -+ renderedType = renderTypeShort(type, typeParameterNameMap); -+ typeParameterNames = new String[typeParameters.length]; -+ int i = 0; -+ for (TypeParameterDescriptor typeParameter : typeParameters) { -+ typeParameterNames[i] = typeParameterNameMap.get(typeParameter); -+ i++; -+ } -+ } -+ -+ @NotNull JetType getType() { -+ return type; -+ } -+ -+ @NotNull -+ public String getRenderedType() { -+ assert renderedType != null : ""call render() first""; -+ return renderedType; -+ } -+ -+ @NotNull -+ public String[] getTypeParameterNames() { -+ assert typeParameterNames != null : ""call render() first""; -+ return typeParameterNames; -+ } -+ -+ @NotNull -+ public TypeParameterDescriptor[] getTypeParameters() { -+ return typeParameters; -+ } -+ } -+ -+ /** -+ * Represents a concrete type or a set of types yet to be inferred from an expression. -+ */ -+ private static class TypeOrExpressionThereof { -+ private final JetExpression expressionOfType; -+ private final JetType type; -+ private final Variance variance; -+ private TypeCandidate[] typeCandidates; -+ private String[] cachedNameCandidatesFromExpression; -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType) { -+ this(expressionOfType, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType, Variance variance) { -+ this(expressionOfType, null, variance); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type) { -+ this(type, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type, Variance variance) { -+ this(null, type, variance); -+ } -+ -+ private TypeOrExpressionThereof(@Nullable JetExpression expressionOfType, @Nullable JetType type, Variance variance) { -+ this.expressionOfType = expressionOfType; -+ this.type = type; -+ this.variance = variance; -+ } -+ -+ public boolean isType() { -+ return this.type != null; -+ } -+ -+ @NotNull -+ public JetType getType() { -+ assert this.type != null; -+ return this.type; -+ } -+ -+ @NotNull -+ private List getPossibleTypes(BindingContext context) { -+ List types = new ArrayList(); -+ if (isType()) { -+ assert type != null : ""!isType() means type == null && expressionOfType != null""; -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ for (JetType type : guessTypeForExpression(expressionOfType, context)) { -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } -+ } -+ return types; -+ } -+ -+ public void computeTypeCandidates(@NotNull BindingContext context) { -+ Collection types = getPossibleTypes(context); -+ -+ typeCandidates = new TypeCandidate[types.size()]; -+ int i = 0; -+ for (JetType type : types) { -+ typeCandidates[i] = new TypeCandidate(type); -+ i++; -+ } -+ } -+ -+ public void computeTypeCandidates( -+ @NotNull BindingContext context, -+ @NotNull TypeSubstitution[] substitutions, -+ @NotNull JetScope scope -+ ) { -+ List types = getPossibleTypes(context); -+ Collections.reverse(types); // reverse and reverse back later, so that things added below are added at the front -+ -+ Set newTypes = new LinkedHashSet(types); -+ for (TypeSubstitution substitution : substitutions) { // each substitution can be applied or not, so we offer all options -+ List toAdd = new ArrayList(); -+ List toRemove = new ArrayList(); -+ for (JetType type : newTypes) { -+ toAdd.add(substituteType(type, substitution, variance)); -+ // substitution.byType are type arguments, but they cannot already occur in the type before substitution -+ if (containsType(type, substitution.getByType())) { -+ toRemove.add(type); -+ } -+ } -+ newTypes.addAll(toAdd); -+ newTypes.removeAll(toRemove); -+ } -+ -+ if (newTypes.isEmpty()) { -+ newTypes.add(KotlinBuiltIns.getInstance().getAnyType()); -+ } -+ -+ typeCandidates = new TypeCandidate[newTypes.size()]; -+ int i = typeCandidates.length - 1; // reverse order (see explanation above) -+ for (JetType type : newTypes) { -+ typeCandidates[i] = new TypeCandidate(type, scope); -+ i--; -+ } -+ } -+ -+ @NotNull -+ public TypeCandidate[] getTypeCandidates() { -+ assert typeCandidates != null : ""call computeTypeCandidates() first""; -+ return typeCandidates; -+ } -+ -+ public void renderTypeCandidates(@NotNull Map typeParameterNameMap) { -+ for (TypeCandidate candidate : typeCandidates) { -+ candidate.render(typeParameterNameMap); -+ } -+ } -+ -+ @NotNull -+ public String[] getPossibleNamesFromExpression() { -+ if (cachedNameCandidatesFromExpression != null) return cachedNameCandidatesFromExpression; -+ if (isType()) { -+ cachedNameCandidatesFromExpression = ArrayUtil.EMPTY_STRING_ARRAY; -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ JetNameValidator dummyValidator = new DummyJetNameValidator(expressionOfType.getProject()); -+ cachedNameCandidatesFromExpression = JetNameSuggester.suggestNamesForExpression(expressionOfType, dummyValidator); -+ } -+ return cachedNameCandidatesFromExpression; -+ } -+ } -+ -+ /** -+ * Encapsulates information about a method parameter that is going to be created. -+ */ -+ private static class Parameter { -+ private final String preferredName; -+ private final TypeOrExpressionThereof type; -+ -+ public Parameter(@Nullable(""no preferred name"") String preferredName, TypeOrExpressionThereof type) { -+ this.preferredName = preferredName; -+ this.type = type; -+ } -+ -+ public String getPreferredName() { -+ return preferredName; -+ } -+ -+ public TypeOrExpressionThereof getType() { -+ return type; -+ } -+ } -+ -+ /** -+ * Special Expression for parameter names based on its type. -+ */ -+ private static class ParameterNameExpression extends Expression { -+ private final String[] names; -+ private final Map parameterTypeToNamesMap; -+ -+ public ParameterNameExpression(@NotNull String[] names, @NotNull Map parameterTypeToNamesMap) { -+ for (String name : names) { -+ assert name != null && !name.isEmpty(); -+ } -+ this.names = names; -+ this.parameterTypeToNamesMap = parameterTypeToNamesMap; -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ LookupElement[] lookupItems = calculateLookupItems(context); -+ if (lookupItems.length == 0) return new TextResult(""""); -+ -+ return new TextResult(lookupItems[0].getLookupString()); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ Set names = new LinkedHashSet(); -+ Collections.addAll(names, this.names); -+ -+ // find the parameter list -+ Project project = context.getProject(); -+ int offset = context.getStartOffset(); -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ Editor editor = context.getEditor(); -+ assert editor != null; -+ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); -+ assert file != null && file instanceof JetFile; -+ PsiElement elementAt = file.findElementAt(offset); -+ JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); -+ if (func == null) return new LookupElement[0]; -+ JetParameterList parameterList = func.getValueParameterList(); -+ assert parameterList != null; -+ -+ // add names based on selected type -+ JetParameter parameter = PsiTreeUtil.getParentOfType(elementAt, JetParameter.class); -+ if (parameter != null) { -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ String[] suggestedNamesBasedOnType = parameterTypeToNamesMap.get(parameterTypeRef.getText()); -+ if (suggestedNamesBasedOnType != null) { -+ Collections.addAll(names, suggestedNamesBasedOnType); -+ } -+ } -+ } -+ -+ // remember other parameter names for later use -+ Set parameterNames = new HashSet(); -+ for (JetParameter jetParameter : parameterList.getParameters()) { -+ if (jetParameter == parameter || jetParameter.getName() == null) continue; -+ parameterNames.add(jetParameter.getName()); -+ } -+ -+ // add fallback parameter name -+ if (names.isEmpty()) { -+ names.add(""arg""); -+ } -+ -+ // ensure there are no conflicts -+ List lookupElements = new ArrayList(); -+ for (String name : names) { -+ name = getNextAvailableName(name, parameterNames); -+ lookupElements.add(LookupElementBuilder.create(name)); -+ } -+ -+ // create and return -+ return lookupElements.toArray(new LookupElement[lookupElements.size()]); -+ } -+ } -+ -+ /** -+ * An Expression for type references. -+ */ -+ private static class TypeExpression extends Expression { -+ private final TypeOrExpressionThereof type; -+ private @NotNull LookupElement[] cachedLookupElements; -+ -+ public TypeExpression(@NotNull TypeOrExpressionThereof type) { -+ this.type = type; -+ TypeCandidate[] candidates = type.getTypeCandidates(); -+ cachedLookupElements = new LookupElement[candidates.length]; -+ for (int i = 0; i < candidates.length; i++) { -+ cachedLookupElements[i] = LookupElementBuilder.create(candidates[i], candidates[i].getRenderedType()); -+ } -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ LookupElement[] lookupItems = calculateLookupItems(context); -+ if (lookupItems.length == 0) return new TextResult(""""); -+ -+ return new TextResult(lookupItems[0].getLookupString()); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ return cachedLookupElements; -+ } -+ -+ @NotNull -+ public TypeOrExpressionThereof getType() { -+ return type; -+ } -+ -+ @Nullable(""can't be found"") -+ public JetType getTypeFromSelection(@NotNull String selection) { -+ TypeCandidate[] options = type.getTypeCandidates(); -+ for (TypeCandidate option : options) { -+ if (option.getRenderedType().equals(selection)) { -+ return option.getType(); -+ } -+ } -+ return null; -+ } -+ } -+ -+ /** -+ * A sort-of dummy Expression for parameter lists, to allow us to update the parameter list as the user makes selections. -+ */ -+ private static class TypeParameterListExpression extends Expression { -+ private final String[] typeParameterNamesFromReceiverType; -+ private final Map parameterTypeToTypeParameterNamesMap; -+ -+ public TypeParameterListExpression( -+ @NotNull String[] typeParameterNamesFromReceiverType, -+ @NotNull Map typeParametersMap -+ ) { -+ this.typeParameterNamesFromReceiverType = typeParameterNamesFromReceiverType; -+ this.parameterTypeToTypeParameterNamesMap = typeParametersMap; -+ } -+ -+ @NotNull -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ Project project = context.getProject(); -+ int offset = context.getStartOffset(); -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ Editor editor = context.getEditor(); -+ assert editor != null; -+ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); -+ assert file != null && file instanceof JetFile; -+ PsiElement elementAt = file.findElementAt(offset); -+ JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); -+ if (func == null) { -+ return new TextResult(""""); -+ } -+ List parameters = func.getValueParameters(); -+ -+ Set typeParameterNames = new LinkedHashSet(); -+ Collections.addAll(typeParameterNames, typeParameterNamesFromReceiverType); -+ for (JetParameter parameter : parameters) { -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ String[] typeParameterNamesFromParameter = parameterTypeToTypeParameterNamesMap.get(parameterTypeRef.getText()); -+ if (typeParameterNamesFromParameter != null) { -+ Collections.addAll(typeParameterNames, typeParameterNamesFromParameter); -+ } -+ } -+ } -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ if (returnTypeRef != null) { -+ String[] typeParameterNamesFromReturnType = parameterTypeToTypeParameterNamesMap.get(returnTypeRef.getText()); -+ if (typeParameterNamesFromReturnType != null) { -+ Collections.addAll(typeParameterNames, typeParameterNamesFromReturnType); -+ } -+ } -+ -+ return typeParameterNames.isEmpty() -+ ? new TextResult("""") -+ : new TextResult("" <"" + StringUtil.join(typeParameterNames, "", "") + "">""); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ return new LookupElement[0]; // do not offer the user any choices -+ } -+ } -+ -+ /** -+ * A JetNameValidator that always succeeds. -+ */ -+ private static class DummyJetNameValidator implements JetNameValidator { -+ private final Project project; -+ -+ public DummyJetNameValidator(Project project) { -+ this.project = project; -+ } -+ -+ @Nullable -+ @Override -+ public String validateName(String name) { -+ return name; -+ } -+ -+ @Override -+ public Project getProject() { -+ return project; -+ } -+ } -+ -+ /** -+ * Encapsulates a single type substitution of a JetType by another JetType. -+ */ -+ private static class TypeSubstitution { -+ private final JetType forType; -+ private final JetType byType; -+ -+ private TypeSubstitution(JetType forType, JetType byType) { -+ this.forType = forType; -+ this.byType = byType; -+ } -+ -+ private JetType getForType() { -+ return forType; -+ } -+ -+ private JetType getByType() { -+ return byType; -+ } -+ } -+ -+ private final String methodName; -+ private final TypeOrExpressionThereof ownerType; -+ private final TypeOrExpressionThereof returnType; -+ private final List parameters; -+ -+ private boolean isUnit; -+ private boolean isExtension; -+ private JetFile currentFile; -+ private JetFile containingFile; -+ private Editor currentFileEditor; -+ private Editor containingFileEditor; -+ private BindingContext currentFileContext; -+ private JetClass ownerClass; -+ private ClassDescriptor ownerClassDescriptor; -+ private TypeCandidate selectedReceiverType; -+ private Map typeParameterNameMap; -+ -+ public CreateMethodFromUsageFix(@NotNull PsiElement element, @NotNull TypeOrExpressionThereof ownerType, @NotNull String methodName, -+ @NotNull TypeOrExpressionThereof returnType, @NotNull List parameters) { -+ super(element); -+ this.methodName = methodName; -+ this.ownerType = ownerType; -+ this.returnType = returnType; -+ this.parameters = parameters; -+ } -+ -+ @NotNull -+ @Override -+ public String getText() { -+ return JetBundle.message(""create.method.from.usage"", methodName); -+ } -+ -+ @Override -+ public void invoke(@NotNull final Project project, Editor editor, PsiFile file) throws IncorrectOperationException { -+ assert file != null && file instanceof JetFile; -+ currentFile = (JetFile) file; -+ currentFileEditor = editor; -+ currentFileContext = AnalyzerFacadeWithCache.analyzeFileWithCache(currentFile).getBindingContext(); -+ -+ ownerType.computeTypeCandidates(currentFileContext); -+ TypeCandidate[] ownerTypeCandidates = ownerType.getTypeCandidates(); -+ assert ownerTypeCandidates.length > 0; -+ if (ownerTypeCandidates.length == 1 || ApplicationManager.getApplication().isUnitTestMode()) { -+ selectedReceiverType = ownerTypeCandidates[0]; -+ doInvoke(project); -+ } else { -+ // class selection -+ List options = new ArrayList(); -+ final Map optionToTypeMap = new HashMap(); -+ for (TypeCandidate ownerTypeCandidate : ownerTypeCandidates) { -+ ClassifierDescriptor possibleClassDescriptor = ownerTypeCandidate.getType().getConstructor().getDeclarationDescriptor(); -+ if (possibleClassDescriptor != null) { -+ String className = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(possibleClassDescriptor.getDefaultType()); -+ DeclarationDescriptor namespaceDescriptor = possibleClassDescriptor.getContainingDeclaration(); -+ String namespace = renderDescriptor(namespaceDescriptor, true); -+ String option = className + "" ("" + namespace + "")""; -+ options.add(option); -+ optionToTypeMap.put(option, ownerTypeCandidate); -+ } -+ } -+ -+ final JList list = new JBList(options); -+ PsiElementListCellRenderer renderer = new JetLightClassListCellRenderer(); -+ list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); -+ list.setCellRenderer(renderer); -+ PopupChooserBuilder builder = new PopupChooserBuilder(list); -+ renderer.installSpeedSearch(builder); -+ -+ Runnable runnable = new Runnable() { -+ @Override -+ public void run() { -+ int index = list.getSelectedIndex(); -+ if (index < 0) return; -+ String option = (String) list.getSelectedValue(); -+ selectedReceiverType = optionToTypeMap.get(option); -+ CommandProcessor.getInstance().executeCommand(project, new Runnable() { -+ @Override -+ public void run() { -+ doInvoke(project); -+ } -+ }, getText(), null); -+ } -+ }; -+ -+ builder.setTitle(JetBundle.message(""choose.target.class.or.trait.title"")) -+ .setItemChoosenCallback(runnable) -+ .createPopup() -+ .showInBestPositionFor(currentFileEditor); -+ } -+ } -+ -+ private void doInvoke(@NotNull final Project project) { -+ // gather relevant information -+ ClassifierDescriptor ownerTypeDescriptor = selectedReceiverType.getType().getConstructor().getDeclarationDescriptor(); -+ assert ownerTypeDescriptor != null && ownerTypeDescriptor instanceof ClassDescriptor; -+ ownerClassDescriptor = (ClassDescriptor) ownerTypeDescriptor; -+ JetType receiverType = ownerClassDescriptor.getDefaultType(); -+ PsiElement typeDeclaration = BindingContextUtils.classDescriptorToDeclaration(currentFileContext, ownerClassDescriptor); -+ if (typeDeclaration != null && typeDeclaration instanceof JetClass) { -+ ownerClass = (JetClass) typeDeclaration; -+ isExtension = !ownerClass.isWritable(); -+ } else { -+ isExtension = true; -+ } -+ isUnit = returnType.isType() && isUnit(returnType.getType()); -+ -+ JetScope scope; -+ if (isExtension) { -+ NamespaceDescriptor namespaceDescriptor = currentFileContext.get(BindingContext.FILE_TO_NAMESPACE, currentFile); -+ assert namespaceDescriptor != null; -+ scope = namespaceDescriptor.getMemberScope(); -+ } else { -+ assert ownerClassDescriptor instanceof MutableClassDescriptor; -+ scope = ((MutableClassDescriptor) ownerClassDescriptor).getScopeForMemberResolution(); -+ } -+ -+ // figure out type substitutions for type parameters -+ List classTypeParameters = receiverType.getArguments(); -+ List ownerTypeArguments = selectedReceiverType.getType().getArguments(); -+ assert ownerTypeArguments.size() == classTypeParameters.size(); -+ TypeSubstitution[] substitutions = new TypeSubstitution[classTypeParameters.size()]; -+ for (int i = 0; i < substitutions.length; i++) { -+ substitutions[i] = new TypeSubstitution(ownerTypeArguments.get(i).getType(), classTypeParameters.get(i).getType()); -+ } -+ for (Parameter parameter : parameters) { -+ parameter.getType().computeTypeCandidates(currentFileContext, substitutions, scope); -+ } -+ if (!isUnit) { -+ returnType.computeTypeCandidates(currentFileContext, substitutions, scope); -+ } -+ -+ // now that we have done substitutions, we can throw it away -+ selectedReceiverType = new TypeCandidate(receiverType, scope); -+ -+ // figure out type parameter renames to avoid conflicts -+ typeParameterNameMap = getTypeParameterRenames(scope); -+ for (Parameter parameter : parameters) { -+ parameter.getType().renderTypeCandidates(typeParameterNameMap); -+ } -+ if (!isUnit) { -+ returnType.renderTypeCandidates(typeParameterNameMap); -+ } -+ selectedReceiverType.render(typeParameterNameMap); -+ -+ ApplicationManager.getApplication().runWriteAction(new Runnable() { -+ @Override -+ public void run() { -+ JetNamedFunction func = createFunctionSkeleton(project); -+ buildAndRunTemplate(project, func); -+ } -+ }); -+ } -+ -+ private JetNamedFunction createFunctionSkeleton(@NotNull Project project) { -+ JetNamedFunction func; -+ String[] parameterStrings = new String[parameters.size()]; -+ for (int i = 0; i < parameterStrings.length; i++) { -+ parameterStrings[i] = ""p"" + i + "": Any""; -+ } -+ String parametersString = StringUtil.join(parameterStrings,"", ""); -+ String returnTypeString = isUnit ? """" : "": Any""; -+ if (isExtension) { // create as extension function -+ String ownerTypeString = selectedReceiverType.getRenderedType(); -+ String methodText = String.format(""fun %s.%s(%s)%s { }"", ownerTypeString, methodName, parametersString, returnTypeString); -+ func = JetPsiFactory.createFunction(project, methodText); -+ containingFile = currentFile; -+ containingFileEditor = currentFileEditor; -+ func = (JetNamedFunction) currentFile.add(func); -+ } else { // create as method -+ String methodText = String.format(""fun %s(%s)%s { }"", methodName, parametersString, returnTypeString); -+ func = JetPsiFactory.createFunction(project, methodText); -+ PsiFile classContainingFile = ownerClass.getContainingFile(); -+ assert classContainingFile instanceof JetFile; -+ containingFile = (JetFile) classContainingFile; -+ -+ VirtualFile virtualFile = containingFile.getVirtualFile(); -+ assert virtualFile != null; -+ FileEditorManager fileEditorManager = FileEditorManager.getInstance(project); -+ fileEditorManager.openFile(virtualFile, true); -+ containingFileEditor = fileEditorManager.getSelectedTextEditor(); -+ -+ JetClassBody classBody = ownerClass.getBody(); -+ if (classBody == null) { -+ classBody = (JetClassBody) ownerClass.add(JetPsiFactory.createEmptyClassBody(project)); -+ ownerClass.addBefore(JetPsiFactory.createWhiteSpace(project), classBody); -+ } -+ PsiElement rBrace = classBody.getRBrace(); -+ assert rBrace != null; -+ func = (JetNamedFunction) classBody.addBefore(func, rBrace); -+ } -+ -+ return func; -+ } -+ -+ private void buildAndRunTemplate(@NotNull final Project project, @NotNull JetNamedFunction func) { -+ JetParameterList parameterList = func.getValueParameterList(); -+ assert parameterList != null; -+ -+ // build templates -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(containingFileEditor.getDocument()); -+ -+ CaretModel caretModel = containingFileEditor.getCaretModel(); -+ caretModel.moveToOffset(containingFile.getNode().getStartOffset()); -+ -+ TemplateBuilderImpl builder = new TemplateBuilderImpl(containingFile); -+ final TypeExpression returnTypeExpression = isUnit ? null : setupReturnTypeTemplate(builder, func); -+ final TypeExpression[] parameterTypeExpressions = setupParameterTypeTemplates(project, builder, parameterList); -+ -+ // add a segment for the parameter list -+ // Note: because TemplateBuilderImpl does not have a replaceElement overload that takes in both a TextRange and alwaysStopAt, we -+ // need to create the segment first and then hack the Expression into the template later. We use this template to update the type -+ // parameter list as the user makes selections in the parameter types, and we need alwaysStopAt to be false so the user can't tab to -+ // it. -+ TypeParameterListExpression expression = setupTypeParameterListTemplate(builder, func); -+ -+ // the template built by TemplateBuilderImpl is ordered by element position, but we want types to be first, so hack it -+ final TemplateImpl template = (TemplateImpl) builder.buildInlineTemplate(); -+ ArrayList variables = template.getVariables(); -+ for (int i = 0; i < parameters.size(); i++) { -+ Collections.swap(variables, i * 2, i * 2 + 1); -+ } -+ -+ // fix up the template to include the expression for the type parameter list -+ variables.add(new Variable(TYPE_PARAMETER_LIST_VARIABLE_NAME, expression, expression, false, true)); -+ -+ // run the template -+ TemplateManager.getInstance(project).startTemplate(containingFileEditor, template, new TemplateEditingAdapter() { -+ @Override -+ public void templateFinished(Template _, boolean brokenOff) { -+ // file templates -+ int offset = template.getSegmentOffset(0); -+ final JetNamedFunction func = PsiTreeUtil.findElementOfClassAtOffset(containingFile, offset, JetNamedFunction.class, false); -+ assert func != null; -+ final List typeRefsToShorten = new ArrayList(); -+ -+ ApplicationManager.getApplication().runWriteAction(new Runnable() { -+ @Override -+ public void run() { -+ // file templates -+ setupFunctionBody(project, func); -+ -+ // change short type names to fully qualified ones (to be shortened below) -+ setupTypeReferencesForShortening(project, func, typeRefsToShorten, parameterTypeExpressions, returnTypeExpression); -+ } -+ }); -+ -+ ReferenceToClassesShortening.compactReferenceToClasses(typeRefsToShorten); -+ } -+ }); -+ } -+ -+ private Map getTypeParameterRenames(JetScope scope) { -+ TypeParameterDescriptor[] receiverTypeParametersNotInScope = selectedReceiverType.getTypeParameters(); -+ Set allTypeParametersNotInScope = new LinkedHashSet(); -+ allTypeParametersNotInScope.addAll(Arrays.asList(receiverTypeParametersNotInScope)); -+ -+ for (Parameter parameter : parameters) { -+ TypeCandidate[] parameterTypeCandidates = parameter.getType().getTypeCandidates(); -+ for (TypeCandidate parameterTypeCandidate : parameterTypeCandidates) { -+ allTypeParametersNotInScope.addAll(Arrays.asList(parameterTypeCandidate.getTypeParameters())); -+ } -+ } -+ -+ if (!isUnit) { -+ TypeCandidate[] returnTypeCandidates = returnType.getTypeCandidates(); -+ for (TypeCandidate returnTypeCandidate : returnTypeCandidates) { -+ allTypeParametersNotInScope.addAll(Arrays.asList(returnTypeCandidate.getTypeParameters())); -+ } -+ } -+ -+ List typeParameters = new ArrayList(allTypeParametersNotInScope); -+ List typeParameterNames = new ArrayList(); -+ for (TypeParameterDescriptor typeParameter : typeParameters) { -+ typeParameterNames.add(getNextAvailableName(typeParameter.getName().getName(), typeParameterNames, scope)); -+ } -+ assert typeParameters.size() == typeParameterNames.size(); -+ Map typeParameterNameMap = new HashMap(); -+ for (int i = 0; i < typeParameters.size(); i++) { -+ typeParameterNameMap.put(typeParameters.get(i), typeParameterNames.get(i)); -+ } -+ -+ return typeParameterNameMap; -+ } -+ -+ private void setupTypeReferencesForShortening( -+ @NotNull Project project, -+ @NotNull JetNamedFunction func, -+ @NotNull List typeRefsToShorten, -+ @NotNull TypeExpression[] parameterTypeExpressions, -+ @Nullable TypeExpression returnTypeExpression -+ ) { -+ if (isExtension) { -+ JetTypeReference receiverTypeRef = -+ JetPsiFactory.createType(project, renderTypeLong(selectedReceiverType.getType(), typeParameterNameMap)); -+ replaceWithLongerName(project, receiverTypeRef, selectedReceiverType.getType()); -+ -+ receiverTypeRef = func.getReceiverTypeRef(); -+ if (receiverTypeRef != null) { -+ typeRefsToShorten.add(receiverTypeRef); -+ } -+ } -+ -+ if (!isUnit) { -+ assert returnTypeExpression != null; -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ if (returnTypeRef != null) { -+ JetType returnType = returnTypeExpression.getTypeFromSelection(returnTypeRef.getText()); -+ if (returnType != null) { // user selected a given type -+ replaceWithLongerName(project, returnTypeRef, returnType); -+ returnTypeRef = func.getReturnTypeRef(); -+ assert returnTypeRef != null; -+ typeRefsToShorten.add(returnTypeRef); -+ } -+ } -+ } -+ -+ List valueParameters = func.getValueParameters(); -+ List parameterIndicesToShorten = new ArrayList(); -+ assert valueParameters.size() == parameterTypeExpressions.length; -+ for (int i = 0; i < valueParameters.size(); i++) { -+ JetParameter parameter = valueParameters.get(i); -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ JetType parameterType = parameterTypeExpressions[i].getTypeFromSelection(parameterTypeRef.getText()); -+ if (parameterType != null) { -+ replaceWithLongerName(project, parameterTypeRef, parameterType); -+ parameterIndicesToShorten.add(i); -+ } -+ } -+ } -+ valueParameters = func.getValueParameters(); -+ for (int i : parameterIndicesToShorten) { -+ JetTypeReference parameterTypeRef = valueParameters.get(i).getTypeReference(); -+ if (parameterTypeRef != null) { -+ typeRefsToShorten.add(parameterTypeRef); -+ } -+ } -+ } -+ -+ private void setupFunctionBody(@NotNull Project project, @NotNull JetNamedFunction func) { -+ FileTemplate fileTemplate = FileTemplateManager.getInstance().getCodeTemplate(TEMPLATE_FROM_USAGE_METHOD_BODY); -+ Properties properties = new Properties(); -+ if (isUnit) { -+ properties.setProperty(FileTemplate.ATTRIBUTE_RETURN_TYPE, ""Unit""); -+ } else { -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ assert returnTypeRef != null; -+ properties.setProperty(FileTemplate.ATTRIBUTE_RETURN_TYPE, returnTypeRef.getText()); -+ } -+ properties.setProperty(FileTemplate.ATTRIBUTE_CLASS_NAME, DescriptorUtils.getFQName(ownerClassDescriptor).getFqName()); -+ properties.setProperty(FileTemplate.ATTRIBUTE_SIMPLE_CLASS_NAME, ownerClassDescriptor.getName().getName()); -+ properties.setProperty(FileTemplate.ATTRIBUTE_METHOD_NAME, methodName); -+ -+ @NonNls String bodyText; -+ try { -+ bodyText = fileTemplate.getText(properties); -+ } catch (ProcessCanceledException e) { -+ throw e; -+ } catch (Exception e) { -+ throw new IncorrectOperationException(""Failed to parse file template"", e); -+ } -+ JetExpression newBodyExpression = JetPsiFactory.createFunctionBody(project, bodyText); -+ JetExpression oldBodyExpression = func.getBodyExpression(); -+ assert oldBodyExpression != null; -+ oldBodyExpression.replace(newBodyExpression); -+ } -+ -+ @NotNull -+ private TypeExpression setupReturnTypeTemplate(@NotNull TemplateBuilder builder, @NotNull JetNamedFunction func) { -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ assert returnTypeRef != null; -+ TypeExpression returnTypeExpression = new TypeExpression(returnType); -+ builder.replaceElement(returnTypeRef, returnTypeExpression); -+ return returnTypeExpression; -+ } -+ -+ @NotNull -+ private TypeParameterListExpression setupTypeParameterListTemplate(@NotNull TemplateBuilderImpl builder, @NotNull JetNamedFunction func) { -+ Map typeParameterMap = new HashMap(); -+ String[] receiverTypeParameterNames = selectedReceiverType.getTypeParameterNames(); -+ -+ for (Parameter parameter : parameters) { -+ TypeCandidate[] parameterTypeCandidates = parameter.getType().getTypeCandidates(); -+ for (TypeCandidate parameterTypeCandidate : parameterTypeCandidates) { -+ typeParameterMap.put(parameterTypeCandidate.getRenderedType(), parameterTypeCandidate.getTypeParameterNames()); -+ } -+ } -+ -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ if (returnTypeRef != null) { -+ TypeCandidate[] returnTypeCandidates = returnType.getTypeCandidates(); -+ for (TypeCandidate returnTypeCandidate : returnTypeCandidates) { -+ typeParameterMap.put(returnTypeCandidate.getRenderedType(), returnTypeCandidate.getTypeParameterNames()); -+ } -+ } -+ -+ builder.replaceElement(func, TextRange.create(3, 3), TYPE_PARAMETER_LIST_VARIABLE_NAME, null, false); // ((3, 3) is after ""fun"") -+ return new TypeParameterListExpression(receiverTypeParameterNames, typeParameterMap); -+ } -+ -+ private TypeExpression[] setupParameterTypeTemplates(@NotNull Project project, @NotNull TemplateBuilder builder, -+ @NotNull JetParameterList parameterList) { -+ List jetParameters = parameterList.getParameters(); -+ assert jetParameters.size() == parameters.size(); -+ TypeExpression[] parameterTypeExpressions = new TypeExpression[parameters.size()]; -+ JetNameValidator dummyValidator = new DummyJetNameValidator(project); -+ for (int i = 0; i < parameters.size(); i++) { -+ Parameter parameter = parameters.get(i); -+ JetParameter jetParameter = jetParameters.get(i); -+ -+ // add parameter type to the template -+ parameterTypeExpressions[i] = new TypeExpression(parameter.getType()); -+ JetTypeReference parameterTypeRef = jetParameter.getTypeReference(); -+ assert parameterTypeRef != null; -+ builder.replaceElement(parameterTypeRef, parameterTypeExpressions[i]); -+ -+ // add parameter name to the template -+ String[] possibleNamesFromExpression = parameter.getType().getPossibleNamesFromExpression(); -+ String preferredName = parameter.getPreferredName(); -+ String[] possibleNames; -+ if (preferredName != null) { -+ possibleNames = new String[possibleNamesFromExpression.length + 1]; -+ possibleNames[0] = preferredName; -+ System.arraycopy(possibleNamesFromExpression, 0, possibleNames, 1, possibleNamesFromExpression.length); -+ } else { -+ possibleNames = possibleNamesFromExpression; -+ } -+ -+ // figure out suggested names for each type option -+ Map parameterTypeToNamesMap = new HashMap(); -+ for (TypeCandidate typeCandidate : parameter.getType().getTypeCandidates()) { -+ String[] suggestedNames = JetNameSuggester.suggestNamesForType(typeCandidate.getType(), dummyValidator); -+ parameterTypeToNamesMap.put(typeCandidate.getRenderedType(), suggestedNames); -+ } -+ -+ // add expression to builder -+ Expression parameterNameExpression = new ParameterNameExpression(possibleNames, parameterTypeToNamesMap); -+ PsiElement parameterNameIdentifier = jetParameter.getNameIdentifier(); -+ assert parameterNameIdentifier != null; -+ builder.replaceElement(parameterNameIdentifier, parameterNameExpression); -+ } -+ return parameterTypeExpressions; -+ } -+ -+ private void replaceWithLongerName(@NotNull Project project, @NotNull JetTypeReference typeRef, @NotNull JetType type) { -+ JetTypeReference fullyQualifiedReceiverTypeRef = JetPsiFactory.createType(project, renderTypeLong(type, typeParameterNameMap)); -+ typeRef.replace(fullyQualifiedReceiverTypeRef); -+ } -+ -+ @NotNull -+ private static JetType substituteType(@NotNull JetType type, @NotNull TypeSubstitution substitution, @NotNull Variance variance) { -+ switch (variance) { -+ case INVARIANT: -+ // for invariant, can replace only when they're equal -+ if (type.equals(substitution.getForType())) { -+ return substitution.getByType(); -+ } -+ break; -+ case IN_VARIANCE: -+ // for covariant (e.g. function parameter), can replace type with any of its supertypes","You seem to mix up ""co"" and ""contra"" prefixes. -",Why is this needed? Looks like a duplicate file. -108,"@@ -0,0 +1,1391 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.codeInsight.lookup.LookupElement; -+import com.intellij.codeInsight.lookup.LookupElementBuilder; -+import com.intellij.codeInsight.template.*; -+import com.intellij.codeInsight.template.impl.TemplateImpl; -+import com.intellij.codeInsight.template.impl.Variable; -+import com.intellij.ide.fileTemplates.FileTemplate; -+import com.intellij.ide.fileTemplates.FileTemplateManager; -+import com.intellij.ide.util.PsiElementListCellRenderer; -+import com.intellij.openapi.application.ApplicationManager; -+import com.intellij.openapi.command.CommandProcessor; -+import com.intellij.openapi.editor.CaretModel; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.fileEditor.FileEditorManager; -+import com.intellij.openapi.progress.ProcessCanceledException; -+import com.intellij.openapi.project.Project; -+import com.intellij.openapi.ui.popup.PopupChooserBuilder; -+import com.intellij.openapi.util.TextRange; -+import com.intellij.openapi.util.text.StringUtil; -+import com.intellij.openapi.vfs.VirtualFile; -+import com.intellij.psi.PsiDocumentManager; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.PsiReference; -+import com.intellij.psi.search.SearchScope; -+import com.intellij.psi.util.PsiTreeUtil; -+import com.intellij.refactoring.psi.SearchUtils; -+import com.intellij.ui.components.JBList; -+import com.intellij.util.ArrayUtil; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NonNls; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.descriptors.*; -+import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1; -+import org.jetbrains.jet.lang.diagnostics.Errors; -+import org.jetbrains.jet.lang.psi.*; -+import org.jetbrains.jet.lang.resolve.BindingContext; -+import org.jetbrains.jet.lang.resolve.BindingContextUtils; -+import org.jetbrains.jet.lang.resolve.DescriptorUtils; -+import org.jetbrains.jet.lang.resolve.name.Name; -+import org.jetbrains.jet.lang.resolve.scopes.JetScope; -+import org.jetbrains.jet.lang.types.*; -+import org.jetbrains.jet.lang.types.checker.JetTypeChecker; -+import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; -+import org.jetbrains.jet.plugin.JetBundle; -+import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening; -+import org.jetbrains.jet.plugin.presentation.JetLightClassListCellRenderer; -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; -+import org.jetbrains.jet.plugin.refactoring.JetNameSuggester; -+import org.jetbrains.jet.plugin.refactoring.JetNameValidator; -+import org.jetbrains.jet.plugin.references.JetSimpleNameReference; -+import org.jetbrains.jet.renderer.DescriptorRenderer; -+ -+import javax.swing.*; -+import java.util.*; -+import java.util.regex.Matcher; -+import java.util.regex.Pattern; -+ -+public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { -+ private static final String TYPE_PARAMETER_LIST_VARIABLE_NAME = ""typeParameterList""; -+ private static final String TEMPLATE_FROM_USAGE_METHOD_BODY = ""New Kotlin Method Body.kt""; -+ private static final Pattern COMPONENT_FUNCTION_PATTERN = Pattern.compile(""^component(\\d+)$""); -+ -+ /** -+ * Represents a single choice for a type (e.g. parameter type or return type). -+ */ -+ private static class TypeCandidate { -+ private final JetType type; -+ private final TypeParameterDescriptor[] typeParameters; -+ private String renderedType; -+ private String[] typeParameterNames; -+ -+ public TypeCandidate(@NotNull JetType type) { -+ this.type = type; -+ Set typeParametersInType = getTypeParametersInType(type); -+ typeParameters = typeParametersInType.toArray(new TypeParameterDescriptor[typeParametersInType.size()]); -+ renderedType = renderTypeShort(type, Collections.emptyMap()); -+ } -+ -+ public TypeCandidate(@NotNull JetType type, @NotNull JetScope scope) { -+ this.type = type; -+ typeParameters = getTypeParameterNamesNotInScope(getTypeParametersInType(type), scope); -+ } -+ -+ public void render(@NotNull Map typeParameterNameMap) { -+ renderedType = renderTypeShort(type, typeParameterNameMap); -+ typeParameterNames = new String[typeParameters.length]; -+ int i = 0; -+ for (TypeParameterDescriptor typeParameter : typeParameters) { -+ typeParameterNames[i] = typeParameterNameMap.get(typeParameter); -+ i++; -+ } -+ } -+ -+ @NotNull JetType getType() { -+ return type; -+ } -+ -+ @NotNull -+ public String getRenderedType() { -+ assert renderedType != null : ""call render() first""; -+ return renderedType; -+ } -+ -+ @NotNull -+ public String[] getTypeParameterNames() { -+ assert typeParameterNames != null : ""call render() first""; -+ return typeParameterNames; -+ } -+ -+ @NotNull -+ public TypeParameterDescriptor[] getTypeParameters() { -+ return typeParameters; -+ } -+ } -+ -+ /** -+ * Represents a concrete type or a set of types yet to be inferred from an expression. -+ */ -+ private static class TypeOrExpressionThereof { -+ private final JetExpression expressionOfType; -+ private final JetType type; -+ private final Variance variance; -+ private TypeCandidate[] typeCandidates; -+ private String[] cachedNameCandidatesFromExpression; -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType) { -+ this(expressionOfType, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType, Variance variance) { -+ this(expressionOfType, null, variance); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type) { -+ this(type, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type, Variance variance) { -+ this(null, type, variance); -+ } -+ -+ private TypeOrExpressionThereof(@Nullable JetExpression expressionOfType, @Nullable JetType type, Variance variance) { -+ this.expressionOfType = expressionOfType; -+ this.type = type; -+ this.variance = variance; -+ } -+ -+ public boolean isType() { -+ return this.type != null; -+ } -+ -+ @NotNull -+ public JetType getType() { -+ assert this.type != null; -+ return this.type; -+ } -+ -+ @NotNull -+ private List getPossibleTypes(BindingContext context) { -+ List types = new ArrayList(); -+ if (isType()) { -+ assert type != null : ""!isType() means type == null && expressionOfType != null""; -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ for (JetType type : guessTypeForExpression(expressionOfType, context)) { -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } -+ } -+ return types; -+ } -+ -+ public void computeTypeCandidates(@NotNull BindingContext context) { -+ Collection types = getPossibleTypes(context); -+ -+ typeCandidates = new TypeCandidate[types.size()]; -+ int i = 0; -+ for (JetType type : types) { -+ typeCandidates[i] = new TypeCandidate(type); -+ i++; -+ } -+ } -+ -+ public void computeTypeCandidates( -+ @NotNull BindingContext context, -+ @NotNull TypeSubstitution[] substitutions, -+ @NotNull JetScope scope -+ ) { -+ List types = getPossibleTypes(context); -+ Collections.reverse(types); // reverse and reverse back later, so that things added below are added at the front -+ -+ Set newTypes = new LinkedHashSet(types); -+ for (TypeSubstitution substitution : substitutions) { // each substitution can be applied or not, so we offer all options -+ List toAdd = new ArrayList(); -+ List toRemove = new ArrayList(); -+ for (JetType type : newTypes) { -+ toAdd.add(substituteType(type, substitution, variance)); -+ // substitution.byType are type arguments, but they cannot already occur in the type before substitution -+ if (containsType(type, substitution.getByType())) { -+ toRemove.add(type); -+ } -+ } -+ newTypes.addAll(toAdd); -+ newTypes.removeAll(toRemove); -+ } -+ -+ if (newTypes.isEmpty()) { -+ newTypes.add(KotlinBuiltIns.getInstance().getAnyType()); -+ } -+ -+ typeCandidates = new TypeCandidate[newTypes.size()]; -+ int i = typeCandidates.length - 1; // reverse order (see explanation above) -+ for (JetType type : newTypes) { -+ typeCandidates[i] = new TypeCandidate(type, scope); -+ i--; -+ } -+ } -+ -+ @NotNull -+ public TypeCandidate[] getTypeCandidates() { -+ assert typeCandidates != null : ""call computeTypeCandidates() first""; -+ return typeCandidates; -+ } -+ -+ public void renderTypeCandidates(@NotNull Map typeParameterNameMap) { -+ for (TypeCandidate candidate : typeCandidates) { -+ candidate.render(typeParameterNameMap); -+ } -+ } -+ -+ @NotNull -+ public String[] getPossibleNamesFromExpression() { -+ if (cachedNameCandidatesFromExpression != null) return cachedNameCandidatesFromExpression; -+ if (isType()) { -+ cachedNameCandidatesFromExpression = ArrayUtil.EMPTY_STRING_ARRAY; -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ JetNameValidator dummyValidator = new DummyJetNameValidator(expressionOfType.getProject()); -+ cachedNameCandidatesFromExpression = JetNameSuggester.suggestNamesForExpression(expressionOfType, dummyValidator); -+ } -+ return cachedNameCandidatesFromExpression; -+ } -+ } -+ -+ /** -+ * Encapsulates information about a method parameter that is going to be created. -+ */ -+ private static class Parameter { -+ private final String preferredName; -+ private final TypeOrExpressionThereof type; -+ -+ public Parameter(@Nullable(""no preferred name"") String preferredName, TypeOrExpressionThereof type) { -+ this.preferredName = preferredName; -+ this.type = type; -+ } -+ -+ public String getPreferredName() { -+ return preferredName; -+ } -+ -+ public TypeOrExpressionThereof getType() { -+ return type; -+ } -+ } -+ -+ /** -+ * Special Expression for parameter names based on its type. -+ */ -+ private static class ParameterNameExpression extends Expression { -+ private final String[] names; -+ private final Map parameterTypeToNamesMap; -+ -+ public ParameterNameExpression(@NotNull String[] names, @NotNull Map parameterTypeToNamesMap) { -+ for (String name : names) { -+ assert name != null && !name.isEmpty(); -+ } -+ this.names = names; -+ this.parameterTypeToNamesMap = parameterTypeToNamesMap; -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ LookupElement[] lookupItems = calculateLookupItems(context); -+ if (lookupItems.length == 0) return new TextResult(""""); -+ -+ return new TextResult(lookupItems[0].getLookupString()); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ Set names = new LinkedHashSet(); -+ Collections.addAll(names, this.names); -+ -+ // find the parameter list -+ Project project = context.getProject(); -+ int offset = context.getStartOffset(); -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ Editor editor = context.getEditor(); -+ assert editor != null; -+ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); -+ assert file != null && file instanceof JetFile; -+ PsiElement elementAt = file.findElementAt(offset); -+ JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); -+ if (func == null) return new LookupElement[0]; -+ JetParameterList parameterList = func.getValueParameterList(); -+ assert parameterList != null; -+ -+ // add names based on selected type -+ JetParameter parameter = PsiTreeUtil.getParentOfType(elementAt, JetParameter.class); -+ if (parameter != null) { -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ String[] suggestedNamesBasedOnType = parameterTypeToNamesMap.get(parameterTypeRef.getText()); -+ if (suggestedNamesBasedOnType != null) { -+ Collections.addAll(names, suggestedNamesBasedOnType); -+ } -+ } -+ } -+ -+ // remember other parameter names for later use -+ Set parameterNames = new HashSet(); -+ for (JetParameter jetParameter : parameterList.getParameters()) { -+ if (jetParameter == parameter || jetParameter.getName() == null) continue; -+ parameterNames.add(jetParameter.getName()); -+ } -+ -+ // add fallback parameter name -+ if (names.isEmpty()) { -+ names.add(""arg""); -+ } -+ -+ // ensure there are no conflicts -+ List lookupElements = new ArrayList(); -+ for (String name : names) { -+ name = getNextAvailableName(name, parameterNames); -+ lookupElements.add(LookupElementBuilder.create(name)); -+ } -+ -+ // create and return -+ return lookupElements.toArray(new LookupElement[lookupElements.size()]); -+ } -+ } -+ -+ /** -+ * An Expression for type references. -+ */ -+ private static class TypeExpression extends Expression { -+ private final TypeOrExpressionThereof type; -+ private @NotNull LookupElement[] cachedLookupElements; -+ -+ public TypeExpression(@NotNull TypeOrExpressionThereof type) { -+ this.type = type; -+ TypeCandidate[] candidates = type.getTypeCandidates(); -+ cachedLookupElements = new LookupElement[candidates.length]; -+ for (int i = 0; i < candidates.length; i++) { -+ cachedLookupElements[i] = LookupElementBuilder.create(candidates[i], candidates[i].getRenderedType()); -+ } -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ LookupElement[] lookupItems = calculateLookupItems(context); -+ if (lookupItems.length == 0) return new TextResult(""""); -+ -+ return new TextResult(lookupItems[0].getLookupString()); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ return cachedLookupElements; -+ } -+ -+ @NotNull -+ public TypeOrExpressionThereof getType() { -+ return type; -+ } -+ -+ @Nullable(""can't be found"") -+ public JetType getTypeFromSelection(@NotNull String selection) { -+ TypeCandidate[] options = type.getTypeCandidates(); -+ for (TypeCandidate option : options) { -+ if (option.getRenderedType().equals(selection)) { -+ return option.getType(); -+ } -+ } -+ return null; -+ } -+ } -+ -+ /** -+ * A sort-of dummy Expression for parameter lists, to allow us to update the parameter list as the user makes selections. -+ */ -+ private static class TypeParameterListExpression extends Expression { -+ private final String[] typeParameterNamesFromReceiverType; -+ private final Map parameterTypeToTypeParameterNamesMap; -+ -+ public TypeParameterListExpression( -+ @NotNull String[] typeParameterNamesFromReceiverType, -+ @NotNull Map typeParametersMap -+ ) { -+ this.typeParameterNamesFromReceiverType = typeParameterNamesFromReceiverType; -+ this.parameterTypeToTypeParameterNamesMap = typeParametersMap; -+ } -+ -+ @NotNull -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ Project project = context.getProject(); -+ int offset = context.getStartOffset(); -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ Editor editor = context.getEditor(); -+ assert editor != null; -+ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); -+ assert file != null && file instanceof JetFile; -+ PsiElement elementAt = file.findElementAt(offset); -+ JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); -+ if (func == null) { -+ return new TextResult(""""); -+ } -+ List parameters = func.getValueParameters(); -+ -+ Set typeParameterNames = new LinkedHashSet(); -+ Collections.addAll(typeParameterNames, typeParameterNamesFromReceiverType); -+ for (JetParameter parameter : parameters) { -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ String[] typeParameterNamesFromParameter = parameterTypeToTypeParameterNamesMap.get(parameterTypeRef.getText()); -+ if (typeParameterNamesFromParameter != null) { -+ Collections.addAll(typeParameterNames, typeParameterNamesFromParameter); -+ } -+ } -+ } -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ if (returnTypeRef != null) { -+ String[] typeParameterNamesFromReturnType = parameterTypeToTypeParameterNamesMap.get(returnTypeRef.getText()); -+ if (typeParameterNamesFromReturnType != null) { -+ Collections.addAll(typeParameterNames, typeParameterNamesFromReturnType); -+ } -+ } -+ -+ return typeParameterNames.isEmpty() -+ ? new TextResult("""") -+ : new TextResult("" <"" + StringUtil.join(typeParameterNames, "", "") + "">""); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ return new LookupElement[0]; // do not offer the user any choices -+ } -+ } -+ -+ /** -+ * A JetNameValidator that always succeeds. -+ */ -+ private static class DummyJetNameValidator implements JetNameValidator { -+ private final Project project; -+ -+ public DummyJetNameValidator(Project project) { -+ this.project = project; -+ } -+ -+ @Nullable -+ @Override -+ public String validateName(String name) { -+ return name; -+ } -+ -+ @Override -+ public Project getProject() { -+ return project; -+ } -+ } -+ -+ /** -+ * Encapsulates a single type substitution of a JetType by another JetType. -+ */ -+ private static class TypeSubstitution { -+ private final JetType forType; -+ private final JetType byType; -+ -+ private TypeSubstitution(JetType forType, JetType byType) { -+ this.forType = forType; -+ this.byType = byType; -+ } -+ -+ private JetType getForType() { -+ return forType; -+ } -+ -+ private JetType getByType() { -+ return byType; -+ } -+ } -+ -+ private final String methodName; -+ private final TypeOrExpressionThereof ownerType; -+ private final TypeOrExpressionThereof returnType; -+ private final List parameters; -+ -+ private boolean isUnit; -+ private boolean isExtension; -+ private JetFile currentFile; -+ private JetFile containingFile; -+ private Editor currentFileEditor; -+ private Editor containingFileEditor; -+ private BindingContext currentFileContext; -+ private JetClass ownerClass; -+ private ClassDescriptor ownerClassDescriptor; -+ private TypeCandidate selectedReceiverType; -+ private Map typeParameterNameMap; -+ -+ public CreateMethodFromUsageFix(@NotNull PsiElement element, @NotNull TypeOrExpressionThereof ownerType, @NotNull String methodName, -+ @NotNull TypeOrExpressionThereof returnType, @NotNull List parameters) { -+ super(element); -+ this.methodName = methodName; -+ this.ownerType = ownerType; -+ this.returnType = returnType; -+ this.parameters = parameters; -+ } -+ -+ @NotNull -+ @Override -+ public String getText() { -+ return JetBundle.message(""create.method.from.usage"", methodName); -+ } -+ -+ @Override -+ public void invoke(@NotNull final Project project, Editor editor, PsiFile file) throws IncorrectOperationException { -+ assert file != null && file instanceof JetFile; -+ currentFile = (JetFile) file; -+ currentFileEditor = editor; -+ currentFileContext = AnalyzerFacadeWithCache.analyzeFileWithCache(currentFile).getBindingContext(); -+ -+ ownerType.computeTypeCandidates(currentFileContext); -+ TypeCandidate[] ownerTypeCandidates = ownerType.getTypeCandidates(); -+ assert ownerTypeCandidates.length > 0; -+ if (ownerTypeCandidates.length == 1 || ApplicationManager.getApplication().isUnitTestMode()) { -+ selectedReceiverType = ownerTypeCandidates[0]; -+ doInvoke(project); -+ } else { -+ // class selection -+ List options = new ArrayList(); -+ final Map optionToTypeMap = new HashMap(); -+ for (TypeCandidate ownerTypeCandidate : ownerTypeCandidates) { -+ ClassifierDescriptor possibleClassDescriptor = ownerTypeCandidate.getType().getConstructor().getDeclarationDescriptor(); -+ if (possibleClassDescriptor != null) { -+ String className = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(possibleClassDescriptor.getDefaultType()); -+ DeclarationDescriptor namespaceDescriptor = possibleClassDescriptor.getContainingDeclaration(); -+ String namespace = renderDescriptor(namespaceDescriptor, true); -+ String option = className + "" ("" + namespace + "")""; -+ options.add(option); -+ optionToTypeMap.put(option, ownerTypeCandidate); -+ } -+ } -+ -+ final JList list = new JBList(options); -+ PsiElementListCellRenderer renderer = new JetLightClassListCellRenderer(); -+ list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); -+ list.setCellRenderer(renderer); -+ PopupChooserBuilder builder = new PopupChooserBuilder(list); -+ renderer.installSpeedSearch(builder); -+ -+ Runnable runnable = new Runnable() { -+ @Override -+ public void run() { -+ int index = list.getSelectedIndex(); -+ if (index < 0) return; -+ String option = (String) list.getSelectedValue(); -+ selectedReceiverType = optionToTypeMap.get(option); -+ CommandProcessor.getInstance().executeCommand(project, new Runnable() { -+ @Override -+ public void run() { -+ doInvoke(project); -+ } -+ }, getText(), null); -+ } -+ }; -+ -+ builder.setTitle(JetBundle.message(""choose.target.class.or.trait.title"")) -+ .setItemChoosenCallback(runnable) -+ .createPopup() -+ .showInBestPositionFor(currentFileEditor); -+ } -+ } -+ -+ private void doInvoke(@NotNull final Project project) { -+ // gather relevant information -+ ClassifierDescriptor ownerTypeDescriptor = selectedReceiverType.getType().getConstructor().getDeclarationDescriptor(); -+ assert ownerTypeDescriptor != null && ownerTypeDescriptor instanceof ClassDescriptor; -+ ownerClassDescriptor = (ClassDescriptor) ownerTypeDescriptor; -+ JetType receiverType = ownerClassDescriptor.getDefaultType(); -+ PsiElement typeDeclaration = BindingContextUtils.classDescriptorToDeclaration(currentFileContext, ownerClassDescriptor); -+ if (typeDeclaration != null && typeDeclaration instanceof JetClass) { -+ ownerClass = (JetClass) typeDeclaration; -+ isExtension = !ownerClass.isWritable(); -+ } else { -+ isExtension = true; -+ } -+ isUnit = returnType.isType() && isUnit(returnType.getType()); -+ -+ JetScope scope; -+ if (isExtension) { -+ NamespaceDescriptor namespaceDescriptor = currentFileContext.get(BindingContext.FILE_TO_NAMESPACE, currentFile); -+ assert namespaceDescriptor != null; -+ scope = namespaceDescriptor.getMemberScope(); -+ } else { -+ assert ownerClassDescriptor instanceof MutableClassDescriptor; -+ scope = ((MutableClassDescriptor) ownerClassDescriptor).getScopeForMemberResolution(); -+ } -+ -+ // figure out type substitutions for type parameters -+ List classTypeParameters = receiverType.getArguments(); -+ List ownerTypeArguments = selectedReceiverType.getType().getArguments(); -+ assert ownerTypeArguments.size() == classTypeParameters.size(); -+ TypeSubstitution[] substitutions = new TypeSubstitution[classTypeParameters.size()]; -+ for (int i = 0; i < substitutions.length; i++) { -+ substitutions[i] = new TypeSubstitution(ownerTypeArguments.get(i).getType(), classTypeParameters.get(i).getType()); -+ } -+ for (Parameter parameter : parameters) { -+ parameter.getType().computeTypeCandidates(currentFileContext, substitutions, scope); -+ } -+ if (!isUnit) { -+ returnType.computeTypeCandidates(currentFileContext, substitutions, scope); -+ } -+ -+ // now that we have done substitutions, we can throw it away -+ selectedReceiverType = new TypeCandidate(receiverType, scope); -+ -+ // figure out type parameter renames to avoid conflicts -+ typeParameterNameMap = getTypeParameterRenames(scope); -+ for (Parameter parameter : parameters) { -+ parameter.getType().renderTypeCandidates(typeParameterNameMap); -+ } -+ if (!isUnit) { -+ returnType.renderTypeCandidates(typeParameterNameMap); -+ } -+ selectedReceiverType.render(typeParameterNameMap); -+ -+ ApplicationManager.getApplication().runWriteAction(new Runnable() { -+ @Override -+ public void run() { -+ JetNamedFunction func = createFunctionSkeleton(project); -+ buildAndRunTemplate(project, func); -+ } -+ }); -+ } -+ -+ private JetNamedFunction createFunctionSkeleton(@NotNull Project project) { -+ JetNamedFunction func; -+ String[] parameterStrings = new String[parameters.size()]; -+ for (int i = 0; i < parameterStrings.length; i++) { -+ parameterStrings[i] = ""p"" + i + "": Any""; -+ } -+ String parametersString = StringUtil.join(parameterStrings,"", ""); -+ String returnTypeString = isUnit ? """" : "": Any""; -+ if (isExtension) { // create as extension function -+ String ownerTypeString = selectedReceiverType.getRenderedType(); -+ String methodText = String.format(""fun %s.%s(%s)%s { }"", ownerTypeString, methodName, parametersString, returnTypeString); -+ func = JetPsiFactory.createFunction(project, methodText); -+ containingFile = currentFile; -+ containingFileEditor = currentFileEditor; -+ func = (JetNamedFunction) currentFile.add(func); -+ } else { // create as method -+ String methodText = String.format(""fun %s(%s)%s { }"", methodName, parametersString, returnTypeString); -+ func = JetPsiFactory.createFunction(project, methodText); -+ PsiFile classContainingFile = ownerClass.getContainingFile(); -+ assert classContainingFile instanceof JetFile; -+ containingFile = (JetFile) classContainingFile; -+ -+ VirtualFile virtualFile = containingFile.getVirtualFile(); -+ assert virtualFile != null; -+ FileEditorManager fileEditorManager = FileEditorManager.getInstance(project); -+ fileEditorManager.openFile(virtualFile, true); -+ containingFileEditor = fileEditorManager.getSelectedTextEditor(); -+ -+ JetClassBody classBody = ownerClass.getBody(); -+ if (classBody == null) { -+ classBody = (JetClassBody) ownerClass.add(JetPsiFactory.createEmptyClassBody(project)); -+ ownerClass.addBefore(JetPsiFactory.createWhiteSpace(project), classBody); -+ } -+ PsiElement rBrace = classBody.getRBrace(); -+ assert rBrace != null; -+ func = (JetNamedFunction) classBody.addBefore(func, rBrace); -+ } -+ -+ return func; -+ } -+ -+ private void buildAndRunTemplate(@NotNull final Project project, @NotNull JetNamedFunction func) { -+ JetParameterList parameterList = func.getValueParameterList(); -+ assert parameterList != null; -+ -+ // build templates -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(containingFileEditor.getDocument()); -+ -+ CaretModel caretModel = containingFileEditor.getCaretModel(); -+ caretModel.moveToOffset(containingFile.getNode().getStartOffset()); -+ -+ TemplateBuilderImpl builder = new TemplateBuilderImpl(containingFile); -+ final TypeExpression returnTypeExpression = isUnit ? null : setupReturnTypeTemplate(builder, func); -+ final TypeExpression[] parameterTypeExpressions = setupParameterTypeTemplates(project, builder, parameterList); -+ -+ // add a segment for the parameter list -+ // Note: because TemplateBuilderImpl does not have a replaceElement overload that takes in both a TextRange and alwaysStopAt, we -+ // need to create the segment first and then hack the Expression into the template later. We use this template to update the type -+ // parameter list as the user makes selections in the parameter types, and we need alwaysStopAt to be false so the user can't tab to -+ // it. -+ TypeParameterListExpression expression = setupTypeParameterListTemplate(builder, func); -+ -+ // the template built by TemplateBuilderImpl is ordered by element position, but we want types to be first, so hack it -+ final TemplateImpl template = (TemplateImpl) builder.buildInlineTemplate(); -+ ArrayList variables = template.getVariables(); -+ for (int i = 0; i < parameters.size(); i++) { -+ Collections.swap(variables, i * 2, i * 2 + 1); -+ } -+ -+ // fix up the template to include the expression for the type parameter list -+ variables.add(new Variable(TYPE_PARAMETER_LIST_VARIABLE_NAME, expression, expression, false, true)); -+ -+ // run the template -+ TemplateManager.getInstance(project).startTemplate(containingFileEditor, template, new TemplateEditingAdapter() { -+ @Override -+ public void templateFinished(Template _, boolean brokenOff) { -+ // file templates -+ int offset = template.getSegmentOffset(0); -+ final JetNamedFunction func = PsiTreeUtil.findElementOfClassAtOffset(containingFile, offset, JetNamedFunction.class, false); -+ assert func != null; -+ final List typeRefsToShorten = new ArrayList(); -+ -+ ApplicationManager.getApplication().runWriteAction(new Runnable() { -+ @Override -+ public void run() { -+ // file templates -+ setupFunctionBody(project, func); -+ -+ // change short type names to fully qualified ones (to be shortened below) -+ setupTypeReferencesForShortening(project, func, typeRefsToShorten, parameterTypeExpressions, returnTypeExpression); -+ } -+ }); -+ -+ ReferenceToClassesShortening.compactReferenceToClasses(typeRefsToShorten); -+ } -+ }); -+ } -+ -+ private Map getTypeParameterRenames(JetScope scope) { -+ TypeParameterDescriptor[] receiverTypeParametersNotInScope = selectedReceiverType.getTypeParameters(); -+ Set allTypeParametersNotInScope = new LinkedHashSet(); -+ allTypeParametersNotInScope.addAll(Arrays.asList(receiverTypeParametersNotInScope)); -+ -+ for (Parameter parameter : parameters) { -+ TypeCandidate[] parameterTypeCandidates = parameter.getType().getTypeCandidates(); -+ for (TypeCandidate parameterTypeCandidate : parameterTypeCandidates) { -+ allTypeParametersNotInScope.addAll(Arrays.asList(parameterTypeCandidate.getTypeParameters())); -+ } -+ } -+ -+ if (!isUnit) { -+ TypeCandidate[] returnTypeCandidates = returnType.getTypeCandidates(); -+ for (TypeCandidate returnTypeCandidate : returnTypeCandidates) { -+ allTypeParametersNotInScope.addAll(Arrays.asList(returnTypeCandidate.getTypeParameters())); -+ } -+ } -+ -+ List typeParameters = new ArrayList(allTypeParametersNotInScope); -+ List typeParameterNames = new ArrayList(); -+ for (TypeParameterDescriptor typeParameter : typeParameters) { -+ typeParameterNames.add(getNextAvailableName(typeParameter.getName().getName(), typeParameterNames, scope)); -+ } -+ assert typeParameters.size() == typeParameterNames.size(); -+ Map typeParameterNameMap = new HashMap(); -+ for (int i = 0; i < typeParameters.size(); i++) { -+ typeParameterNameMap.put(typeParameters.get(i), typeParameterNames.get(i)); -+ } -+ -+ return typeParameterNameMap; -+ } -+ -+ private void setupTypeReferencesForShortening( -+ @NotNull Project project, -+ @NotNull JetNamedFunction func, -+ @NotNull List typeRefsToShorten, -+ @NotNull TypeExpression[] parameterTypeExpressions, -+ @Nullable TypeExpression returnTypeExpression -+ ) { -+ if (isExtension) { -+ JetTypeReference receiverTypeRef = -+ JetPsiFactory.createType(project, renderTypeLong(selectedReceiverType.getType(), typeParameterNameMap)); -+ replaceWithLongerName(project, receiverTypeRef, selectedReceiverType.getType()); -+ -+ receiverTypeRef = func.getReceiverTypeRef(); -+ if (receiverTypeRef != null) { -+ typeRefsToShorten.add(receiverTypeRef); -+ } -+ } -+ -+ if (!isUnit) { -+ assert returnTypeExpression != null; -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ if (returnTypeRef != null) { -+ JetType returnType = returnTypeExpression.getTypeFromSelection(returnTypeRef.getText()); -+ if (returnType != null) { // user selected a given type -+ replaceWithLongerName(project, returnTypeRef, returnType); -+ returnTypeRef = func.getReturnTypeRef(); -+ assert returnTypeRef != null; -+ typeRefsToShorten.add(returnTypeRef); -+ } -+ } -+ } -+ -+ List valueParameters = func.getValueParameters(); -+ List parameterIndicesToShorten = new ArrayList(); -+ assert valueParameters.size() == parameterTypeExpressions.length; -+ for (int i = 0; i < valueParameters.size(); i++) { -+ JetParameter parameter = valueParameters.get(i); -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ JetType parameterType = parameterTypeExpressions[i].getTypeFromSelection(parameterTypeRef.getText()); -+ if (parameterType != null) { -+ replaceWithLongerName(project, parameterTypeRef, parameterType); -+ parameterIndicesToShorten.add(i); -+ } -+ } -+ } -+ valueParameters = func.getValueParameters(); -+ for (int i : parameterIndicesToShorten) { -+ JetTypeReference parameterTypeRef = valueParameters.get(i).getTypeReference(); -+ if (parameterTypeRef != null) { -+ typeRefsToShorten.add(parameterTypeRef); -+ } -+ } -+ } -+ -+ private void setupFunctionBody(@NotNull Project project, @NotNull JetNamedFunction func) { -+ FileTemplate fileTemplate = FileTemplateManager.getInstance().getCodeTemplate(TEMPLATE_FROM_USAGE_METHOD_BODY); -+ Properties properties = new Properties(); -+ if (isUnit) { -+ properties.setProperty(FileTemplate.ATTRIBUTE_RETURN_TYPE, ""Unit""); -+ } else { -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ assert returnTypeRef != null; -+ properties.setProperty(FileTemplate.ATTRIBUTE_RETURN_TYPE, returnTypeRef.getText()); -+ } -+ properties.setProperty(FileTemplate.ATTRIBUTE_CLASS_NAME, DescriptorUtils.getFQName(ownerClassDescriptor).getFqName()); -+ properties.setProperty(FileTemplate.ATTRIBUTE_SIMPLE_CLASS_NAME, ownerClassDescriptor.getName().getName()); -+ properties.setProperty(FileTemplate.ATTRIBUTE_METHOD_NAME, methodName); -+ -+ @NonNls String bodyText; -+ try { -+ bodyText = fileTemplate.getText(properties); -+ } catch (ProcessCanceledException e) { -+ throw e; -+ } catch (Exception e) { -+ throw new IncorrectOperationException(""Failed to parse file template"", e); -+ } -+ JetExpression newBodyExpression = JetPsiFactory.createFunctionBody(project, bodyText); -+ JetExpression oldBodyExpression = func.getBodyExpression(); -+ assert oldBodyExpression != null; -+ oldBodyExpression.replace(newBodyExpression); -+ } -+ -+ @NotNull -+ private TypeExpression setupReturnTypeTemplate(@NotNull TemplateBuilder builder, @NotNull JetNamedFunction func) { -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ assert returnTypeRef != null; -+ TypeExpression returnTypeExpression = new TypeExpression(returnType); -+ builder.replaceElement(returnTypeRef, returnTypeExpression); -+ return returnTypeExpression; -+ } -+ -+ @NotNull -+ private TypeParameterListExpression setupTypeParameterListTemplate(@NotNull TemplateBuilderImpl builder, @NotNull JetNamedFunction func) { -+ Map typeParameterMap = new HashMap(); -+ String[] receiverTypeParameterNames = selectedReceiverType.getTypeParameterNames(); -+ -+ for (Parameter parameter : parameters) { -+ TypeCandidate[] parameterTypeCandidates = parameter.getType().getTypeCandidates(); -+ for (TypeCandidate parameterTypeCandidate : parameterTypeCandidates) { -+ typeParameterMap.put(parameterTypeCandidate.getRenderedType(), parameterTypeCandidate.getTypeParameterNames()); -+ } -+ } -+ -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ if (returnTypeRef != null) { -+ TypeCandidate[] returnTypeCandidates = returnType.getTypeCandidates(); -+ for (TypeCandidate returnTypeCandidate : returnTypeCandidates) { -+ typeParameterMap.put(returnTypeCandidate.getRenderedType(), returnTypeCandidate.getTypeParameterNames()); -+ } -+ } -+ -+ builder.replaceElement(func, TextRange.create(3, 3), TYPE_PARAMETER_LIST_VARIABLE_NAME, null, false); // ((3, 3) is after ""fun"") -+ return new TypeParameterListExpression(receiverTypeParameterNames, typeParameterMap); -+ } -+ -+ private TypeExpression[] setupParameterTypeTemplates(@NotNull Project project, @NotNull TemplateBuilder builder, -+ @NotNull JetParameterList parameterList) { -+ List jetParameters = parameterList.getParameters(); -+ assert jetParameters.size() == parameters.size(); -+ TypeExpression[] parameterTypeExpressions = new TypeExpression[parameters.size()]; -+ JetNameValidator dummyValidator = new DummyJetNameValidator(project); -+ for (int i = 0; i < parameters.size(); i++) { -+ Parameter parameter = parameters.get(i); -+ JetParameter jetParameter = jetParameters.get(i); -+ -+ // add parameter type to the template -+ parameterTypeExpressions[i] = new TypeExpression(parameter.getType()); -+ JetTypeReference parameterTypeRef = jetParameter.getTypeReference(); -+ assert parameterTypeRef != null; -+ builder.replaceElement(parameterTypeRef, parameterTypeExpressions[i]); -+ -+ // add parameter name to the template -+ String[] possibleNamesFromExpression = parameter.getType().getPossibleNamesFromExpression(); -+ String preferredName = parameter.getPreferredName(); -+ String[] possibleNames; -+ if (preferredName != null) { -+ possibleNames = new String[possibleNamesFromExpression.length + 1]; -+ possibleNames[0] = preferredName; -+ System.arraycopy(possibleNamesFromExpression, 0, possibleNames, 1, possibleNamesFromExpression.length); -+ } else { -+ possibleNames = possibleNamesFromExpression; -+ } -+ -+ // figure out suggested names for each type option -+ Map parameterTypeToNamesMap = new HashMap(); -+ for (TypeCandidate typeCandidate : parameter.getType().getTypeCandidates()) { -+ String[] suggestedNames = JetNameSuggester.suggestNamesForType(typeCandidate.getType(), dummyValidator); -+ parameterTypeToNamesMap.put(typeCandidate.getRenderedType(), suggestedNames); -+ } -+ -+ // add expression to builder -+ Expression parameterNameExpression = new ParameterNameExpression(possibleNames, parameterTypeToNamesMap); -+ PsiElement parameterNameIdentifier = jetParameter.getNameIdentifier(); -+ assert parameterNameIdentifier != null; -+ builder.replaceElement(parameterNameIdentifier, parameterNameExpression); -+ } -+ return parameterTypeExpressions; -+ } -+ -+ private void replaceWithLongerName(@NotNull Project project, @NotNull JetTypeReference typeRef, @NotNull JetType type) { -+ JetTypeReference fullyQualifiedReceiverTypeRef = JetPsiFactory.createType(project, renderTypeLong(type, typeParameterNameMap)); -+ typeRef.replace(fullyQualifiedReceiverTypeRef); -+ } -+ -+ @NotNull -+ private static JetType substituteType(@NotNull JetType type, @NotNull TypeSubstitution substitution, @NotNull Variance variance) { -+ switch (variance) { -+ case INVARIANT: -+ // for invariant, can replace only when they're equal -+ if (type.equals(substitution.getForType())) { -+ return substitution.getByType(); -+ } -+ break; -+ case IN_VARIANCE: -+ // for covariant (e.g. function parameter), can replace type with any of its supertypes -+ if (JetTypeChecker.INSTANCE.isSubtypeOf(type, substitution.getForType())) { -+ return substitution.getByType(); -+ } -+ break; -+ case OUT_VARIANCE: -+ // for contravariant (e.g. function return value), can replace type with any of its subtypes -+ if (JetTypeChecker.INSTANCE.isSubtypeOf(substitution.getForType(), type)) { -+ return substitution.getByType(); -+ } -+ break; -+ } -+ -+ List newArguments = new ArrayList(); -+ List typeParameters = type.getConstructor().getParameters(); -+ int i = 0; -+ for (TypeProjection projection : type.getArguments()) { -+ TypeParameterDescriptor typeParameter = typeParameters.get(i); -+ JetType newArgument = substituteType(projection.getType(), substitution, typeParameter.getVariance()); -+ newArguments.add(new TypeProjection(Variance.INVARIANT, newArgument)); -+ i++; -+ } -+ return new JetTypeImpl(type.getAnnotations(), type.getConstructor(), -+ type.isNullable(), newArguments, type.getMemberScope()); -+ } -+ -+ private static boolean containsType(JetType outer, JetType inner) { -+ if (outer.equals(inner)) { -+ return true; -+ } -+ -+ for (TypeProjection projection : outer.getArguments()) { -+ if (containsType(projection.getType(), inner)) { -+ return true; -+ } -+ } -+ -+ return false; -+ } -+ -+ @NotNull -+ private static String renderDescriptor( -+ @NotNull DeclarationDescriptor declarationDescriptor, -+ @NotNull Map typeParameterNameMap, -+ boolean fq -+ ) { -+ if (declarationDescriptor instanceof TypeParameterDescriptor) { -+ String replacement = typeParameterNameMap.get(declarationDescriptor); -+ return replacement == null ? declarationDescriptor.getName().getName() : replacement; -+ } else { -+ return fq ? DescriptorUtils.getFQName(declarationDescriptor).getFqName() : declarationDescriptor.getName().getName(); -+ } -+ } -+ -+ @NotNull -+ private static String renderDescriptor(@NotNull DeclarationDescriptor declarationDescriptor, boolean fq) { -+ return renderDescriptor(declarationDescriptor, Collections.emptyMap(), fq); -+ } -+ -+ private static String renderType(@NotNull JetType type, @NotNull Map typeParameterNameMap, boolean fq) { -+ List projections = type.getArguments(); -+ DeclarationDescriptor declarationDescriptor = type.getConstructor().getDeclarationDescriptor(); -+ assert declarationDescriptor != null; -+ if (projections.isEmpty()) { -+ return renderDescriptor(declarationDescriptor, typeParameterNameMap, fq); -+ } -+ -+ List arguments = new ArrayList(); -+ for (TypeProjection projection : projections) { -+ arguments.add(renderType(projection.getType(), typeParameterNameMap, fq)); -+ } -+ return renderDescriptor(declarationDescriptor, typeParameterNameMap, fq) + ""<"" + StringUtil.join(arguments, "", "") + "">""; -+ } -+ -+ @NotNull -+ private static String renderTypeShort(@NotNull JetType type, @NotNull Map typeParameterNameMap) { -+ return renderType(type, typeParameterNameMap, false); -+ } -+ -+ @NotNull -+ private static String renderTypeLong(@NotNull JetType type, @NotNull Map typeParameterNameMap) { -+ return renderType(type, typeParameterNameMap, true); -+ } -+ -+ @NotNull -+ private static TypeParameterDescriptor[] getTypeParameterNamesNotInScope( -+ @NotNull Collection typeParameters, -+ @NotNull JetScope scope -+ ) { -+ List typeParameterNames = new ArrayList(); -+ for (TypeParameterDescriptor typeParameter : typeParameters) { -+ ClassifierDescriptor classifier = scope.getClassifier(typeParameter.getName()); -+ if (classifier == null || !classifier.equals(typeParameter)) { -+ typeParameterNames.add(typeParameter); -+ } -+ } -+ return typeParameterNames.toArray(new TypeParameterDescriptor[typeParameterNames.size()]); -+ } -+ -+ @NotNull -+ private static Set getTypeParametersInType(@NotNull JetType type) { -+ Set typeParameters = new LinkedHashSet(); -+ List arguments = type.getArguments(); -+ if (arguments.isEmpty()) { -+ ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); -+ if (descriptor instanceof TypeParameterDescriptor) { -+ typeParameters.add((TypeParameterDescriptor) descriptor); -+ } -+ } else { -+ for (TypeProjection projection : arguments) { -+ typeParameters.addAll(getTypeParametersInType(projection.getType())); -+ } -+ } -+ return typeParameters; -+ } -+ -+ @NotNull -+ private static String getNextAvailableName(@NotNull String name, @NotNull Collection existingNames) {","I think, it's better to merge this and next method (with `@Nullable` scope) -Add comment, that for Foo name from parameter it returns itself, if it is available, and Foo1, Foo2, .. if it's not. -",Why is this needed? Looks like a duplicate file. -109,"@@ -0,0 +1,1391 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.codeInsight.lookup.LookupElement; -+import com.intellij.codeInsight.lookup.LookupElementBuilder; -+import com.intellij.codeInsight.template.*; -+import com.intellij.codeInsight.template.impl.TemplateImpl; -+import com.intellij.codeInsight.template.impl.Variable; -+import com.intellij.ide.fileTemplates.FileTemplate; -+import com.intellij.ide.fileTemplates.FileTemplateManager; -+import com.intellij.ide.util.PsiElementListCellRenderer; -+import com.intellij.openapi.application.ApplicationManager; -+import com.intellij.openapi.command.CommandProcessor; -+import com.intellij.openapi.editor.CaretModel; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.fileEditor.FileEditorManager; -+import com.intellij.openapi.progress.ProcessCanceledException; -+import com.intellij.openapi.project.Project; -+import com.intellij.openapi.ui.popup.PopupChooserBuilder; -+import com.intellij.openapi.util.TextRange; -+import com.intellij.openapi.util.text.StringUtil; -+import com.intellij.openapi.vfs.VirtualFile; -+import com.intellij.psi.PsiDocumentManager; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.PsiReference; -+import com.intellij.psi.search.SearchScope; -+import com.intellij.psi.util.PsiTreeUtil; -+import com.intellij.refactoring.psi.SearchUtils; -+import com.intellij.ui.components.JBList; -+import com.intellij.util.ArrayUtil; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NonNls; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.descriptors.*; -+import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1; -+import org.jetbrains.jet.lang.diagnostics.Errors; -+import org.jetbrains.jet.lang.psi.*; -+import org.jetbrains.jet.lang.resolve.BindingContext; -+import org.jetbrains.jet.lang.resolve.BindingContextUtils; -+import org.jetbrains.jet.lang.resolve.DescriptorUtils; -+import org.jetbrains.jet.lang.resolve.name.Name; -+import org.jetbrains.jet.lang.resolve.scopes.JetScope; -+import org.jetbrains.jet.lang.types.*; -+import org.jetbrains.jet.lang.types.checker.JetTypeChecker; -+import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; -+import org.jetbrains.jet.plugin.JetBundle; -+import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening; -+import org.jetbrains.jet.plugin.presentation.JetLightClassListCellRenderer; -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; -+import org.jetbrains.jet.plugin.refactoring.JetNameSuggester; -+import org.jetbrains.jet.plugin.refactoring.JetNameValidator; -+import org.jetbrains.jet.plugin.references.JetSimpleNameReference; -+import org.jetbrains.jet.renderer.DescriptorRenderer; -+ -+import javax.swing.*; -+import java.util.*; -+import java.util.regex.Matcher; -+import java.util.regex.Pattern; -+ -+public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { -+ private static final String TYPE_PARAMETER_LIST_VARIABLE_NAME = ""typeParameterList""; -+ private static final String TEMPLATE_FROM_USAGE_METHOD_BODY = ""New Kotlin Method Body.kt""; -+ private static final Pattern COMPONENT_FUNCTION_PATTERN = Pattern.compile(""^component(\\d+)$""); -+ -+ /** -+ * Represents a single choice for a type (e.g. parameter type or return type). -+ */ -+ private static class TypeCandidate { -+ private final JetType type; -+ private final TypeParameterDescriptor[] typeParameters; -+ private String renderedType; -+ private String[] typeParameterNames; -+ -+ public TypeCandidate(@NotNull JetType type) { -+ this.type = type; -+ Set typeParametersInType = getTypeParametersInType(type); -+ typeParameters = typeParametersInType.toArray(new TypeParameterDescriptor[typeParametersInType.size()]); -+ renderedType = renderTypeShort(type, Collections.emptyMap()); -+ } -+ -+ public TypeCandidate(@NotNull JetType type, @NotNull JetScope scope) { -+ this.type = type; -+ typeParameters = getTypeParameterNamesNotInScope(getTypeParametersInType(type), scope); -+ } -+ -+ public void render(@NotNull Map typeParameterNameMap) { -+ renderedType = renderTypeShort(type, typeParameterNameMap); -+ typeParameterNames = new String[typeParameters.length]; -+ int i = 0; -+ for (TypeParameterDescriptor typeParameter : typeParameters) { -+ typeParameterNames[i] = typeParameterNameMap.get(typeParameter); -+ i++; -+ } -+ } -+ -+ @NotNull JetType getType() { -+ return type; -+ } -+ -+ @NotNull -+ public String getRenderedType() { -+ assert renderedType != null : ""call render() first""; -+ return renderedType; -+ } -+ -+ @NotNull -+ public String[] getTypeParameterNames() { -+ assert typeParameterNames != null : ""call render() first""; -+ return typeParameterNames; -+ } -+ -+ @NotNull -+ public TypeParameterDescriptor[] getTypeParameters() { -+ return typeParameters; -+ } -+ } -+ -+ /** -+ * Represents a concrete type or a set of types yet to be inferred from an expression. -+ */ -+ private static class TypeOrExpressionThereof { -+ private final JetExpression expressionOfType; -+ private final JetType type; -+ private final Variance variance; -+ private TypeCandidate[] typeCandidates; -+ private String[] cachedNameCandidatesFromExpression; -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType) { -+ this(expressionOfType, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType, Variance variance) { -+ this(expressionOfType, null, variance); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type) { -+ this(type, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type, Variance variance) { -+ this(null, type, variance); -+ } -+ -+ private TypeOrExpressionThereof(@Nullable JetExpression expressionOfType, @Nullable JetType type, Variance variance) { -+ this.expressionOfType = expressionOfType; -+ this.type = type; -+ this.variance = variance; -+ } -+ -+ public boolean isType() { -+ return this.type != null; -+ } -+ -+ @NotNull -+ public JetType getType() { -+ assert this.type != null; -+ return this.type; -+ } -+ -+ @NotNull -+ private List getPossibleTypes(BindingContext context) { -+ List types = new ArrayList(); -+ if (isType()) { -+ assert type != null : ""!isType() means type == null && expressionOfType != null""; -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ for (JetType type : guessTypeForExpression(expressionOfType, context)) { -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } -+ } -+ return types; -+ } -+ -+ public void computeTypeCandidates(@NotNull BindingContext context) { -+ Collection types = getPossibleTypes(context); -+ -+ typeCandidates = new TypeCandidate[types.size()]; -+ int i = 0; -+ for (JetType type : types) { -+ typeCandidates[i] = new TypeCandidate(type); -+ i++; -+ } -+ } -+ -+ public void computeTypeCandidates( -+ @NotNull BindingContext context, -+ @NotNull TypeSubstitution[] substitutions, -+ @NotNull JetScope scope -+ ) { -+ List types = getPossibleTypes(context); -+ Collections.reverse(types); // reverse and reverse back later, so that things added below are added at the front -+ -+ Set newTypes = new LinkedHashSet(types); -+ for (TypeSubstitution substitution : substitutions) { // each substitution can be applied or not, so we offer all options -+ List toAdd = new ArrayList(); -+ List toRemove = new ArrayList(); -+ for (JetType type : newTypes) { -+ toAdd.add(substituteType(type, substitution, variance)); -+ // substitution.byType are type arguments, but they cannot already occur in the type before substitution -+ if (containsType(type, substitution.getByType())) { -+ toRemove.add(type); -+ } -+ } -+ newTypes.addAll(toAdd); -+ newTypes.removeAll(toRemove); -+ } -+ -+ if (newTypes.isEmpty()) { -+ newTypes.add(KotlinBuiltIns.getInstance().getAnyType()); -+ } -+ -+ typeCandidates = new TypeCandidate[newTypes.size()]; -+ int i = typeCandidates.length - 1; // reverse order (see explanation above) -+ for (JetType type : newTypes) { -+ typeCandidates[i] = new TypeCandidate(type, scope); -+ i--; -+ } -+ } -+ -+ @NotNull -+ public TypeCandidate[] getTypeCandidates() { -+ assert typeCandidates != null : ""call computeTypeCandidates() first""; -+ return typeCandidates; -+ } -+ -+ public void renderTypeCandidates(@NotNull Map typeParameterNameMap) { -+ for (TypeCandidate candidate : typeCandidates) { -+ candidate.render(typeParameterNameMap); -+ } -+ } -+ -+ @NotNull -+ public String[] getPossibleNamesFromExpression() { -+ if (cachedNameCandidatesFromExpression != null) return cachedNameCandidatesFromExpression; -+ if (isType()) { -+ cachedNameCandidatesFromExpression = ArrayUtil.EMPTY_STRING_ARRAY; -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ JetNameValidator dummyValidator = new DummyJetNameValidator(expressionOfType.getProject()); -+ cachedNameCandidatesFromExpression = JetNameSuggester.suggestNamesForExpression(expressionOfType, dummyValidator); -+ } -+ return cachedNameCandidatesFromExpression; -+ } -+ } -+ -+ /** -+ * Encapsulates information about a method parameter that is going to be created. -+ */ -+ private static class Parameter { -+ private final String preferredName; -+ private final TypeOrExpressionThereof type; -+ -+ public Parameter(@Nullable(""no preferred name"") String preferredName, TypeOrExpressionThereof type) { -+ this.preferredName = preferredName; -+ this.type = type; -+ } -+ -+ public String getPreferredName() { -+ return preferredName; -+ } -+ -+ public TypeOrExpressionThereof getType() { -+ return type; -+ } -+ } -+ -+ /** -+ * Special Expression for parameter names based on its type. -+ */ -+ private static class ParameterNameExpression extends Expression { -+ private final String[] names; -+ private final Map parameterTypeToNamesMap; -+ -+ public ParameterNameExpression(@NotNull String[] names, @NotNull Map parameterTypeToNamesMap) { -+ for (String name : names) { -+ assert name != null && !name.isEmpty(); -+ } -+ this.names = names; -+ this.parameterTypeToNamesMap = parameterTypeToNamesMap; -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ LookupElement[] lookupItems = calculateLookupItems(context); -+ if (lookupItems.length == 0) return new TextResult(""""); -+ -+ return new TextResult(lookupItems[0].getLookupString()); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ Set names = new LinkedHashSet(); -+ Collections.addAll(names, this.names); -+ -+ // find the parameter list -+ Project project = context.getProject(); -+ int offset = context.getStartOffset(); -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ Editor editor = context.getEditor(); -+ assert editor != null; -+ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); -+ assert file != null && file instanceof JetFile; -+ PsiElement elementAt = file.findElementAt(offset); -+ JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); -+ if (func == null) return new LookupElement[0]; -+ JetParameterList parameterList = func.getValueParameterList(); -+ assert parameterList != null; -+ -+ // add names based on selected type -+ JetParameter parameter = PsiTreeUtil.getParentOfType(elementAt, JetParameter.class); -+ if (parameter != null) { -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ String[] suggestedNamesBasedOnType = parameterTypeToNamesMap.get(parameterTypeRef.getText()); -+ if (suggestedNamesBasedOnType != null) { -+ Collections.addAll(names, suggestedNamesBasedOnType); -+ } -+ } -+ } -+ -+ // remember other parameter names for later use -+ Set parameterNames = new HashSet(); -+ for (JetParameter jetParameter : parameterList.getParameters()) { -+ if (jetParameter == parameter || jetParameter.getName() == null) continue; -+ parameterNames.add(jetParameter.getName()); -+ } -+ -+ // add fallback parameter name -+ if (names.isEmpty()) { -+ names.add(""arg""); -+ } -+ -+ // ensure there are no conflicts -+ List lookupElements = new ArrayList(); -+ for (String name : names) { -+ name = getNextAvailableName(name, parameterNames); -+ lookupElements.add(LookupElementBuilder.create(name)); -+ } -+ -+ // create and return -+ return lookupElements.toArray(new LookupElement[lookupElements.size()]); -+ } -+ } -+ -+ /** -+ * An Expression for type references. -+ */ -+ private static class TypeExpression extends Expression { -+ private final TypeOrExpressionThereof type; -+ private @NotNull LookupElement[] cachedLookupElements; -+ -+ public TypeExpression(@NotNull TypeOrExpressionThereof type) { -+ this.type = type; -+ TypeCandidate[] candidates = type.getTypeCandidates(); -+ cachedLookupElements = new LookupElement[candidates.length]; -+ for (int i = 0; i < candidates.length; i++) { -+ cachedLookupElements[i] = LookupElementBuilder.create(candidates[i], candidates[i].getRenderedType()); -+ } -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ LookupElement[] lookupItems = calculateLookupItems(context); -+ if (lookupItems.length == 0) return new TextResult(""""); -+ -+ return new TextResult(lookupItems[0].getLookupString()); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ return cachedLookupElements; -+ } -+ -+ @NotNull -+ public TypeOrExpressionThereof getType() { -+ return type; -+ } -+ -+ @Nullable(""can't be found"") -+ public JetType getTypeFromSelection(@NotNull String selection) { -+ TypeCandidate[] options = type.getTypeCandidates(); -+ for (TypeCandidate option : options) { -+ if (option.getRenderedType().equals(selection)) { -+ return option.getType(); -+ } -+ } -+ return null; -+ } -+ } -+ -+ /** -+ * A sort-of dummy Expression for parameter lists, to allow us to update the parameter list as the user makes selections. -+ */ -+ private static class TypeParameterListExpression extends Expression { -+ private final String[] typeParameterNamesFromReceiverType; -+ private final Map parameterTypeToTypeParameterNamesMap; -+ -+ public TypeParameterListExpression( -+ @NotNull String[] typeParameterNamesFromReceiverType, -+ @NotNull Map typeParametersMap -+ ) { -+ this.typeParameterNamesFromReceiverType = typeParameterNamesFromReceiverType; -+ this.parameterTypeToTypeParameterNamesMap = typeParametersMap; -+ } -+ -+ @NotNull -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ Project project = context.getProject(); -+ int offset = context.getStartOffset(); -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ Editor editor = context.getEditor(); -+ assert editor != null; -+ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); -+ assert file != null && file instanceof JetFile; -+ PsiElement elementAt = file.findElementAt(offset); -+ JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); -+ if (func == null) { -+ return new TextResult(""""); -+ } -+ List parameters = func.getValueParameters(); -+ -+ Set typeParameterNames = new LinkedHashSet(); -+ Collections.addAll(typeParameterNames, typeParameterNamesFromReceiverType); -+ for (JetParameter parameter : parameters) { -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ String[] typeParameterNamesFromParameter = parameterTypeToTypeParameterNamesMap.get(parameterTypeRef.getText()); -+ if (typeParameterNamesFromParameter != null) { -+ Collections.addAll(typeParameterNames, typeParameterNamesFromParameter); -+ } -+ } -+ } -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ if (returnTypeRef != null) { -+ String[] typeParameterNamesFromReturnType = parameterTypeToTypeParameterNamesMap.get(returnTypeRef.getText()); -+ if (typeParameterNamesFromReturnType != null) { -+ Collections.addAll(typeParameterNames, typeParameterNamesFromReturnType); -+ } -+ } -+ -+ return typeParameterNames.isEmpty() -+ ? new TextResult("""") -+ : new TextResult("" <"" + StringUtil.join(typeParameterNames, "", "") + "">""); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ return new LookupElement[0]; // do not offer the user any choices -+ } -+ } -+ -+ /** -+ * A JetNameValidator that always succeeds. -+ */ -+ private static class DummyJetNameValidator implements JetNameValidator { -+ private final Project project; -+ -+ public DummyJetNameValidator(Project project) { -+ this.project = project; -+ } -+ -+ @Nullable -+ @Override -+ public String validateName(String name) { -+ return name; -+ } -+ -+ @Override -+ public Project getProject() { -+ return project; -+ } -+ } -+ -+ /** -+ * Encapsulates a single type substitution of a JetType by another JetType. -+ */ -+ private static class TypeSubstitution { -+ private final JetType forType; -+ private final JetType byType; -+ -+ private TypeSubstitution(JetType forType, JetType byType) { -+ this.forType = forType; -+ this.byType = byType; -+ } -+ -+ private JetType getForType() { -+ return forType; -+ } -+ -+ private JetType getByType() { -+ return byType; -+ } -+ } -+ -+ private final String methodName; -+ private final TypeOrExpressionThereof ownerType; -+ private final TypeOrExpressionThereof returnType; -+ private final List parameters; -+ -+ private boolean isUnit; -+ private boolean isExtension; -+ private JetFile currentFile; -+ private JetFile containingFile; -+ private Editor currentFileEditor; -+ private Editor containingFileEditor; -+ private BindingContext currentFileContext; -+ private JetClass ownerClass; -+ private ClassDescriptor ownerClassDescriptor; -+ private TypeCandidate selectedReceiverType; -+ private Map typeParameterNameMap; -+ -+ public CreateMethodFromUsageFix(@NotNull PsiElement element, @NotNull TypeOrExpressionThereof ownerType, @NotNull String methodName, -+ @NotNull TypeOrExpressionThereof returnType, @NotNull List parameters) { -+ super(element); -+ this.methodName = methodName; -+ this.ownerType = ownerType; -+ this.returnType = returnType; -+ this.parameters = parameters; -+ } -+ -+ @NotNull -+ @Override -+ public String getText() { -+ return JetBundle.message(""create.method.from.usage"", methodName); -+ } -+ -+ @Override -+ public void invoke(@NotNull final Project project, Editor editor, PsiFile file) throws IncorrectOperationException { -+ assert file != null && file instanceof JetFile; -+ currentFile = (JetFile) file; -+ currentFileEditor = editor; -+ currentFileContext = AnalyzerFacadeWithCache.analyzeFileWithCache(currentFile).getBindingContext(); -+ -+ ownerType.computeTypeCandidates(currentFileContext); -+ TypeCandidate[] ownerTypeCandidates = ownerType.getTypeCandidates(); -+ assert ownerTypeCandidates.length > 0; -+ if (ownerTypeCandidates.length == 1 || ApplicationManager.getApplication().isUnitTestMode()) { -+ selectedReceiverType = ownerTypeCandidates[0]; -+ doInvoke(project); -+ } else { -+ // class selection -+ List options = new ArrayList(); -+ final Map optionToTypeMap = new HashMap(); -+ for (TypeCandidate ownerTypeCandidate : ownerTypeCandidates) { -+ ClassifierDescriptor possibleClassDescriptor = ownerTypeCandidate.getType().getConstructor().getDeclarationDescriptor(); -+ if (possibleClassDescriptor != null) { -+ String className = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(possibleClassDescriptor.getDefaultType()); -+ DeclarationDescriptor namespaceDescriptor = possibleClassDescriptor.getContainingDeclaration(); -+ String namespace = renderDescriptor(namespaceDescriptor, true); -+ String option = className + "" ("" + namespace + "")""; -+ options.add(option); -+ optionToTypeMap.put(option, ownerTypeCandidate); -+ } -+ } -+ -+ final JList list = new JBList(options); -+ PsiElementListCellRenderer renderer = new JetLightClassListCellRenderer(); -+ list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); -+ list.setCellRenderer(renderer); -+ PopupChooserBuilder builder = new PopupChooserBuilder(list); -+ renderer.installSpeedSearch(builder); -+ -+ Runnable runnable = new Runnable() { -+ @Override -+ public void run() { -+ int index = list.getSelectedIndex(); -+ if (index < 0) return; -+ String option = (String) list.getSelectedValue(); -+ selectedReceiverType = optionToTypeMap.get(option); -+ CommandProcessor.getInstance().executeCommand(project, new Runnable() { -+ @Override -+ public void run() { -+ doInvoke(project); -+ } -+ }, getText(), null); -+ } -+ }; -+ -+ builder.setTitle(JetBundle.message(""choose.target.class.or.trait.title"")) -+ .setItemChoosenCallback(runnable) -+ .createPopup() -+ .showInBestPositionFor(currentFileEditor); -+ } -+ } -+ -+ private void doInvoke(@NotNull final Project project) { -+ // gather relevant information -+ ClassifierDescriptor ownerTypeDescriptor = selectedReceiverType.getType().getConstructor().getDeclarationDescriptor(); -+ assert ownerTypeDescriptor != null && ownerTypeDescriptor instanceof ClassDescriptor; -+ ownerClassDescriptor = (ClassDescriptor) ownerTypeDescriptor; -+ JetType receiverType = ownerClassDescriptor.getDefaultType(); -+ PsiElement typeDeclaration = BindingContextUtils.classDescriptorToDeclaration(currentFileContext, ownerClassDescriptor); -+ if (typeDeclaration != null && typeDeclaration instanceof JetClass) { -+ ownerClass = (JetClass) typeDeclaration; -+ isExtension = !ownerClass.isWritable(); -+ } else { -+ isExtension = true; -+ } -+ isUnit = returnType.isType() && isUnit(returnType.getType()); -+ -+ JetScope scope; -+ if (isExtension) { -+ NamespaceDescriptor namespaceDescriptor = currentFileContext.get(BindingContext.FILE_TO_NAMESPACE, currentFile); -+ assert namespaceDescriptor != null; -+ scope = namespaceDescriptor.getMemberScope(); -+ } else { -+ assert ownerClassDescriptor instanceof MutableClassDescriptor; -+ scope = ((MutableClassDescriptor) ownerClassDescriptor).getScopeForMemberResolution(); -+ } -+ -+ // figure out type substitutions for type parameters -+ List classTypeParameters = receiverType.getArguments(); -+ List ownerTypeArguments = selectedReceiverType.getType().getArguments(); -+ assert ownerTypeArguments.size() == classTypeParameters.size(); -+ TypeSubstitution[] substitutions = new TypeSubstitution[classTypeParameters.size()]; -+ for (int i = 0; i < substitutions.length; i++) { -+ substitutions[i] = new TypeSubstitution(ownerTypeArguments.get(i).getType(), classTypeParameters.get(i).getType()); -+ } -+ for (Parameter parameter : parameters) { -+ parameter.getType().computeTypeCandidates(currentFileContext, substitutions, scope); -+ } -+ if (!isUnit) { -+ returnType.computeTypeCandidates(currentFileContext, substitutions, scope); -+ } -+ -+ // now that we have done substitutions, we can throw it away -+ selectedReceiverType = new TypeCandidate(receiverType, scope); -+ -+ // figure out type parameter renames to avoid conflicts -+ typeParameterNameMap = getTypeParameterRenames(scope); -+ for (Parameter parameter : parameters) { -+ parameter.getType().renderTypeCandidates(typeParameterNameMap); -+ } -+ if (!isUnit) { -+ returnType.renderTypeCandidates(typeParameterNameMap); -+ } -+ selectedReceiverType.render(typeParameterNameMap); -+ -+ ApplicationManager.getApplication().runWriteAction(new Runnable() { -+ @Override -+ public void run() { -+ JetNamedFunction func = createFunctionSkeleton(project); -+ buildAndRunTemplate(project, func); -+ } -+ }); -+ } -+ -+ private JetNamedFunction createFunctionSkeleton(@NotNull Project project) { -+ JetNamedFunction func; -+ String[] parameterStrings = new String[parameters.size()]; -+ for (int i = 0; i < parameterStrings.length; i++) { -+ parameterStrings[i] = ""p"" + i + "": Any""; -+ } -+ String parametersString = StringUtil.join(parameterStrings,"", ""); -+ String returnTypeString = isUnit ? """" : "": Any""; -+ if (isExtension) { // create as extension function -+ String ownerTypeString = selectedReceiverType.getRenderedType(); -+ String methodText = String.format(""fun %s.%s(%s)%s { }"", ownerTypeString, methodName, parametersString, returnTypeString); -+ func = JetPsiFactory.createFunction(project, methodText); -+ containingFile = currentFile; -+ containingFileEditor = currentFileEditor; -+ func = (JetNamedFunction) currentFile.add(func); -+ } else { // create as method -+ String methodText = String.format(""fun %s(%s)%s { }"", methodName, parametersString, returnTypeString); -+ func = JetPsiFactory.createFunction(project, methodText); -+ PsiFile classContainingFile = ownerClass.getContainingFile(); -+ assert classContainingFile instanceof JetFile; -+ containingFile = (JetFile) classContainingFile; -+ -+ VirtualFile virtualFile = containingFile.getVirtualFile(); -+ assert virtualFile != null; -+ FileEditorManager fileEditorManager = FileEditorManager.getInstance(project); -+ fileEditorManager.openFile(virtualFile, true); -+ containingFileEditor = fileEditorManager.getSelectedTextEditor(); -+ -+ JetClassBody classBody = ownerClass.getBody(); -+ if (classBody == null) { -+ classBody = (JetClassBody) ownerClass.add(JetPsiFactory.createEmptyClassBody(project)); -+ ownerClass.addBefore(JetPsiFactory.createWhiteSpace(project), classBody); -+ } -+ PsiElement rBrace = classBody.getRBrace(); -+ assert rBrace != null; -+ func = (JetNamedFunction) classBody.addBefore(func, rBrace); -+ } -+ -+ return func; -+ } -+ -+ private void buildAndRunTemplate(@NotNull final Project project, @NotNull JetNamedFunction func) { -+ JetParameterList parameterList = func.getValueParameterList(); -+ assert parameterList != null; -+ -+ // build templates -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(containingFileEditor.getDocument()); -+ -+ CaretModel caretModel = containingFileEditor.getCaretModel(); -+ caretModel.moveToOffset(containingFile.getNode().getStartOffset()); -+ -+ TemplateBuilderImpl builder = new TemplateBuilderImpl(containingFile); -+ final TypeExpression returnTypeExpression = isUnit ? null : setupReturnTypeTemplate(builder, func); -+ final TypeExpression[] parameterTypeExpressions = setupParameterTypeTemplates(project, builder, parameterList); -+ -+ // add a segment for the parameter list -+ // Note: because TemplateBuilderImpl does not have a replaceElement overload that takes in both a TextRange and alwaysStopAt, we -+ // need to create the segment first and then hack the Expression into the template later. We use this template to update the type -+ // parameter list as the user makes selections in the parameter types, and we need alwaysStopAt to be false so the user can't tab to -+ // it. -+ TypeParameterListExpression expression = setupTypeParameterListTemplate(builder, func); -+ -+ // the template built by TemplateBuilderImpl is ordered by element position, but we want types to be first, so hack it -+ final TemplateImpl template = (TemplateImpl) builder.buildInlineTemplate(); -+ ArrayList variables = template.getVariables(); -+ for (int i = 0; i < parameters.size(); i++) { -+ Collections.swap(variables, i * 2, i * 2 + 1); -+ } -+ -+ // fix up the template to include the expression for the type parameter list -+ variables.add(new Variable(TYPE_PARAMETER_LIST_VARIABLE_NAME, expression, expression, false, true)); -+ -+ // run the template -+ TemplateManager.getInstance(project).startTemplate(containingFileEditor, template, new TemplateEditingAdapter() { -+ @Override -+ public void templateFinished(Template _, boolean brokenOff) { -+ // file templates -+ int offset = template.getSegmentOffset(0); -+ final JetNamedFunction func = PsiTreeUtil.findElementOfClassAtOffset(containingFile, offset, JetNamedFunction.class, false); -+ assert func != null; -+ final List typeRefsToShorten = new ArrayList(); -+ -+ ApplicationManager.getApplication().runWriteAction(new Runnable() { -+ @Override -+ public void run() { -+ // file templates -+ setupFunctionBody(project, func); -+ -+ // change short type names to fully qualified ones (to be shortened below) -+ setupTypeReferencesForShortening(project, func, typeRefsToShorten, parameterTypeExpressions, returnTypeExpression); -+ } -+ }); -+ -+ ReferenceToClassesShortening.compactReferenceToClasses(typeRefsToShorten); -+ } -+ }); -+ } -+ -+ private Map getTypeParameterRenames(JetScope scope) { -+ TypeParameterDescriptor[] receiverTypeParametersNotInScope = selectedReceiverType.getTypeParameters(); -+ Set allTypeParametersNotInScope = new LinkedHashSet(); -+ allTypeParametersNotInScope.addAll(Arrays.asList(receiverTypeParametersNotInScope)); -+ -+ for (Parameter parameter : parameters) { -+ TypeCandidate[] parameterTypeCandidates = parameter.getType().getTypeCandidates(); -+ for (TypeCandidate parameterTypeCandidate : parameterTypeCandidates) { -+ allTypeParametersNotInScope.addAll(Arrays.asList(parameterTypeCandidate.getTypeParameters())); -+ } -+ } -+ -+ if (!isUnit) { -+ TypeCandidate[] returnTypeCandidates = returnType.getTypeCandidates(); -+ for (TypeCandidate returnTypeCandidate : returnTypeCandidates) { -+ allTypeParametersNotInScope.addAll(Arrays.asList(returnTypeCandidate.getTypeParameters())); -+ } -+ } -+ -+ List typeParameters = new ArrayList(allTypeParametersNotInScope); -+ List typeParameterNames = new ArrayList(); -+ for (TypeParameterDescriptor typeParameter : typeParameters) { -+ typeParameterNames.add(getNextAvailableName(typeParameter.getName().getName(), typeParameterNames, scope)); -+ } -+ assert typeParameters.size() == typeParameterNames.size(); -+ Map typeParameterNameMap = new HashMap(); -+ for (int i = 0; i < typeParameters.size(); i++) { -+ typeParameterNameMap.put(typeParameters.get(i), typeParameterNames.get(i)); -+ } -+ -+ return typeParameterNameMap; -+ } -+ -+ private void setupTypeReferencesForShortening( -+ @NotNull Project project, -+ @NotNull JetNamedFunction func, -+ @NotNull List typeRefsToShorten, -+ @NotNull TypeExpression[] parameterTypeExpressions, -+ @Nullable TypeExpression returnTypeExpression -+ ) { -+ if (isExtension) { -+ JetTypeReference receiverTypeRef = -+ JetPsiFactory.createType(project, renderTypeLong(selectedReceiverType.getType(), typeParameterNameMap)); -+ replaceWithLongerName(project, receiverTypeRef, selectedReceiverType.getType()); -+ -+ receiverTypeRef = func.getReceiverTypeRef(); -+ if (receiverTypeRef != null) { -+ typeRefsToShorten.add(receiverTypeRef); -+ } -+ } -+ -+ if (!isUnit) { -+ assert returnTypeExpression != null; -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ if (returnTypeRef != null) { -+ JetType returnType = returnTypeExpression.getTypeFromSelection(returnTypeRef.getText()); -+ if (returnType != null) { // user selected a given type -+ replaceWithLongerName(project, returnTypeRef, returnType); -+ returnTypeRef = func.getReturnTypeRef(); -+ assert returnTypeRef != null; -+ typeRefsToShorten.add(returnTypeRef); -+ } -+ } -+ } -+ -+ List valueParameters = func.getValueParameters(); -+ List parameterIndicesToShorten = new ArrayList(); -+ assert valueParameters.size() == parameterTypeExpressions.length; -+ for (int i = 0; i < valueParameters.size(); i++) { -+ JetParameter parameter = valueParameters.get(i); -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ JetType parameterType = parameterTypeExpressions[i].getTypeFromSelection(parameterTypeRef.getText()); -+ if (parameterType != null) { -+ replaceWithLongerName(project, parameterTypeRef, parameterType); -+ parameterIndicesToShorten.add(i); -+ } -+ } -+ } -+ valueParameters = func.getValueParameters(); -+ for (int i : parameterIndicesToShorten) { -+ JetTypeReference parameterTypeRef = valueParameters.get(i).getTypeReference(); -+ if (parameterTypeRef != null) { -+ typeRefsToShorten.add(parameterTypeRef); -+ } -+ } -+ } -+ -+ private void setupFunctionBody(@NotNull Project project, @NotNull JetNamedFunction func) { -+ FileTemplate fileTemplate = FileTemplateManager.getInstance().getCodeTemplate(TEMPLATE_FROM_USAGE_METHOD_BODY); -+ Properties properties = new Properties(); -+ if (isUnit) { -+ properties.setProperty(FileTemplate.ATTRIBUTE_RETURN_TYPE, ""Unit""); -+ } else { -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ assert returnTypeRef != null; -+ properties.setProperty(FileTemplate.ATTRIBUTE_RETURN_TYPE, returnTypeRef.getText()); -+ } -+ properties.setProperty(FileTemplate.ATTRIBUTE_CLASS_NAME, DescriptorUtils.getFQName(ownerClassDescriptor).getFqName()); -+ properties.setProperty(FileTemplate.ATTRIBUTE_SIMPLE_CLASS_NAME, ownerClassDescriptor.getName().getName()); -+ properties.setProperty(FileTemplate.ATTRIBUTE_METHOD_NAME, methodName); -+ -+ @NonNls String bodyText; -+ try { -+ bodyText = fileTemplate.getText(properties); -+ } catch (ProcessCanceledException e) { -+ throw e; -+ } catch (Exception e) { -+ throw new IncorrectOperationException(""Failed to parse file template"", e); -+ } -+ JetExpression newBodyExpression = JetPsiFactory.createFunctionBody(project, bodyText); -+ JetExpression oldBodyExpression = func.getBodyExpression(); -+ assert oldBodyExpression != null; -+ oldBodyExpression.replace(newBodyExpression); -+ } -+ -+ @NotNull -+ private TypeExpression setupReturnTypeTemplate(@NotNull TemplateBuilder builder, @NotNull JetNamedFunction func) { -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ assert returnTypeRef != null; -+ TypeExpression returnTypeExpression = new TypeExpression(returnType); -+ builder.replaceElement(returnTypeRef, returnTypeExpression); -+ return returnTypeExpression; -+ } -+ -+ @NotNull -+ private TypeParameterListExpression setupTypeParameterListTemplate(@NotNull TemplateBuilderImpl builder, @NotNull JetNamedFunction func) { -+ Map typeParameterMap = new HashMap(); -+ String[] receiverTypeParameterNames = selectedReceiverType.getTypeParameterNames(); -+ -+ for (Parameter parameter : parameters) { -+ TypeCandidate[] parameterTypeCandidates = parameter.getType().getTypeCandidates(); -+ for (TypeCandidate parameterTypeCandidate : parameterTypeCandidates) { -+ typeParameterMap.put(parameterTypeCandidate.getRenderedType(), parameterTypeCandidate.getTypeParameterNames()); -+ } -+ } -+ -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ if (returnTypeRef != null) { -+ TypeCandidate[] returnTypeCandidates = returnType.getTypeCandidates(); -+ for (TypeCandidate returnTypeCandidate : returnTypeCandidates) { -+ typeParameterMap.put(returnTypeCandidate.getRenderedType(), returnTypeCandidate.getTypeParameterNames()); -+ } -+ } -+ -+ builder.replaceElement(func, TextRange.create(3, 3), TYPE_PARAMETER_LIST_VARIABLE_NAME, null, false); // ((3, 3) is after ""fun"") -+ return new TypeParameterListExpression(receiverTypeParameterNames, typeParameterMap); -+ } -+ -+ private TypeExpression[] setupParameterTypeTemplates(@NotNull Project project, @NotNull TemplateBuilder builder, -+ @NotNull JetParameterList parameterList) { -+ List jetParameters = parameterList.getParameters(); -+ assert jetParameters.size() == parameters.size(); -+ TypeExpression[] parameterTypeExpressions = new TypeExpression[parameters.size()]; -+ JetNameValidator dummyValidator = new DummyJetNameValidator(project); -+ for (int i = 0; i < parameters.size(); i++) { -+ Parameter parameter = parameters.get(i); -+ JetParameter jetParameter = jetParameters.get(i); -+ -+ // add parameter type to the template -+ parameterTypeExpressions[i] = new TypeExpression(parameter.getType()); -+ JetTypeReference parameterTypeRef = jetParameter.getTypeReference(); -+ assert parameterTypeRef != null; -+ builder.replaceElement(parameterTypeRef, parameterTypeExpressions[i]); -+ -+ // add parameter name to the template -+ String[] possibleNamesFromExpression = parameter.getType().getPossibleNamesFromExpression(); -+ String preferredName = parameter.getPreferredName(); -+ String[] possibleNames; -+ if (preferredName != null) { -+ possibleNames = new String[possibleNamesFromExpression.length + 1]; -+ possibleNames[0] = preferredName; -+ System.arraycopy(possibleNamesFromExpression, 0, possibleNames, 1, possibleNamesFromExpression.length); -+ } else { -+ possibleNames = possibleNamesFromExpression; -+ } -+ -+ // figure out suggested names for each type option -+ Map parameterTypeToNamesMap = new HashMap(); -+ for (TypeCandidate typeCandidate : parameter.getType().getTypeCandidates()) { -+ String[] suggestedNames = JetNameSuggester.suggestNamesForType(typeCandidate.getType(), dummyValidator); -+ parameterTypeToNamesMap.put(typeCandidate.getRenderedType(), suggestedNames); -+ } -+ -+ // add expression to builder -+ Expression parameterNameExpression = new ParameterNameExpression(possibleNames, parameterTypeToNamesMap); -+ PsiElement parameterNameIdentifier = jetParameter.getNameIdentifier(); -+ assert parameterNameIdentifier != null; -+ builder.replaceElement(parameterNameIdentifier, parameterNameExpression); -+ } -+ return parameterTypeExpressions; -+ } -+ -+ private void replaceWithLongerName(@NotNull Project project, @NotNull JetTypeReference typeRef, @NotNull JetType type) { -+ JetTypeReference fullyQualifiedReceiverTypeRef = JetPsiFactory.createType(project, renderTypeLong(type, typeParameterNameMap)); -+ typeRef.replace(fullyQualifiedReceiverTypeRef); -+ } -+ -+ @NotNull -+ private static JetType substituteType(@NotNull JetType type, @NotNull TypeSubstitution substitution, @NotNull Variance variance) { -+ switch (variance) { -+ case INVARIANT: -+ // for invariant, can replace only when they're equal -+ if (type.equals(substitution.getForType())) { -+ return substitution.getByType(); -+ } -+ break; -+ case IN_VARIANCE: -+ // for covariant (e.g. function parameter), can replace type with any of its supertypes -+ if (JetTypeChecker.INSTANCE.isSubtypeOf(type, substitution.getForType())) { -+ return substitution.getByType(); -+ } -+ break; -+ case OUT_VARIANCE: -+ // for contravariant (e.g. function return value), can replace type with any of its subtypes -+ if (JetTypeChecker.INSTANCE.isSubtypeOf(substitution.getForType(), type)) { -+ return substitution.getByType(); -+ } -+ break; -+ } -+ -+ List newArguments = new ArrayList(); -+ List typeParameters = type.getConstructor().getParameters(); -+ int i = 0; -+ for (TypeProjection projection : type.getArguments()) { -+ TypeParameterDescriptor typeParameter = typeParameters.get(i); -+ JetType newArgument = substituteType(projection.getType(), substitution, typeParameter.getVariance()); -+ newArguments.add(new TypeProjection(Variance.INVARIANT, newArgument)); -+ i++; -+ } -+ return new JetTypeImpl(type.getAnnotations(), type.getConstructor(), -+ type.isNullable(), newArguments, type.getMemberScope()); -+ } -+ -+ private static boolean containsType(JetType outer, JetType inner) { -+ if (outer.equals(inner)) { -+ return true; -+ } -+ -+ for (TypeProjection projection : outer.getArguments()) { -+ if (containsType(projection.getType(), inner)) { -+ return true; -+ } -+ } -+ -+ return false; -+ } -+ -+ @NotNull -+ private static String renderDescriptor( -+ @NotNull DeclarationDescriptor declarationDescriptor, -+ @NotNull Map typeParameterNameMap, -+ boolean fq -+ ) { -+ if (declarationDescriptor instanceof TypeParameterDescriptor) { -+ String replacement = typeParameterNameMap.get(declarationDescriptor); -+ return replacement == null ? declarationDescriptor.getName().getName() : replacement; -+ } else { -+ return fq ? DescriptorUtils.getFQName(declarationDescriptor).getFqName() : declarationDescriptor.getName().getName(); -+ } -+ } -+ -+ @NotNull -+ private static String renderDescriptor(@NotNull DeclarationDescriptor declarationDescriptor, boolean fq) { -+ return renderDescriptor(declarationDescriptor, Collections.emptyMap(), fq); -+ } -+ -+ private static String renderType(@NotNull JetType type, @NotNull Map typeParameterNameMap, boolean fq) { -+ List projections = type.getArguments(); -+ DeclarationDescriptor declarationDescriptor = type.getConstructor().getDeclarationDescriptor(); -+ assert declarationDescriptor != null; -+ if (projections.isEmpty()) { -+ return renderDescriptor(declarationDescriptor, typeParameterNameMap, fq); -+ } -+ -+ List arguments = new ArrayList(); -+ for (TypeProjection projection : projections) { -+ arguments.add(renderType(projection.getType(), typeParameterNameMap, fq)); -+ } -+ return renderDescriptor(declarationDescriptor, typeParameterNameMap, fq) + ""<"" + StringUtil.join(arguments, "", "") + "">""; -+ } -+ -+ @NotNull -+ private static String renderTypeShort(@NotNull JetType type, @NotNull Map typeParameterNameMap) { -+ return renderType(type, typeParameterNameMap, false); -+ } -+ -+ @NotNull -+ private static String renderTypeLong(@NotNull JetType type, @NotNull Map typeParameterNameMap) { -+ return renderType(type, typeParameterNameMap, true); -+ } -+ -+ @NotNull -+ private static TypeParameterDescriptor[] getTypeParameterNamesNotInScope( -+ @NotNull Collection typeParameters, -+ @NotNull JetScope scope -+ ) { -+ List typeParameterNames = new ArrayList(); -+ for (TypeParameterDescriptor typeParameter : typeParameters) { -+ ClassifierDescriptor classifier = scope.getClassifier(typeParameter.getName()); -+ if (classifier == null || !classifier.equals(typeParameter)) { -+ typeParameterNames.add(typeParameter); -+ } -+ } -+ return typeParameterNames.toArray(new TypeParameterDescriptor[typeParameterNames.size()]); -+ } -+ -+ @NotNull -+ private static Set getTypeParametersInType(@NotNull JetType type) { -+ Set typeParameters = new LinkedHashSet(); -+ List arguments = type.getArguments(); -+ if (arguments.isEmpty()) { -+ ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); -+ if (descriptor instanceof TypeParameterDescriptor) { -+ typeParameters.add((TypeParameterDescriptor) descriptor); -+ } -+ } else { -+ for (TypeProjection projection : arguments) { -+ typeParameters.addAll(getTypeParametersInType(projection.getType())); -+ } -+ } -+ return typeParameters; -+ } -+ -+ @NotNull -+ private static String getNextAvailableName(@NotNull String name, @NotNull Collection existingNames) { -+ if (existingNames.contains(name)) { -+ int j = 1; -+ while (existingNames.contains(name + j)) j++; -+ name += j; -+ } -+ return name; -+ } -+ -+ @NotNull -+ private static String getNextAvailableName(@NotNull String name, @NotNull Collection existingNames, @NotNull JetScope scope) { -+ if (existingNames.contains(name) || scope.getClassifier(Name.identifier(name)) != null) { -+ int j = 1; -+ while (existingNames.contains(name + j) || scope.getClassifier(Name.identifier(name + j)) != null) j++; -+ name += j; -+ } -+ return name; -+ } -+ -+ @NotNull -+ private static JetType[] guessTypeForExpression(@NotNull JetExpression expr, @NotNull BindingContext context) {","If this method returns several types, maybe it should be named `guessTypes...`? - -The method is very complex. -- Reassigning local variables is usually a bad style, because it makes code harder to comprehend and refactor. -- Combination of reassignments and deep if-else-if is even worse. - I offer extracting method guessTypesForDeclaration and use it immediately instead of assigning to declaration. This will allow removing reassigned variable and make each `if` end with `return`, and `else`s will be unnecessary. -",Why is this needed? Looks like a duplicate file. -110,"@@ -0,0 +1,1391 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.codeInsight.lookup.LookupElement; -+import com.intellij.codeInsight.lookup.LookupElementBuilder; -+import com.intellij.codeInsight.template.*; -+import com.intellij.codeInsight.template.impl.TemplateImpl; -+import com.intellij.codeInsight.template.impl.Variable; -+import com.intellij.ide.fileTemplates.FileTemplate; -+import com.intellij.ide.fileTemplates.FileTemplateManager; -+import com.intellij.ide.util.PsiElementListCellRenderer; -+import com.intellij.openapi.application.ApplicationManager; -+import com.intellij.openapi.command.CommandProcessor; -+import com.intellij.openapi.editor.CaretModel; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.fileEditor.FileEditorManager; -+import com.intellij.openapi.progress.ProcessCanceledException; -+import com.intellij.openapi.project.Project; -+import com.intellij.openapi.ui.popup.PopupChooserBuilder; -+import com.intellij.openapi.util.TextRange; -+import com.intellij.openapi.util.text.StringUtil; -+import com.intellij.openapi.vfs.VirtualFile; -+import com.intellij.psi.PsiDocumentManager; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.PsiReference; -+import com.intellij.psi.search.SearchScope; -+import com.intellij.psi.util.PsiTreeUtil; -+import com.intellij.refactoring.psi.SearchUtils; -+import com.intellij.ui.components.JBList; -+import com.intellij.util.ArrayUtil; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NonNls; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.descriptors.*; -+import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1; -+import org.jetbrains.jet.lang.diagnostics.Errors; -+import org.jetbrains.jet.lang.psi.*; -+import org.jetbrains.jet.lang.resolve.BindingContext; -+import org.jetbrains.jet.lang.resolve.BindingContextUtils; -+import org.jetbrains.jet.lang.resolve.DescriptorUtils; -+import org.jetbrains.jet.lang.resolve.name.Name; -+import org.jetbrains.jet.lang.resolve.scopes.JetScope; -+import org.jetbrains.jet.lang.types.*; -+import org.jetbrains.jet.lang.types.checker.JetTypeChecker; -+import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; -+import org.jetbrains.jet.plugin.JetBundle; -+import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening; -+import org.jetbrains.jet.plugin.presentation.JetLightClassListCellRenderer; -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; -+import org.jetbrains.jet.plugin.refactoring.JetNameSuggester; -+import org.jetbrains.jet.plugin.refactoring.JetNameValidator; -+import org.jetbrains.jet.plugin.references.JetSimpleNameReference; -+import org.jetbrains.jet.renderer.DescriptorRenderer; -+ -+import javax.swing.*; -+import java.util.*; -+import java.util.regex.Matcher; -+import java.util.regex.Pattern; -+ -+public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { -+ private static final String TYPE_PARAMETER_LIST_VARIABLE_NAME = ""typeParameterList""; -+ private static final String TEMPLATE_FROM_USAGE_METHOD_BODY = ""New Kotlin Method Body.kt""; -+ private static final Pattern COMPONENT_FUNCTION_PATTERN = Pattern.compile(""^component(\\d+)$""); -+ -+ /** -+ * Represents a single choice for a type (e.g. parameter type or return type). -+ */ -+ private static class TypeCandidate { -+ private final JetType type; -+ private final TypeParameterDescriptor[] typeParameters; -+ private String renderedType; -+ private String[] typeParameterNames; -+ -+ public TypeCandidate(@NotNull JetType type) { -+ this.type = type; -+ Set typeParametersInType = getTypeParametersInType(type); -+ typeParameters = typeParametersInType.toArray(new TypeParameterDescriptor[typeParametersInType.size()]); -+ renderedType = renderTypeShort(type, Collections.emptyMap()); -+ } -+ -+ public TypeCandidate(@NotNull JetType type, @NotNull JetScope scope) { -+ this.type = type; -+ typeParameters = getTypeParameterNamesNotInScope(getTypeParametersInType(type), scope); -+ } -+ -+ public void render(@NotNull Map typeParameterNameMap) { -+ renderedType = renderTypeShort(type, typeParameterNameMap); -+ typeParameterNames = new String[typeParameters.length]; -+ int i = 0; -+ for (TypeParameterDescriptor typeParameter : typeParameters) { -+ typeParameterNames[i] = typeParameterNameMap.get(typeParameter); -+ i++; -+ } -+ } -+ -+ @NotNull JetType getType() { -+ return type; -+ } -+ -+ @NotNull -+ public String getRenderedType() { -+ assert renderedType != null : ""call render() first""; -+ return renderedType; -+ } -+ -+ @NotNull -+ public String[] getTypeParameterNames() { -+ assert typeParameterNames != null : ""call render() first""; -+ return typeParameterNames; -+ } -+ -+ @NotNull -+ public TypeParameterDescriptor[] getTypeParameters() { -+ return typeParameters; -+ } -+ } -+ -+ /** -+ * Represents a concrete type or a set of types yet to be inferred from an expression. -+ */ -+ private static class TypeOrExpressionThereof { -+ private final JetExpression expressionOfType; -+ private final JetType type; -+ private final Variance variance; -+ private TypeCandidate[] typeCandidates; -+ private String[] cachedNameCandidatesFromExpression; -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType) { -+ this(expressionOfType, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType, Variance variance) { -+ this(expressionOfType, null, variance); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type) { -+ this(type, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type, Variance variance) { -+ this(null, type, variance); -+ } -+ -+ private TypeOrExpressionThereof(@Nullable JetExpression expressionOfType, @Nullable JetType type, Variance variance) { -+ this.expressionOfType = expressionOfType; -+ this.type = type; -+ this.variance = variance; -+ } -+ -+ public boolean isType() { -+ return this.type != null; -+ } -+ -+ @NotNull -+ public JetType getType() { -+ assert this.type != null; -+ return this.type; -+ } -+ -+ @NotNull -+ private List getPossibleTypes(BindingContext context) { -+ List types = new ArrayList(); -+ if (isType()) { -+ assert type != null : ""!isType() means type == null && expressionOfType != null""; -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ for (JetType type : guessTypeForExpression(expressionOfType, context)) { -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } -+ } -+ return types; -+ } -+ -+ public void computeTypeCandidates(@NotNull BindingContext context) { -+ Collection types = getPossibleTypes(context); -+ -+ typeCandidates = new TypeCandidate[types.size()]; -+ int i = 0; -+ for (JetType type : types) { -+ typeCandidates[i] = new TypeCandidate(type); -+ i++; -+ } -+ } -+ -+ public void computeTypeCandidates( -+ @NotNull BindingContext context, -+ @NotNull TypeSubstitution[] substitutions, -+ @NotNull JetScope scope -+ ) { -+ List types = getPossibleTypes(context); -+ Collections.reverse(types); // reverse and reverse back later, so that things added below are added at the front -+ -+ Set newTypes = new LinkedHashSet(types); -+ for (TypeSubstitution substitution : substitutions) { // each substitution can be applied or not, so we offer all options -+ List toAdd = new ArrayList(); -+ List toRemove = new ArrayList(); -+ for (JetType type : newTypes) { -+ toAdd.add(substituteType(type, substitution, variance)); -+ // substitution.byType are type arguments, but they cannot already occur in the type before substitution -+ if (containsType(type, substitution.getByType())) { -+ toRemove.add(type); -+ } -+ } -+ newTypes.addAll(toAdd); -+ newTypes.removeAll(toRemove); -+ } -+ -+ if (newTypes.isEmpty()) { -+ newTypes.add(KotlinBuiltIns.getInstance().getAnyType()); -+ } -+ -+ typeCandidates = new TypeCandidate[newTypes.size()]; -+ int i = typeCandidates.length - 1; // reverse order (see explanation above) -+ for (JetType type : newTypes) { -+ typeCandidates[i] = new TypeCandidate(type, scope); -+ i--; -+ } -+ } -+ -+ @NotNull -+ public TypeCandidate[] getTypeCandidates() { -+ assert typeCandidates != null : ""call computeTypeCandidates() first""; -+ return typeCandidates; -+ } -+ -+ public void renderTypeCandidates(@NotNull Map typeParameterNameMap) { -+ for (TypeCandidate candidate : typeCandidates) { -+ candidate.render(typeParameterNameMap); -+ } -+ } -+ -+ @NotNull -+ public String[] getPossibleNamesFromExpression() { -+ if (cachedNameCandidatesFromExpression != null) return cachedNameCandidatesFromExpression; -+ if (isType()) { -+ cachedNameCandidatesFromExpression = ArrayUtil.EMPTY_STRING_ARRAY; -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ JetNameValidator dummyValidator = new DummyJetNameValidator(expressionOfType.getProject()); -+ cachedNameCandidatesFromExpression = JetNameSuggester.suggestNamesForExpression(expressionOfType, dummyValidator); -+ } -+ return cachedNameCandidatesFromExpression; -+ } -+ } -+ -+ /** -+ * Encapsulates information about a method parameter that is going to be created. -+ */ -+ private static class Parameter { -+ private final String preferredName; -+ private final TypeOrExpressionThereof type; -+ -+ public Parameter(@Nullable(""no preferred name"") String preferredName, TypeOrExpressionThereof type) { -+ this.preferredName = preferredName; -+ this.type = type; -+ } -+ -+ public String getPreferredName() { -+ return preferredName; -+ } -+ -+ public TypeOrExpressionThereof getType() { -+ return type; -+ } -+ } -+ -+ /** -+ * Special Expression for parameter names based on its type. -+ */ -+ private static class ParameterNameExpression extends Expression { -+ private final String[] names; -+ private final Map parameterTypeToNamesMap; -+ -+ public ParameterNameExpression(@NotNull String[] names, @NotNull Map parameterTypeToNamesMap) { -+ for (String name : names) { -+ assert name != null && !name.isEmpty(); -+ } -+ this.names = names; -+ this.parameterTypeToNamesMap = parameterTypeToNamesMap; -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ LookupElement[] lookupItems = calculateLookupItems(context); -+ if (lookupItems.length == 0) return new TextResult(""""); -+ -+ return new TextResult(lookupItems[0].getLookupString()); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ Set names = new LinkedHashSet(); -+ Collections.addAll(names, this.names); -+ -+ // find the parameter list -+ Project project = context.getProject(); -+ int offset = context.getStartOffset(); -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ Editor editor = context.getEditor(); -+ assert editor != null; -+ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); -+ assert file != null && file instanceof JetFile; -+ PsiElement elementAt = file.findElementAt(offset); -+ JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); -+ if (func == null) return new LookupElement[0]; -+ JetParameterList parameterList = func.getValueParameterList(); -+ assert parameterList != null; -+ -+ // add names based on selected type -+ JetParameter parameter = PsiTreeUtil.getParentOfType(elementAt, JetParameter.class); -+ if (parameter != null) { -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ String[] suggestedNamesBasedOnType = parameterTypeToNamesMap.get(parameterTypeRef.getText()); -+ if (suggestedNamesBasedOnType != null) { -+ Collections.addAll(names, suggestedNamesBasedOnType); -+ } -+ } -+ } -+ -+ // remember other parameter names for later use -+ Set parameterNames = new HashSet(); -+ for (JetParameter jetParameter : parameterList.getParameters()) { -+ if (jetParameter == parameter || jetParameter.getName() == null) continue; -+ parameterNames.add(jetParameter.getName()); -+ } -+ -+ // add fallback parameter name -+ if (names.isEmpty()) { -+ names.add(""arg""); -+ } -+ -+ // ensure there are no conflicts -+ List lookupElements = new ArrayList(); -+ for (String name : names) { -+ name = getNextAvailableName(name, parameterNames); -+ lookupElements.add(LookupElementBuilder.create(name)); -+ } -+ -+ // create and return -+ return lookupElements.toArray(new LookupElement[lookupElements.size()]); -+ } -+ } -+ -+ /** -+ * An Expression for type references. -+ */ -+ private static class TypeExpression extends Expression { -+ private final TypeOrExpressionThereof type; -+ private @NotNull LookupElement[] cachedLookupElements; -+ -+ public TypeExpression(@NotNull TypeOrExpressionThereof type) { -+ this.type = type; -+ TypeCandidate[] candidates = type.getTypeCandidates(); -+ cachedLookupElements = new LookupElement[candidates.length]; -+ for (int i = 0; i < candidates.length; i++) { -+ cachedLookupElements[i] = LookupElementBuilder.create(candidates[i], candidates[i].getRenderedType()); -+ } -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ LookupElement[] lookupItems = calculateLookupItems(context); -+ if (lookupItems.length == 0) return new TextResult(""""); -+ -+ return new TextResult(lookupItems[0].getLookupString()); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ return cachedLookupElements; -+ } -+ -+ @NotNull -+ public TypeOrExpressionThereof getType() { -+ return type; -+ } -+ -+ @Nullable(""can't be found"") -+ public JetType getTypeFromSelection(@NotNull String selection) { -+ TypeCandidate[] options = type.getTypeCandidates(); -+ for (TypeCandidate option : options) { -+ if (option.getRenderedType().equals(selection)) { -+ return option.getType(); -+ } -+ } -+ return null; -+ } -+ } -+ -+ /** -+ * A sort-of dummy Expression for parameter lists, to allow us to update the parameter list as the user makes selections. -+ */ -+ private static class TypeParameterListExpression extends Expression { -+ private final String[] typeParameterNamesFromReceiverType; -+ private final Map parameterTypeToTypeParameterNamesMap; -+ -+ public TypeParameterListExpression( -+ @NotNull String[] typeParameterNamesFromReceiverType, -+ @NotNull Map typeParametersMap -+ ) { -+ this.typeParameterNamesFromReceiverType = typeParameterNamesFromReceiverType; -+ this.parameterTypeToTypeParameterNamesMap = typeParametersMap; -+ } -+ -+ @NotNull -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ Project project = context.getProject(); -+ int offset = context.getStartOffset(); -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ Editor editor = context.getEditor(); -+ assert editor != null; -+ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); -+ assert file != null && file instanceof JetFile; -+ PsiElement elementAt = file.findElementAt(offset); -+ JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); -+ if (func == null) { -+ return new TextResult(""""); -+ } -+ List parameters = func.getValueParameters(); -+ -+ Set typeParameterNames = new LinkedHashSet(); -+ Collections.addAll(typeParameterNames, typeParameterNamesFromReceiverType); -+ for (JetParameter parameter : parameters) { -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ String[] typeParameterNamesFromParameter = parameterTypeToTypeParameterNamesMap.get(parameterTypeRef.getText()); -+ if (typeParameterNamesFromParameter != null) { -+ Collections.addAll(typeParameterNames, typeParameterNamesFromParameter); -+ } -+ } -+ } -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ if (returnTypeRef != null) { -+ String[] typeParameterNamesFromReturnType = parameterTypeToTypeParameterNamesMap.get(returnTypeRef.getText()); -+ if (typeParameterNamesFromReturnType != null) { -+ Collections.addAll(typeParameterNames, typeParameterNamesFromReturnType); -+ } -+ } -+ -+ return typeParameterNames.isEmpty() -+ ? new TextResult("""") -+ : new TextResult("" <"" + StringUtil.join(typeParameterNames, "", "") + "">""); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ return new LookupElement[0]; // do not offer the user any choices -+ } -+ } -+ -+ /** -+ * A JetNameValidator that always succeeds. -+ */ -+ private static class DummyJetNameValidator implements JetNameValidator { -+ private final Project project; -+ -+ public DummyJetNameValidator(Project project) { -+ this.project = project; -+ } -+ -+ @Nullable -+ @Override -+ public String validateName(String name) { -+ return name; -+ } -+ -+ @Override -+ public Project getProject() { -+ return project; -+ } -+ } -+ -+ /** -+ * Encapsulates a single type substitution of a JetType by another JetType. -+ */ -+ private static class TypeSubstitution { -+ private final JetType forType; -+ private final JetType byType; -+ -+ private TypeSubstitution(JetType forType, JetType byType) { -+ this.forType = forType; -+ this.byType = byType; -+ } -+ -+ private JetType getForType() { -+ return forType; -+ } -+ -+ private JetType getByType() { -+ return byType; -+ } -+ } -+ -+ private final String methodName; -+ private final TypeOrExpressionThereof ownerType; -+ private final TypeOrExpressionThereof returnType; -+ private final List parameters; -+ -+ private boolean isUnit; -+ private boolean isExtension; -+ private JetFile currentFile; -+ private JetFile containingFile; -+ private Editor currentFileEditor; -+ private Editor containingFileEditor; -+ private BindingContext currentFileContext; -+ private JetClass ownerClass; -+ private ClassDescriptor ownerClassDescriptor; -+ private TypeCandidate selectedReceiverType; -+ private Map typeParameterNameMap; -+ -+ public CreateMethodFromUsageFix(@NotNull PsiElement element, @NotNull TypeOrExpressionThereof ownerType, @NotNull String methodName, -+ @NotNull TypeOrExpressionThereof returnType, @NotNull List parameters) { -+ super(element); -+ this.methodName = methodName; -+ this.ownerType = ownerType; -+ this.returnType = returnType; -+ this.parameters = parameters; -+ } -+ -+ @NotNull -+ @Override -+ public String getText() { -+ return JetBundle.message(""create.method.from.usage"", methodName); -+ } -+ -+ @Override -+ public void invoke(@NotNull final Project project, Editor editor, PsiFile file) throws IncorrectOperationException { -+ assert file != null && file instanceof JetFile; -+ currentFile = (JetFile) file; -+ currentFileEditor = editor; -+ currentFileContext = AnalyzerFacadeWithCache.analyzeFileWithCache(currentFile).getBindingContext(); -+ -+ ownerType.computeTypeCandidates(currentFileContext); -+ TypeCandidate[] ownerTypeCandidates = ownerType.getTypeCandidates(); -+ assert ownerTypeCandidates.length > 0; -+ if (ownerTypeCandidates.length == 1 || ApplicationManager.getApplication().isUnitTestMode()) { -+ selectedReceiverType = ownerTypeCandidates[0]; -+ doInvoke(project); -+ } else { -+ // class selection -+ List options = new ArrayList(); -+ final Map optionToTypeMap = new HashMap(); -+ for (TypeCandidate ownerTypeCandidate : ownerTypeCandidates) { -+ ClassifierDescriptor possibleClassDescriptor = ownerTypeCandidate.getType().getConstructor().getDeclarationDescriptor(); -+ if (possibleClassDescriptor != null) { -+ String className = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(possibleClassDescriptor.getDefaultType()); -+ DeclarationDescriptor namespaceDescriptor = possibleClassDescriptor.getContainingDeclaration(); -+ String namespace = renderDescriptor(namespaceDescriptor, true); -+ String option = className + "" ("" + namespace + "")""; -+ options.add(option); -+ optionToTypeMap.put(option, ownerTypeCandidate); -+ } -+ } -+ -+ final JList list = new JBList(options); -+ PsiElementListCellRenderer renderer = new JetLightClassListCellRenderer(); -+ list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); -+ list.setCellRenderer(renderer); -+ PopupChooserBuilder builder = new PopupChooserBuilder(list); -+ renderer.installSpeedSearch(builder); -+ -+ Runnable runnable = new Runnable() { -+ @Override -+ public void run() { -+ int index = list.getSelectedIndex(); -+ if (index < 0) return; -+ String option = (String) list.getSelectedValue(); -+ selectedReceiverType = optionToTypeMap.get(option); -+ CommandProcessor.getInstance().executeCommand(project, new Runnable() { -+ @Override -+ public void run() { -+ doInvoke(project); -+ } -+ }, getText(), null); -+ } -+ }; -+ -+ builder.setTitle(JetBundle.message(""choose.target.class.or.trait.title"")) -+ .setItemChoosenCallback(runnable) -+ .createPopup() -+ .showInBestPositionFor(currentFileEditor); -+ } -+ } -+ -+ private void doInvoke(@NotNull final Project project) { -+ // gather relevant information -+ ClassifierDescriptor ownerTypeDescriptor = selectedReceiverType.getType().getConstructor().getDeclarationDescriptor(); -+ assert ownerTypeDescriptor != null && ownerTypeDescriptor instanceof ClassDescriptor; -+ ownerClassDescriptor = (ClassDescriptor) ownerTypeDescriptor; -+ JetType receiverType = ownerClassDescriptor.getDefaultType(); -+ PsiElement typeDeclaration = BindingContextUtils.classDescriptorToDeclaration(currentFileContext, ownerClassDescriptor); -+ if (typeDeclaration != null && typeDeclaration instanceof JetClass) { -+ ownerClass = (JetClass) typeDeclaration; -+ isExtension = !ownerClass.isWritable(); -+ } else { -+ isExtension = true; -+ } -+ isUnit = returnType.isType() && isUnit(returnType.getType()); -+ -+ JetScope scope; -+ if (isExtension) { -+ NamespaceDescriptor namespaceDescriptor = currentFileContext.get(BindingContext.FILE_TO_NAMESPACE, currentFile); -+ assert namespaceDescriptor != null; -+ scope = namespaceDescriptor.getMemberScope(); -+ } else { -+ assert ownerClassDescriptor instanceof MutableClassDescriptor; -+ scope = ((MutableClassDescriptor) ownerClassDescriptor).getScopeForMemberResolution(); -+ } -+ -+ // figure out type substitutions for type parameters -+ List classTypeParameters = receiverType.getArguments(); -+ List ownerTypeArguments = selectedReceiverType.getType().getArguments(); -+ assert ownerTypeArguments.size() == classTypeParameters.size(); -+ TypeSubstitution[] substitutions = new TypeSubstitution[classTypeParameters.size()]; -+ for (int i = 0; i < substitutions.length; i++) { -+ substitutions[i] = new TypeSubstitution(ownerTypeArguments.get(i).getType(), classTypeParameters.get(i).getType()); -+ } -+ for (Parameter parameter : parameters) { -+ parameter.getType().computeTypeCandidates(currentFileContext, substitutions, scope); -+ } -+ if (!isUnit) { -+ returnType.computeTypeCandidates(currentFileContext, substitutions, scope); -+ } -+ -+ // now that we have done substitutions, we can throw it away -+ selectedReceiverType = new TypeCandidate(receiverType, scope); -+ -+ // figure out type parameter renames to avoid conflicts -+ typeParameterNameMap = getTypeParameterRenames(scope); -+ for (Parameter parameter : parameters) { -+ parameter.getType().renderTypeCandidates(typeParameterNameMap); -+ } -+ if (!isUnit) { -+ returnType.renderTypeCandidates(typeParameterNameMap); -+ } -+ selectedReceiverType.render(typeParameterNameMap); -+ -+ ApplicationManager.getApplication().runWriteAction(new Runnable() { -+ @Override -+ public void run() { -+ JetNamedFunction func = createFunctionSkeleton(project); -+ buildAndRunTemplate(project, func); -+ } -+ }); -+ } -+ -+ private JetNamedFunction createFunctionSkeleton(@NotNull Project project) { -+ JetNamedFunction func; -+ String[] parameterStrings = new String[parameters.size()]; -+ for (int i = 0; i < parameterStrings.length; i++) { -+ parameterStrings[i] = ""p"" + i + "": Any""; -+ } -+ String parametersString = StringUtil.join(parameterStrings,"", ""); -+ String returnTypeString = isUnit ? """" : "": Any""; -+ if (isExtension) { // create as extension function -+ String ownerTypeString = selectedReceiverType.getRenderedType(); -+ String methodText = String.format(""fun %s.%s(%s)%s { }"", ownerTypeString, methodName, parametersString, returnTypeString); -+ func = JetPsiFactory.createFunction(project, methodText); -+ containingFile = currentFile; -+ containingFileEditor = currentFileEditor; -+ func = (JetNamedFunction) currentFile.add(func); -+ } else { // create as method -+ String methodText = String.format(""fun %s(%s)%s { }"", methodName, parametersString, returnTypeString); -+ func = JetPsiFactory.createFunction(project, methodText); -+ PsiFile classContainingFile = ownerClass.getContainingFile(); -+ assert classContainingFile instanceof JetFile; -+ containingFile = (JetFile) classContainingFile; -+ -+ VirtualFile virtualFile = containingFile.getVirtualFile(); -+ assert virtualFile != null; -+ FileEditorManager fileEditorManager = FileEditorManager.getInstance(project); -+ fileEditorManager.openFile(virtualFile, true); -+ containingFileEditor = fileEditorManager.getSelectedTextEditor(); -+ -+ JetClassBody classBody = ownerClass.getBody(); -+ if (classBody == null) { -+ classBody = (JetClassBody) ownerClass.add(JetPsiFactory.createEmptyClassBody(project)); -+ ownerClass.addBefore(JetPsiFactory.createWhiteSpace(project), classBody); -+ } -+ PsiElement rBrace = classBody.getRBrace(); -+ assert rBrace != null; -+ func = (JetNamedFunction) classBody.addBefore(func, rBrace); -+ } -+ -+ return func; -+ } -+ -+ private void buildAndRunTemplate(@NotNull final Project project, @NotNull JetNamedFunction func) { -+ JetParameterList parameterList = func.getValueParameterList(); -+ assert parameterList != null; -+ -+ // build templates -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(containingFileEditor.getDocument()); -+ -+ CaretModel caretModel = containingFileEditor.getCaretModel(); -+ caretModel.moveToOffset(containingFile.getNode().getStartOffset()); -+ -+ TemplateBuilderImpl builder = new TemplateBuilderImpl(containingFile); -+ final TypeExpression returnTypeExpression = isUnit ? null : setupReturnTypeTemplate(builder, func); -+ final TypeExpression[] parameterTypeExpressions = setupParameterTypeTemplates(project, builder, parameterList); -+ -+ // add a segment for the parameter list -+ // Note: because TemplateBuilderImpl does not have a replaceElement overload that takes in both a TextRange and alwaysStopAt, we -+ // need to create the segment first and then hack the Expression into the template later. We use this template to update the type -+ // parameter list as the user makes selections in the parameter types, and we need alwaysStopAt to be false so the user can't tab to -+ // it. -+ TypeParameterListExpression expression = setupTypeParameterListTemplate(builder, func); -+ -+ // the template built by TemplateBuilderImpl is ordered by element position, but we want types to be first, so hack it -+ final TemplateImpl template = (TemplateImpl) builder.buildInlineTemplate(); -+ ArrayList variables = template.getVariables(); -+ for (int i = 0; i < parameters.size(); i++) { -+ Collections.swap(variables, i * 2, i * 2 + 1); -+ } -+ -+ // fix up the template to include the expression for the type parameter list -+ variables.add(new Variable(TYPE_PARAMETER_LIST_VARIABLE_NAME, expression, expression, false, true)); -+ -+ // run the template -+ TemplateManager.getInstance(project).startTemplate(containingFileEditor, template, new TemplateEditingAdapter() { -+ @Override -+ public void templateFinished(Template _, boolean brokenOff) { -+ // file templates -+ int offset = template.getSegmentOffset(0); -+ final JetNamedFunction func = PsiTreeUtil.findElementOfClassAtOffset(containingFile, offset, JetNamedFunction.class, false); -+ assert func != null; -+ final List typeRefsToShorten = new ArrayList(); -+ -+ ApplicationManager.getApplication().runWriteAction(new Runnable() { -+ @Override -+ public void run() { -+ // file templates -+ setupFunctionBody(project, func); -+ -+ // change short type names to fully qualified ones (to be shortened below) -+ setupTypeReferencesForShortening(project, func, typeRefsToShorten, parameterTypeExpressions, returnTypeExpression); -+ } -+ }); -+ -+ ReferenceToClassesShortening.compactReferenceToClasses(typeRefsToShorten); -+ } -+ }); -+ } -+ -+ private Map getTypeParameterRenames(JetScope scope) { -+ TypeParameterDescriptor[] receiverTypeParametersNotInScope = selectedReceiverType.getTypeParameters(); -+ Set allTypeParametersNotInScope = new LinkedHashSet(); -+ allTypeParametersNotInScope.addAll(Arrays.asList(receiverTypeParametersNotInScope)); -+ -+ for (Parameter parameter : parameters) { -+ TypeCandidate[] parameterTypeCandidates = parameter.getType().getTypeCandidates(); -+ for (TypeCandidate parameterTypeCandidate : parameterTypeCandidates) { -+ allTypeParametersNotInScope.addAll(Arrays.asList(parameterTypeCandidate.getTypeParameters())); -+ } -+ } -+ -+ if (!isUnit) { -+ TypeCandidate[] returnTypeCandidates = returnType.getTypeCandidates(); -+ for (TypeCandidate returnTypeCandidate : returnTypeCandidates) { -+ allTypeParametersNotInScope.addAll(Arrays.asList(returnTypeCandidate.getTypeParameters())); -+ } -+ } -+ -+ List typeParameters = new ArrayList(allTypeParametersNotInScope); -+ List typeParameterNames = new ArrayList(); -+ for (TypeParameterDescriptor typeParameter : typeParameters) { -+ typeParameterNames.add(getNextAvailableName(typeParameter.getName().getName(), typeParameterNames, scope)); -+ } -+ assert typeParameters.size() == typeParameterNames.size(); -+ Map typeParameterNameMap = new HashMap(); -+ for (int i = 0; i < typeParameters.size(); i++) { -+ typeParameterNameMap.put(typeParameters.get(i), typeParameterNames.get(i)); -+ } -+ -+ return typeParameterNameMap; -+ } -+ -+ private void setupTypeReferencesForShortening( -+ @NotNull Project project, -+ @NotNull JetNamedFunction func, -+ @NotNull List typeRefsToShorten, -+ @NotNull TypeExpression[] parameterTypeExpressions, -+ @Nullable TypeExpression returnTypeExpression -+ ) { -+ if (isExtension) { -+ JetTypeReference receiverTypeRef = -+ JetPsiFactory.createType(project, renderTypeLong(selectedReceiverType.getType(), typeParameterNameMap)); -+ replaceWithLongerName(project, receiverTypeRef, selectedReceiverType.getType()); -+ -+ receiverTypeRef = func.getReceiverTypeRef(); -+ if (receiverTypeRef != null) { -+ typeRefsToShorten.add(receiverTypeRef); -+ } -+ } -+ -+ if (!isUnit) { -+ assert returnTypeExpression != null; -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ if (returnTypeRef != null) { -+ JetType returnType = returnTypeExpression.getTypeFromSelection(returnTypeRef.getText()); -+ if (returnType != null) { // user selected a given type -+ replaceWithLongerName(project, returnTypeRef, returnType); -+ returnTypeRef = func.getReturnTypeRef(); -+ assert returnTypeRef != null; -+ typeRefsToShorten.add(returnTypeRef); -+ } -+ } -+ } -+ -+ List valueParameters = func.getValueParameters(); -+ List parameterIndicesToShorten = new ArrayList(); -+ assert valueParameters.size() == parameterTypeExpressions.length; -+ for (int i = 0; i < valueParameters.size(); i++) { -+ JetParameter parameter = valueParameters.get(i); -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ JetType parameterType = parameterTypeExpressions[i].getTypeFromSelection(parameterTypeRef.getText()); -+ if (parameterType != null) { -+ replaceWithLongerName(project, parameterTypeRef, parameterType); -+ parameterIndicesToShorten.add(i); -+ } -+ } -+ } -+ valueParameters = func.getValueParameters(); -+ for (int i : parameterIndicesToShorten) { -+ JetTypeReference parameterTypeRef = valueParameters.get(i).getTypeReference(); -+ if (parameterTypeRef != null) { -+ typeRefsToShorten.add(parameterTypeRef); -+ } -+ } -+ } -+ -+ private void setupFunctionBody(@NotNull Project project, @NotNull JetNamedFunction func) { -+ FileTemplate fileTemplate = FileTemplateManager.getInstance().getCodeTemplate(TEMPLATE_FROM_USAGE_METHOD_BODY); -+ Properties properties = new Properties(); -+ if (isUnit) { -+ properties.setProperty(FileTemplate.ATTRIBUTE_RETURN_TYPE, ""Unit""); -+ } else { -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ assert returnTypeRef != null; -+ properties.setProperty(FileTemplate.ATTRIBUTE_RETURN_TYPE, returnTypeRef.getText()); -+ } -+ properties.setProperty(FileTemplate.ATTRIBUTE_CLASS_NAME, DescriptorUtils.getFQName(ownerClassDescriptor).getFqName()); -+ properties.setProperty(FileTemplate.ATTRIBUTE_SIMPLE_CLASS_NAME, ownerClassDescriptor.getName().getName()); -+ properties.setProperty(FileTemplate.ATTRIBUTE_METHOD_NAME, methodName); -+ -+ @NonNls String bodyText; -+ try { -+ bodyText = fileTemplate.getText(properties); -+ } catch (ProcessCanceledException e) { -+ throw e; -+ } catch (Exception e) { -+ throw new IncorrectOperationException(""Failed to parse file template"", e); -+ } -+ JetExpression newBodyExpression = JetPsiFactory.createFunctionBody(project, bodyText); -+ JetExpression oldBodyExpression = func.getBodyExpression(); -+ assert oldBodyExpression != null; -+ oldBodyExpression.replace(newBodyExpression); -+ } -+ -+ @NotNull -+ private TypeExpression setupReturnTypeTemplate(@NotNull TemplateBuilder builder, @NotNull JetNamedFunction func) { -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ assert returnTypeRef != null; -+ TypeExpression returnTypeExpression = new TypeExpression(returnType); -+ builder.replaceElement(returnTypeRef, returnTypeExpression); -+ return returnTypeExpression; -+ } -+ -+ @NotNull -+ private TypeParameterListExpression setupTypeParameterListTemplate(@NotNull TemplateBuilderImpl builder, @NotNull JetNamedFunction func) { -+ Map typeParameterMap = new HashMap(); -+ String[] receiverTypeParameterNames = selectedReceiverType.getTypeParameterNames(); -+ -+ for (Parameter parameter : parameters) { -+ TypeCandidate[] parameterTypeCandidates = parameter.getType().getTypeCandidates(); -+ for (TypeCandidate parameterTypeCandidate : parameterTypeCandidates) { -+ typeParameterMap.put(parameterTypeCandidate.getRenderedType(), parameterTypeCandidate.getTypeParameterNames()); -+ } -+ } -+ -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ if (returnTypeRef != null) { -+ TypeCandidate[] returnTypeCandidates = returnType.getTypeCandidates(); -+ for (TypeCandidate returnTypeCandidate : returnTypeCandidates) { -+ typeParameterMap.put(returnTypeCandidate.getRenderedType(), returnTypeCandidate.getTypeParameterNames()); -+ } -+ } -+ -+ builder.replaceElement(func, TextRange.create(3, 3), TYPE_PARAMETER_LIST_VARIABLE_NAME, null, false); // ((3, 3) is after ""fun"") -+ return new TypeParameterListExpression(receiverTypeParameterNames, typeParameterMap); -+ } -+ -+ private TypeExpression[] setupParameterTypeTemplates(@NotNull Project project, @NotNull TemplateBuilder builder, -+ @NotNull JetParameterList parameterList) { -+ List jetParameters = parameterList.getParameters(); -+ assert jetParameters.size() == parameters.size(); -+ TypeExpression[] parameterTypeExpressions = new TypeExpression[parameters.size()]; -+ JetNameValidator dummyValidator = new DummyJetNameValidator(project); -+ for (int i = 0; i < parameters.size(); i++) { -+ Parameter parameter = parameters.get(i); -+ JetParameter jetParameter = jetParameters.get(i); -+ -+ // add parameter type to the template -+ parameterTypeExpressions[i] = new TypeExpression(parameter.getType()); -+ JetTypeReference parameterTypeRef = jetParameter.getTypeReference(); -+ assert parameterTypeRef != null; -+ builder.replaceElement(parameterTypeRef, parameterTypeExpressions[i]); -+ -+ // add parameter name to the template -+ String[] possibleNamesFromExpression = parameter.getType().getPossibleNamesFromExpression(); -+ String preferredName = parameter.getPreferredName(); -+ String[] possibleNames; -+ if (preferredName != null) { -+ possibleNames = new String[possibleNamesFromExpression.length + 1]; -+ possibleNames[0] = preferredName; -+ System.arraycopy(possibleNamesFromExpression, 0, possibleNames, 1, possibleNamesFromExpression.length); -+ } else { -+ possibleNames = possibleNamesFromExpression; -+ } -+ -+ // figure out suggested names for each type option -+ Map parameterTypeToNamesMap = new HashMap(); -+ for (TypeCandidate typeCandidate : parameter.getType().getTypeCandidates()) { -+ String[] suggestedNames = JetNameSuggester.suggestNamesForType(typeCandidate.getType(), dummyValidator); -+ parameterTypeToNamesMap.put(typeCandidate.getRenderedType(), suggestedNames); -+ } -+ -+ // add expression to builder -+ Expression parameterNameExpression = new ParameterNameExpression(possibleNames, parameterTypeToNamesMap); -+ PsiElement parameterNameIdentifier = jetParameter.getNameIdentifier(); -+ assert parameterNameIdentifier != null; -+ builder.replaceElement(parameterNameIdentifier, parameterNameExpression); -+ } -+ return parameterTypeExpressions; -+ } -+ -+ private void replaceWithLongerName(@NotNull Project project, @NotNull JetTypeReference typeRef, @NotNull JetType type) { -+ JetTypeReference fullyQualifiedReceiverTypeRef = JetPsiFactory.createType(project, renderTypeLong(type, typeParameterNameMap)); -+ typeRef.replace(fullyQualifiedReceiverTypeRef); -+ } -+ -+ @NotNull -+ private static JetType substituteType(@NotNull JetType type, @NotNull TypeSubstitution substitution, @NotNull Variance variance) { -+ switch (variance) { -+ case INVARIANT: -+ // for invariant, can replace only when they're equal -+ if (type.equals(substitution.getForType())) { -+ return substitution.getByType(); -+ } -+ break; -+ case IN_VARIANCE: -+ // for covariant (e.g. function parameter), can replace type with any of its supertypes -+ if (JetTypeChecker.INSTANCE.isSubtypeOf(type, substitution.getForType())) { -+ return substitution.getByType(); -+ } -+ break; -+ case OUT_VARIANCE: -+ // for contravariant (e.g. function return value), can replace type with any of its subtypes -+ if (JetTypeChecker.INSTANCE.isSubtypeOf(substitution.getForType(), type)) { -+ return substitution.getByType(); -+ } -+ break; -+ } -+ -+ List newArguments = new ArrayList(); -+ List typeParameters = type.getConstructor().getParameters(); -+ int i = 0; -+ for (TypeProjection projection : type.getArguments()) { -+ TypeParameterDescriptor typeParameter = typeParameters.get(i); -+ JetType newArgument = substituteType(projection.getType(), substitution, typeParameter.getVariance()); -+ newArguments.add(new TypeProjection(Variance.INVARIANT, newArgument)); -+ i++; -+ } -+ return new JetTypeImpl(type.getAnnotations(), type.getConstructor(), -+ type.isNullable(), newArguments, type.getMemberScope()); -+ } -+ -+ private static boolean containsType(JetType outer, JetType inner) { -+ if (outer.equals(inner)) { -+ return true; -+ } -+ -+ for (TypeProjection projection : outer.getArguments()) { -+ if (containsType(projection.getType(), inner)) { -+ return true; -+ } -+ } -+ -+ return false; -+ } -+ -+ @NotNull -+ private static String renderDescriptor( -+ @NotNull DeclarationDescriptor declarationDescriptor, -+ @NotNull Map typeParameterNameMap, -+ boolean fq -+ ) { -+ if (declarationDescriptor instanceof TypeParameterDescriptor) { -+ String replacement = typeParameterNameMap.get(declarationDescriptor); -+ return replacement == null ? declarationDescriptor.getName().getName() : replacement; -+ } else { -+ return fq ? DescriptorUtils.getFQName(declarationDescriptor).getFqName() : declarationDescriptor.getName().getName(); -+ } -+ } -+ -+ @NotNull -+ private static String renderDescriptor(@NotNull DeclarationDescriptor declarationDescriptor, boolean fq) { -+ return renderDescriptor(declarationDescriptor, Collections.emptyMap(), fq); -+ } -+ -+ private static String renderType(@NotNull JetType type, @NotNull Map typeParameterNameMap, boolean fq) { -+ List projections = type.getArguments(); -+ DeclarationDescriptor declarationDescriptor = type.getConstructor().getDeclarationDescriptor(); -+ assert declarationDescriptor != null; -+ if (projections.isEmpty()) { -+ return renderDescriptor(declarationDescriptor, typeParameterNameMap, fq); -+ } -+ -+ List arguments = new ArrayList(); -+ for (TypeProjection projection : projections) { -+ arguments.add(renderType(projection.getType(), typeParameterNameMap, fq)); -+ } -+ return renderDescriptor(declarationDescriptor, typeParameterNameMap, fq) + ""<"" + StringUtil.join(arguments, "", "") + "">""; -+ } -+ -+ @NotNull -+ private static String renderTypeShort(@NotNull JetType type, @NotNull Map typeParameterNameMap) { -+ return renderType(type, typeParameterNameMap, false); -+ } -+ -+ @NotNull -+ private static String renderTypeLong(@NotNull JetType type, @NotNull Map typeParameterNameMap) { -+ return renderType(type, typeParameterNameMap, true); -+ } -+ -+ @NotNull -+ private static TypeParameterDescriptor[] getTypeParameterNamesNotInScope( -+ @NotNull Collection typeParameters, -+ @NotNull JetScope scope -+ ) { -+ List typeParameterNames = new ArrayList(); -+ for (TypeParameterDescriptor typeParameter : typeParameters) { -+ ClassifierDescriptor classifier = scope.getClassifier(typeParameter.getName()); -+ if (classifier == null || !classifier.equals(typeParameter)) { -+ typeParameterNames.add(typeParameter); -+ } -+ } -+ return typeParameterNames.toArray(new TypeParameterDescriptor[typeParameterNames.size()]); -+ } -+ -+ @NotNull -+ private static Set getTypeParametersInType(@NotNull JetType type) { -+ Set typeParameters = new LinkedHashSet(); -+ List arguments = type.getArguments(); -+ if (arguments.isEmpty()) { -+ ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); -+ if (descriptor instanceof TypeParameterDescriptor) { -+ typeParameters.add((TypeParameterDescriptor) descriptor); -+ } -+ } else { -+ for (TypeProjection projection : arguments) { -+ typeParameters.addAll(getTypeParametersInType(projection.getType())); -+ } -+ } -+ return typeParameters; -+ } -+ -+ @NotNull -+ private static String getNextAvailableName(@NotNull String name, @NotNull Collection existingNames) { -+ if (existingNames.contains(name)) { -+ int j = 1; -+ while (existingNames.contains(name + j)) j++; -+ name += j; -+ } -+ return name; -+ } -+ -+ @NotNull -+ private static String getNextAvailableName(@NotNull String name, @NotNull Collection existingNames, @NotNull JetScope scope) { -+ if (existingNames.contains(name) || scope.getClassifier(Name.identifier(name)) != null) { -+ int j = 1; -+ while (existingNames.contains(name + j) || scope.getClassifier(Name.identifier(name + j)) != null) j++; -+ name += j; -+ } -+ return name; -+ } -+ -+ @NotNull -+ private static JetType[] guessTypeForExpression(@NotNull JetExpression expr, @NotNull BindingContext context) { -+ JetType type = context.get(BindingContext.EXPRESSION_TYPE, expr); -+ JetNamedDeclaration declaration = null; -+ -+ // if we know the actual type of the expression -+ if (type != null) { -+ return new JetType[] {type}; -+ } -+ -+ // expression has an expected type -+ else if ((type = context.get(BindingContext.EXPECTED_EXPRESSION_TYPE, expr)) != null) { -+ return new JetType[] {type}; -+ } -+ -+ // expression itself is a type assertion -+ else if (expr instanceof JetTypeConstraint) { // expression itself is a type assertion -+ JetTypeConstraint constraint = (JetTypeConstraint) expr; -+ return new JetType[] {context.get(BindingContext.TYPE, constraint.getBoundTypeReference())}; -+ } -+ -+ // expression is on the left side of a type assertion -+ else if (expr.getParent() instanceof JetTypeConstraint) { -+ JetTypeConstraint constraint = (JetTypeConstraint) expr.getParent(); -+ return new JetType[] {context.get(BindingContext.TYPE, constraint.getBoundTypeReference())}; -+ } -+ -+ // expression is on the lhs of a multi-declaration -+ else if (expr instanceof JetMultiDeclarationEntry) { -+ JetMultiDeclarationEntry entry = (JetMultiDeclarationEntry) expr; -+ JetTypeReference typeRef = entry.getTypeRef(); -+ if (typeRef != null) { // and has a specified type -+ return new JetType[] {context.get(BindingContext.TYPE, typeRef)};","Why not just guess by declaration immediately, without checking `BindingContext.TYPE`? Wouldn't it be enough? -",Why is this needed? Looks like a duplicate file. -111,"@@ -0,0 +1,1391 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.codeInsight.lookup.LookupElement; -+import com.intellij.codeInsight.lookup.LookupElementBuilder; -+import com.intellij.codeInsight.template.*; -+import com.intellij.codeInsight.template.impl.TemplateImpl; -+import com.intellij.codeInsight.template.impl.Variable; -+import com.intellij.ide.fileTemplates.FileTemplate; -+import com.intellij.ide.fileTemplates.FileTemplateManager; -+import com.intellij.ide.util.PsiElementListCellRenderer; -+import com.intellij.openapi.application.ApplicationManager; -+import com.intellij.openapi.command.CommandProcessor; -+import com.intellij.openapi.editor.CaretModel; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.fileEditor.FileEditorManager; -+import com.intellij.openapi.progress.ProcessCanceledException; -+import com.intellij.openapi.project.Project; -+import com.intellij.openapi.ui.popup.PopupChooserBuilder; -+import com.intellij.openapi.util.TextRange; -+import com.intellij.openapi.util.text.StringUtil; -+import com.intellij.openapi.vfs.VirtualFile; -+import com.intellij.psi.PsiDocumentManager; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.PsiReference; -+import com.intellij.psi.search.SearchScope; -+import com.intellij.psi.util.PsiTreeUtil; -+import com.intellij.refactoring.psi.SearchUtils; -+import com.intellij.ui.components.JBList; -+import com.intellij.util.ArrayUtil; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NonNls; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.descriptors.*; -+import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1; -+import org.jetbrains.jet.lang.diagnostics.Errors; -+import org.jetbrains.jet.lang.psi.*; -+import org.jetbrains.jet.lang.resolve.BindingContext; -+import org.jetbrains.jet.lang.resolve.BindingContextUtils; -+import org.jetbrains.jet.lang.resolve.DescriptorUtils; -+import org.jetbrains.jet.lang.resolve.name.Name; -+import org.jetbrains.jet.lang.resolve.scopes.JetScope; -+import org.jetbrains.jet.lang.types.*; -+import org.jetbrains.jet.lang.types.checker.JetTypeChecker; -+import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; -+import org.jetbrains.jet.plugin.JetBundle; -+import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening; -+import org.jetbrains.jet.plugin.presentation.JetLightClassListCellRenderer; -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; -+import org.jetbrains.jet.plugin.refactoring.JetNameSuggester; -+import org.jetbrains.jet.plugin.refactoring.JetNameValidator; -+import org.jetbrains.jet.plugin.references.JetSimpleNameReference; -+import org.jetbrains.jet.renderer.DescriptorRenderer; -+ -+import javax.swing.*; -+import java.util.*; -+import java.util.regex.Matcher; -+import java.util.regex.Pattern; -+ -+public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { -+ private static final String TYPE_PARAMETER_LIST_VARIABLE_NAME = ""typeParameterList""; -+ private static final String TEMPLATE_FROM_USAGE_METHOD_BODY = ""New Kotlin Method Body.kt""; -+ private static final Pattern COMPONENT_FUNCTION_PATTERN = Pattern.compile(""^component(\\d+)$""); -+ -+ /** -+ * Represents a single choice for a type (e.g. parameter type or return type). -+ */ -+ private static class TypeCandidate { -+ private final JetType type; -+ private final TypeParameterDescriptor[] typeParameters; -+ private String renderedType; -+ private String[] typeParameterNames; -+ -+ public TypeCandidate(@NotNull JetType type) { -+ this.type = type; -+ Set typeParametersInType = getTypeParametersInType(type); -+ typeParameters = typeParametersInType.toArray(new TypeParameterDescriptor[typeParametersInType.size()]); -+ renderedType = renderTypeShort(type, Collections.emptyMap()); -+ } -+ -+ public TypeCandidate(@NotNull JetType type, @NotNull JetScope scope) { -+ this.type = type; -+ typeParameters = getTypeParameterNamesNotInScope(getTypeParametersInType(type), scope); -+ } -+ -+ public void render(@NotNull Map typeParameterNameMap) { -+ renderedType = renderTypeShort(type, typeParameterNameMap); -+ typeParameterNames = new String[typeParameters.length]; -+ int i = 0; -+ for (TypeParameterDescriptor typeParameter : typeParameters) { -+ typeParameterNames[i] = typeParameterNameMap.get(typeParameter); -+ i++; -+ } -+ } -+ -+ @NotNull JetType getType() { -+ return type; -+ } -+ -+ @NotNull -+ public String getRenderedType() { -+ assert renderedType != null : ""call render() first""; -+ return renderedType; -+ } -+ -+ @NotNull -+ public String[] getTypeParameterNames() { -+ assert typeParameterNames != null : ""call render() first""; -+ return typeParameterNames; -+ } -+ -+ @NotNull -+ public TypeParameterDescriptor[] getTypeParameters() { -+ return typeParameters; -+ } -+ } -+ -+ /** -+ * Represents a concrete type or a set of types yet to be inferred from an expression. -+ */ -+ private static class TypeOrExpressionThereof { -+ private final JetExpression expressionOfType; -+ private final JetType type; -+ private final Variance variance; -+ private TypeCandidate[] typeCandidates; -+ private String[] cachedNameCandidatesFromExpression; -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType) { -+ this(expressionOfType, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType, Variance variance) { -+ this(expressionOfType, null, variance); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type) { -+ this(type, Variance.IN_VARIANCE); -+ } -+ -+ public TypeOrExpressionThereof(@NotNull JetType type, Variance variance) { -+ this(null, type, variance); -+ } -+ -+ private TypeOrExpressionThereof(@Nullable JetExpression expressionOfType, @Nullable JetType type, Variance variance) { -+ this.expressionOfType = expressionOfType; -+ this.type = type; -+ this.variance = variance; -+ } -+ -+ public boolean isType() { -+ return this.type != null; -+ } -+ -+ @NotNull -+ public JetType getType() { -+ assert this.type != null; -+ return this.type; -+ } -+ -+ @NotNull -+ private List getPossibleTypes(BindingContext context) { -+ List types = new ArrayList(); -+ if (isType()) { -+ assert type != null : ""!isType() means type == null && expressionOfType != null""; -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ for (JetType type : guessTypeForExpression(expressionOfType, context)) { -+ types.add(type); -+ if (variance == Variance.IN_VARIANCE) { -+ types.addAll(TypeUtils.getAllSupertypes(type)); -+ } -+ } -+ } -+ return types; -+ } -+ -+ public void computeTypeCandidates(@NotNull BindingContext context) { -+ Collection types = getPossibleTypes(context); -+ -+ typeCandidates = new TypeCandidate[types.size()]; -+ int i = 0; -+ for (JetType type : types) { -+ typeCandidates[i] = new TypeCandidate(type); -+ i++; -+ } -+ } -+ -+ public void computeTypeCandidates( -+ @NotNull BindingContext context, -+ @NotNull TypeSubstitution[] substitutions, -+ @NotNull JetScope scope -+ ) { -+ List types = getPossibleTypes(context); -+ Collections.reverse(types); // reverse and reverse back later, so that things added below are added at the front -+ -+ Set newTypes = new LinkedHashSet(types); -+ for (TypeSubstitution substitution : substitutions) { // each substitution can be applied or not, so we offer all options -+ List toAdd = new ArrayList(); -+ List toRemove = new ArrayList(); -+ for (JetType type : newTypes) { -+ toAdd.add(substituteType(type, substitution, variance)); -+ // substitution.byType are type arguments, but they cannot already occur in the type before substitution -+ if (containsType(type, substitution.getByType())) { -+ toRemove.add(type); -+ } -+ } -+ newTypes.addAll(toAdd); -+ newTypes.removeAll(toRemove); -+ } -+ -+ if (newTypes.isEmpty()) { -+ newTypes.add(KotlinBuiltIns.getInstance().getAnyType()); -+ } -+ -+ typeCandidates = new TypeCandidate[newTypes.size()]; -+ int i = typeCandidates.length - 1; // reverse order (see explanation above) -+ for (JetType type : newTypes) { -+ typeCandidates[i] = new TypeCandidate(type, scope); -+ i--; -+ } -+ } -+ -+ @NotNull -+ public TypeCandidate[] getTypeCandidates() { -+ assert typeCandidates != null : ""call computeTypeCandidates() first""; -+ return typeCandidates; -+ } -+ -+ public void renderTypeCandidates(@NotNull Map typeParameterNameMap) { -+ for (TypeCandidate candidate : typeCandidates) { -+ candidate.render(typeParameterNameMap); -+ } -+ } -+ -+ @NotNull -+ public String[] getPossibleNamesFromExpression() { -+ if (cachedNameCandidatesFromExpression != null) return cachedNameCandidatesFromExpression; -+ if (isType()) { -+ cachedNameCandidatesFromExpression = ArrayUtil.EMPTY_STRING_ARRAY; -+ } else { -+ assert expressionOfType != null : ""!isType() means type == null && expressionOfType != null""; -+ JetNameValidator dummyValidator = new DummyJetNameValidator(expressionOfType.getProject()); -+ cachedNameCandidatesFromExpression = JetNameSuggester.suggestNamesForExpression(expressionOfType, dummyValidator); -+ } -+ return cachedNameCandidatesFromExpression; -+ } -+ } -+ -+ /** -+ * Encapsulates information about a method parameter that is going to be created. -+ */ -+ private static class Parameter { -+ private final String preferredName; -+ private final TypeOrExpressionThereof type; -+ -+ public Parameter(@Nullable(""no preferred name"") String preferredName, TypeOrExpressionThereof type) { -+ this.preferredName = preferredName; -+ this.type = type; -+ } -+ -+ public String getPreferredName() { -+ return preferredName; -+ } -+ -+ public TypeOrExpressionThereof getType() { -+ return type; -+ } -+ } -+ -+ /** -+ * Special Expression for parameter names based on its type. -+ */ -+ private static class ParameterNameExpression extends Expression { -+ private final String[] names; -+ private final Map parameterTypeToNamesMap; -+ -+ public ParameterNameExpression(@NotNull String[] names, @NotNull Map parameterTypeToNamesMap) { -+ for (String name : names) { -+ assert name != null && !name.isEmpty(); -+ } -+ this.names = names; -+ this.parameterTypeToNamesMap = parameterTypeToNamesMap; -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ LookupElement[] lookupItems = calculateLookupItems(context); -+ if (lookupItems.length == 0) return new TextResult(""""); -+ -+ return new TextResult(lookupItems[0].getLookupString()); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ Set names = new LinkedHashSet(); -+ Collections.addAll(names, this.names); -+ -+ // find the parameter list -+ Project project = context.getProject(); -+ int offset = context.getStartOffset(); -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ Editor editor = context.getEditor(); -+ assert editor != null; -+ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); -+ assert file != null && file instanceof JetFile; -+ PsiElement elementAt = file.findElementAt(offset); -+ JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); -+ if (func == null) return new LookupElement[0]; -+ JetParameterList parameterList = func.getValueParameterList(); -+ assert parameterList != null; -+ -+ // add names based on selected type -+ JetParameter parameter = PsiTreeUtil.getParentOfType(elementAt, JetParameter.class); -+ if (parameter != null) { -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ String[] suggestedNamesBasedOnType = parameterTypeToNamesMap.get(parameterTypeRef.getText()); -+ if (suggestedNamesBasedOnType != null) { -+ Collections.addAll(names, suggestedNamesBasedOnType); -+ } -+ } -+ } -+ -+ // remember other parameter names for later use -+ Set parameterNames = new HashSet(); -+ for (JetParameter jetParameter : parameterList.getParameters()) { -+ if (jetParameter == parameter || jetParameter.getName() == null) continue; -+ parameterNames.add(jetParameter.getName()); -+ } -+ -+ // add fallback parameter name -+ if (names.isEmpty()) { -+ names.add(""arg""); -+ } -+ -+ // ensure there are no conflicts -+ List lookupElements = new ArrayList(); -+ for (String name : names) { -+ name = getNextAvailableName(name, parameterNames); -+ lookupElements.add(LookupElementBuilder.create(name)); -+ } -+ -+ // create and return -+ return lookupElements.toArray(new LookupElement[lookupElements.size()]); -+ } -+ } -+ -+ /** -+ * An Expression for type references. -+ */ -+ private static class TypeExpression extends Expression { -+ private final TypeOrExpressionThereof type; -+ private @NotNull LookupElement[] cachedLookupElements; -+ -+ public TypeExpression(@NotNull TypeOrExpressionThereof type) { -+ this.type = type; -+ TypeCandidate[] candidates = type.getTypeCandidates(); -+ cachedLookupElements = new LookupElement[candidates.length]; -+ for (int i = 0; i < candidates.length; i++) { -+ cachedLookupElements[i] = LookupElementBuilder.create(candidates[i], candidates[i].getRenderedType()); -+ } -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ LookupElement[] lookupItems = calculateLookupItems(context); -+ if (lookupItems.length == 0) return new TextResult(""""); -+ -+ return new TextResult(lookupItems[0].getLookupString()); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ return cachedLookupElements; -+ } -+ -+ @NotNull -+ public TypeOrExpressionThereof getType() { -+ return type; -+ } -+ -+ @Nullable(""can't be found"") -+ public JetType getTypeFromSelection(@NotNull String selection) { -+ TypeCandidate[] options = type.getTypeCandidates(); -+ for (TypeCandidate option : options) { -+ if (option.getRenderedType().equals(selection)) { -+ return option.getType(); -+ } -+ } -+ return null; -+ } -+ } -+ -+ /** -+ * A sort-of dummy Expression for parameter lists, to allow us to update the parameter list as the user makes selections. -+ */ -+ private static class TypeParameterListExpression extends Expression { -+ private final String[] typeParameterNamesFromReceiverType; -+ private final Map parameterTypeToTypeParameterNamesMap; -+ -+ public TypeParameterListExpression( -+ @NotNull String[] typeParameterNamesFromReceiverType, -+ @NotNull Map typeParametersMap -+ ) { -+ this.typeParameterNamesFromReceiverType = typeParameterNamesFromReceiverType; -+ this.parameterTypeToTypeParameterNamesMap = typeParametersMap; -+ } -+ -+ @NotNull -+ @Override -+ public Result calculateResult(ExpressionContext context) { -+ Project project = context.getProject(); -+ int offset = context.getStartOffset(); -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ Editor editor = context.getEditor(); -+ assert editor != null; -+ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); -+ assert file != null && file instanceof JetFile; -+ PsiElement elementAt = file.findElementAt(offset); -+ JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); -+ if (func == null) { -+ return new TextResult(""""); -+ } -+ List parameters = func.getValueParameters(); -+ -+ Set typeParameterNames = new LinkedHashSet(); -+ Collections.addAll(typeParameterNames, typeParameterNamesFromReceiverType); -+ for (JetParameter parameter : parameters) { -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ String[] typeParameterNamesFromParameter = parameterTypeToTypeParameterNamesMap.get(parameterTypeRef.getText()); -+ if (typeParameterNamesFromParameter != null) { -+ Collections.addAll(typeParameterNames, typeParameterNamesFromParameter); -+ } -+ } -+ } -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ if (returnTypeRef != null) { -+ String[] typeParameterNamesFromReturnType = parameterTypeToTypeParameterNamesMap.get(returnTypeRef.getText()); -+ if (typeParameterNamesFromReturnType != null) { -+ Collections.addAll(typeParameterNames, typeParameterNamesFromReturnType); -+ } -+ } -+ -+ return typeParameterNames.isEmpty() -+ ? new TextResult("""") -+ : new TextResult("" <"" + StringUtil.join(typeParameterNames, "", "") + "">""); -+ } -+ -+ @Nullable -+ @Override -+ public Result calculateQuickResult(ExpressionContext context) { -+ return calculateResult(context); -+ } -+ -+ @NotNull -+ @Override -+ public LookupElement[] calculateLookupItems(ExpressionContext context) { -+ return new LookupElement[0]; // do not offer the user any choices -+ } -+ } -+ -+ /** -+ * A JetNameValidator that always succeeds. -+ */ -+ private static class DummyJetNameValidator implements JetNameValidator { -+ private final Project project; -+ -+ public DummyJetNameValidator(Project project) { -+ this.project = project; -+ } -+ -+ @Nullable -+ @Override -+ public String validateName(String name) { -+ return name; -+ } -+ -+ @Override -+ public Project getProject() { -+ return project; -+ } -+ } -+ -+ /** -+ * Encapsulates a single type substitution of a JetType by another JetType. -+ */ -+ private static class TypeSubstitution { -+ private final JetType forType; -+ private final JetType byType; -+ -+ private TypeSubstitution(JetType forType, JetType byType) { -+ this.forType = forType; -+ this.byType = byType; -+ } -+ -+ private JetType getForType() { -+ return forType; -+ } -+ -+ private JetType getByType() { -+ return byType; -+ } -+ } -+ -+ private final String methodName; -+ private final TypeOrExpressionThereof ownerType; -+ private final TypeOrExpressionThereof returnType; -+ private final List parameters; -+ -+ private boolean isUnit; -+ private boolean isExtension; -+ private JetFile currentFile; -+ private JetFile containingFile; -+ private Editor currentFileEditor; -+ private Editor containingFileEditor; -+ private BindingContext currentFileContext; -+ private JetClass ownerClass; -+ private ClassDescriptor ownerClassDescriptor; -+ private TypeCandidate selectedReceiverType; -+ private Map typeParameterNameMap; -+ -+ public CreateMethodFromUsageFix(@NotNull PsiElement element, @NotNull TypeOrExpressionThereof ownerType, @NotNull String methodName, -+ @NotNull TypeOrExpressionThereof returnType, @NotNull List parameters) { -+ super(element); -+ this.methodName = methodName; -+ this.ownerType = ownerType; -+ this.returnType = returnType; -+ this.parameters = parameters; -+ } -+ -+ @NotNull -+ @Override -+ public String getText() { -+ return JetBundle.message(""create.method.from.usage"", methodName); -+ } -+ -+ @Override -+ public void invoke(@NotNull final Project project, Editor editor, PsiFile file) throws IncorrectOperationException { -+ assert file != null && file instanceof JetFile; -+ currentFile = (JetFile) file; -+ currentFileEditor = editor; -+ currentFileContext = AnalyzerFacadeWithCache.analyzeFileWithCache(currentFile).getBindingContext(); -+ -+ ownerType.computeTypeCandidates(currentFileContext); -+ TypeCandidate[] ownerTypeCandidates = ownerType.getTypeCandidates(); -+ assert ownerTypeCandidates.length > 0; -+ if (ownerTypeCandidates.length == 1 || ApplicationManager.getApplication().isUnitTestMode()) { -+ selectedReceiverType = ownerTypeCandidates[0]; -+ doInvoke(project); -+ } else { -+ // class selection -+ List options = new ArrayList(); -+ final Map optionToTypeMap = new HashMap(); -+ for (TypeCandidate ownerTypeCandidate : ownerTypeCandidates) { -+ ClassifierDescriptor possibleClassDescriptor = ownerTypeCandidate.getType().getConstructor().getDeclarationDescriptor(); -+ if (possibleClassDescriptor != null) { -+ String className = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(possibleClassDescriptor.getDefaultType()); -+ DeclarationDescriptor namespaceDescriptor = possibleClassDescriptor.getContainingDeclaration(); -+ String namespace = renderDescriptor(namespaceDescriptor, true); -+ String option = className + "" ("" + namespace + "")""; -+ options.add(option); -+ optionToTypeMap.put(option, ownerTypeCandidate); -+ } -+ } -+ -+ final JList list = new JBList(options); -+ PsiElementListCellRenderer renderer = new JetLightClassListCellRenderer(); -+ list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); -+ list.setCellRenderer(renderer); -+ PopupChooserBuilder builder = new PopupChooserBuilder(list); -+ renderer.installSpeedSearch(builder); -+ -+ Runnable runnable = new Runnable() { -+ @Override -+ public void run() { -+ int index = list.getSelectedIndex(); -+ if (index < 0) return; -+ String option = (String) list.getSelectedValue(); -+ selectedReceiverType = optionToTypeMap.get(option); -+ CommandProcessor.getInstance().executeCommand(project, new Runnable() { -+ @Override -+ public void run() { -+ doInvoke(project); -+ } -+ }, getText(), null); -+ } -+ }; -+ -+ builder.setTitle(JetBundle.message(""choose.target.class.or.trait.title"")) -+ .setItemChoosenCallback(runnable) -+ .createPopup() -+ .showInBestPositionFor(currentFileEditor); -+ } -+ } -+ -+ private void doInvoke(@NotNull final Project project) { -+ // gather relevant information -+ ClassifierDescriptor ownerTypeDescriptor = selectedReceiverType.getType().getConstructor().getDeclarationDescriptor(); -+ assert ownerTypeDescriptor != null && ownerTypeDescriptor instanceof ClassDescriptor; -+ ownerClassDescriptor = (ClassDescriptor) ownerTypeDescriptor; -+ JetType receiverType = ownerClassDescriptor.getDefaultType(); -+ PsiElement typeDeclaration = BindingContextUtils.classDescriptorToDeclaration(currentFileContext, ownerClassDescriptor); -+ if (typeDeclaration != null && typeDeclaration instanceof JetClass) { -+ ownerClass = (JetClass) typeDeclaration; -+ isExtension = !ownerClass.isWritable(); -+ } else { -+ isExtension = true; -+ } -+ isUnit = returnType.isType() && isUnit(returnType.getType()); -+ -+ JetScope scope; -+ if (isExtension) { -+ NamespaceDescriptor namespaceDescriptor = currentFileContext.get(BindingContext.FILE_TO_NAMESPACE, currentFile); -+ assert namespaceDescriptor != null; -+ scope = namespaceDescriptor.getMemberScope(); -+ } else { -+ assert ownerClassDescriptor instanceof MutableClassDescriptor; -+ scope = ((MutableClassDescriptor) ownerClassDescriptor).getScopeForMemberResolution(); -+ } -+ -+ // figure out type substitutions for type parameters -+ List classTypeParameters = receiverType.getArguments(); -+ List ownerTypeArguments = selectedReceiverType.getType().getArguments(); -+ assert ownerTypeArguments.size() == classTypeParameters.size(); -+ TypeSubstitution[] substitutions = new TypeSubstitution[classTypeParameters.size()]; -+ for (int i = 0; i < substitutions.length; i++) { -+ substitutions[i] = new TypeSubstitution(ownerTypeArguments.get(i).getType(), classTypeParameters.get(i).getType()); -+ } -+ for (Parameter parameter : parameters) { -+ parameter.getType().computeTypeCandidates(currentFileContext, substitutions, scope); -+ } -+ if (!isUnit) { -+ returnType.computeTypeCandidates(currentFileContext, substitutions, scope); -+ } -+ -+ // now that we have done substitutions, we can throw it away -+ selectedReceiverType = new TypeCandidate(receiverType, scope); -+ -+ // figure out type parameter renames to avoid conflicts -+ typeParameterNameMap = getTypeParameterRenames(scope); -+ for (Parameter parameter : parameters) { -+ parameter.getType().renderTypeCandidates(typeParameterNameMap); -+ } -+ if (!isUnit) { -+ returnType.renderTypeCandidates(typeParameterNameMap); -+ } -+ selectedReceiverType.render(typeParameterNameMap); -+ -+ ApplicationManager.getApplication().runWriteAction(new Runnable() { -+ @Override -+ public void run() { -+ JetNamedFunction func = createFunctionSkeleton(project); -+ buildAndRunTemplate(project, func); -+ } -+ }); -+ } -+ -+ private JetNamedFunction createFunctionSkeleton(@NotNull Project project) { -+ JetNamedFunction func; -+ String[] parameterStrings = new String[parameters.size()]; -+ for (int i = 0; i < parameterStrings.length; i++) { -+ parameterStrings[i] = ""p"" + i + "": Any""; -+ } -+ String parametersString = StringUtil.join(parameterStrings,"", ""); -+ String returnTypeString = isUnit ? """" : "": Any""; -+ if (isExtension) { // create as extension function -+ String ownerTypeString = selectedReceiverType.getRenderedType(); -+ String methodText = String.format(""fun %s.%s(%s)%s { }"", ownerTypeString, methodName, parametersString, returnTypeString); -+ func = JetPsiFactory.createFunction(project, methodText); -+ containingFile = currentFile; -+ containingFileEditor = currentFileEditor; -+ func = (JetNamedFunction) currentFile.add(func); -+ } else { // create as method -+ String methodText = String.format(""fun %s(%s)%s { }"", methodName, parametersString, returnTypeString); -+ func = JetPsiFactory.createFunction(project, methodText); -+ PsiFile classContainingFile = ownerClass.getContainingFile(); -+ assert classContainingFile instanceof JetFile; -+ containingFile = (JetFile) classContainingFile; -+ -+ VirtualFile virtualFile = containingFile.getVirtualFile(); -+ assert virtualFile != null; -+ FileEditorManager fileEditorManager = FileEditorManager.getInstance(project); -+ fileEditorManager.openFile(virtualFile, true); -+ containingFileEditor = fileEditorManager.getSelectedTextEditor(); -+ -+ JetClassBody classBody = ownerClass.getBody(); -+ if (classBody == null) { -+ classBody = (JetClassBody) ownerClass.add(JetPsiFactory.createEmptyClassBody(project)); -+ ownerClass.addBefore(JetPsiFactory.createWhiteSpace(project), classBody); -+ } -+ PsiElement rBrace = classBody.getRBrace(); -+ assert rBrace != null; -+ func = (JetNamedFunction) classBody.addBefore(func, rBrace); -+ } -+ -+ return func; -+ } -+ -+ private void buildAndRunTemplate(@NotNull final Project project, @NotNull JetNamedFunction func) { -+ JetParameterList parameterList = func.getValueParameterList(); -+ assert parameterList != null; -+ -+ // build templates -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(containingFileEditor.getDocument()); -+ -+ CaretModel caretModel = containingFileEditor.getCaretModel(); -+ caretModel.moveToOffset(containingFile.getNode().getStartOffset()); -+ -+ TemplateBuilderImpl builder = new TemplateBuilderImpl(containingFile); -+ final TypeExpression returnTypeExpression = isUnit ? null : setupReturnTypeTemplate(builder, func); -+ final TypeExpression[] parameterTypeExpressions = setupParameterTypeTemplates(project, builder, parameterList); -+ -+ // add a segment for the parameter list -+ // Note: because TemplateBuilderImpl does not have a replaceElement overload that takes in both a TextRange and alwaysStopAt, we -+ // need to create the segment first and then hack the Expression into the template later. We use this template to update the type -+ // parameter list as the user makes selections in the parameter types, and we need alwaysStopAt to be false so the user can't tab to -+ // it. -+ TypeParameterListExpression expression = setupTypeParameterListTemplate(builder, func); -+ -+ // the template built by TemplateBuilderImpl is ordered by element position, but we want types to be first, so hack it -+ final TemplateImpl template = (TemplateImpl) builder.buildInlineTemplate(); -+ ArrayList variables = template.getVariables(); -+ for (int i = 0; i < parameters.size(); i++) { -+ Collections.swap(variables, i * 2, i * 2 + 1); -+ } -+ -+ // fix up the template to include the expression for the type parameter list -+ variables.add(new Variable(TYPE_PARAMETER_LIST_VARIABLE_NAME, expression, expression, false, true)); -+ -+ // run the template -+ TemplateManager.getInstance(project).startTemplate(containingFileEditor, template, new TemplateEditingAdapter() { -+ @Override -+ public void templateFinished(Template _, boolean brokenOff) { -+ // file templates -+ int offset = template.getSegmentOffset(0); -+ final JetNamedFunction func = PsiTreeUtil.findElementOfClassAtOffset(containingFile, offset, JetNamedFunction.class, false); -+ assert func != null; -+ final List typeRefsToShorten = new ArrayList(); -+ -+ ApplicationManager.getApplication().runWriteAction(new Runnable() { -+ @Override -+ public void run() { -+ // file templates -+ setupFunctionBody(project, func); -+ -+ // change short type names to fully qualified ones (to be shortened below) -+ setupTypeReferencesForShortening(project, func, typeRefsToShorten, parameterTypeExpressions, returnTypeExpression); -+ } -+ }); -+ -+ ReferenceToClassesShortening.compactReferenceToClasses(typeRefsToShorten); -+ } -+ }); -+ } -+ -+ private Map getTypeParameterRenames(JetScope scope) { -+ TypeParameterDescriptor[] receiverTypeParametersNotInScope = selectedReceiverType.getTypeParameters(); -+ Set allTypeParametersNotInScope = new LinkedHashSet(); -+ allTypeParametersNotInScope.addAll(Arrays.asList(receiverTypeParametersNotInScope)); -+ -+ for (Parameter parameter : parameters) { -+ TypeCandidate[] parameterTypeCandidates = parameter.getType().getTypeCandidates(); -+ for (TypeCandidate parameterTypeCandidate : parameterTypeCandidates) { -+ allTypeParametersNotInScope.addAll(Arrays.asList(parameterTypeCandidate.getTypeParameters())); -+ } -+ } -+ -+ if (!isUnit) { -+ TypeCandidate[] returnTypeCandidates = returnType.getTypeCandidates(); -+ for (TypeCandidate returnTypeCandidate : returnTypeCandidates) { -+ allTypeParametersNotInScope.addAll(Arrays.asList(returnTypeCandidate.getTypeParameters())); -+ } -+ } -+ -+ List typeParameters = new ArrayList(allTypeParametersNotInScope); -+ List typeParameterNames = new ArrayList(); -+ for (TypeParameterDescriptor typeParameter : typeParameters) { -+ typeParameterNames.add(getNextAvailableName(typeParameter.getName().getName(), typeParameterNames, scope)); -+ } -+ assert typeParameters.size() == typeParameterNames.size(); -+ Map typeParameterNameMap = new HashMap(); -+ for (int i = 0; i < typeParameters.size(); i++) { -+ typeParameterNameMap.put(typeParameters.get(i), typeParameterNames.get(i)); -+ } -+ -+ return typeParameterNameMap; -+ } -+ -+ private void setupTypeReferencesForShortening( -+ @NotNull Project project, -+ @NotNull JetNamedFunction func, -+ @NotNull List typeRefsToShorten, -+ @NotNull TypeExpression[] parameterTypeExpressions, -+ @Nullable TypeExpression returnTypeExpression -+ ) { -+ if (isExtension) { -+ JetTypeReference receiverTypeRef = -+ JetPsiFactory.createType(project, renderTypeLong(selectedReceiverType.getType(), typeParameterNameMap)); -+ replaceWithLongerName(project, receiverTypeRef, selectedReceiverType.getType()); -+ -+ receiverTypeRef = func.getReceiverTypeRef(); -+ if (receiverTypeRef != null) { -+ typeRefsToShorten.add(receiverTypeRef); -+ } -+ } -+ -+ if (!isUnit) { -+ assert returnTypeExpression != null; -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ if (returnTypeRef != null) { -+ JetType returnType = returnTypeExpression.getTypeFromSelection(returnTypeRef.getText()); -+ if (returnType != null) { // user selected a given type -+ replaceWithLongerName(project, returnTypeRef, returnType); -+ returnTypeRef = func.getReturnTypeRef(); -+ assert returnTypeRef != null; -+ typeRefsToShorten.add(returnTypeRef); -+ } -+ } -+ } -+ -+ List valueParameters = func.getValueParameters(); -+ List parameterIndicesToShorten = new ArrayList(); -+ assert valueParameters.size() == parameterTypeExpressions.length; -+ for (int i = 0; i < valueParameters.size(); i++) { -+ JetParameter parameter = valueParameters.get(i); -+ JetTypeReference parameterTypeRef = parameter.getTypeReference(); -+ if (parameterTypeRef != null) { -+ JetType parameterType = parameterTypeExpressions[i].getTypeFromSelection(parameterTypeRef.getText()); -+ if (parameterType != null) { -+ replaceWithLongerName(project, parameterTypeRef, parameterType); -+ parameterIndicesToShorten.add(i); -+ } -+ } -+ } -+ valueParameters = func.getValueParameters(); -+ for (int i : parameterIndicesToShorten) { -+ JetTypeReference parameterTypeRef = valueParameters.get(i).getTypeReference(); -+ if (parameterTypeRef != null) { -+ typeRefsToShorten.add(parameterTypeRef); -+ } -+ } -+ } -+ -+ private void setupFunctionBody(@NotNull Project project, @NotNull JetNamedFunction func) { -+ FileTemplate fileTemplate = FileTemplateManager.getInstance().getCodeTemplate(TEMPLATE_FROM_USAGE_METHOD_BODY); -+ Properties properties = new Properties(); -+ if (isUnit) { -+ properties.setProperty(FileTemplate.ATTRIBUTE_RETURN_TYPE, ""Unit""); -+ } else { -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ assert returnTypeRef != null; -+ properties.setProperty(FileTemplate.ATTRIBUTE_RETURN_TYPE, returnTypeRef.getText()); -+ } -+ properties.setProperty(FileTemplate.ATTRIBUTE_CLASS_NAME, DescriptorUtils.getFQName(ownerClassDescriptor).getFqName()); -+ properties.setProperty(FileTemplate.ATTRIBUTE_SIMPLE_CLASS_NAME, ownerClassDescriptor.getName().getName()); -+ properties.setProperty(FileTemplate.ATTRIBUTE_METHOD_NAME, methodName); -+ -+ @NonNls String bodyText; -+ try { -+ bodyText = fileTemplate.getText(properties); -+ } catch (ProcessCanceledException e) { -+ throw e; -+ } catch (Exception e) { -+ throw new IncorrectOperationException(""Failed to parse file template"", e); -+ } -+ JetExpression newBodyExpression = JetPsiFactory.createFunctionBody(project, bodyText); -+ JetExpression oldBodyExpression = func.getBodyExpression(); -+ assert oldBodyExpression != null; -+ oldBodyExpression.replace(newBodyExpression); -+ } -+ -+ @NotNull -+ private TypeExpression setupReturnTypeTemplate(@NotNull TemplateBuilder builder, @NotNull JetNamedFunction func) { -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ assert returnTypeRef != null; -+ TypeExpression returnTypeExpression = new TypeExpression(returnType); -+ builder.replaceElement(returnTypeRef, returnTypeExpression); -+ return returnTypeExpression; -+ } -+ -+ @NotNull -+ private TypeParameterListExpression setupTypeParameterListTemplate(@NotNull TemplateBuilderImpl builder, @NotNull JetNamedFunction func) { -+ Map typeParameterMap = new HashMap(); -+ String[] receiverTypeParameterNames = selectedReceiverType.getTypeParameterNames(); -+ -+ for (Parameter parameter : parameters) { -+ TypeCandidate[] parameterTypeCandidates = parameter.getType().getTypeCandidates(); -+ for (TypeCandidate parameterTypeCandidate : parameterTypeCandidates) { -+ typeParameterMap.put(parameterTypeCandidate.getRenderedType(), parameterTypeCandidate.getTypeParameterNames()); -+ } -+ } -+ -+ JetTypeReference returnTypeRef = func.getReturnTypeRef(); -+ if (returnTypeRef != null) { -+ TypeCandidate[] returnTypeCandidates = returnType.getTypeCandidates(); -+ for (TypeCandidate returnTypeCandidate : returnTypeCandidates) { -+ typeParameterMap.put(returnTypeCandidate.getRenderedType(), returnTypeCandidate.getTypeParameterNames()); -+ } -+ } -+ -+ builder.replaceElement(func, TextRange.create(3, 3), TYPE_PARAMETER_LIST_VARIABLE_NAME, null, false); // ((3, 3) is after ""fun"") -+ return new TypeParameterListExpression(receiverTypeParameterNames, typeParameterMap); -+ } -+ -+ private TypeExpression[] setupParameterTypeTemplates(@NotNull Project project, @NotNull TemplateBuilder builder, -+ @NotNull JetParameterList parameterList) { -+ List jetParameters = parameterList.getParameters(); -+ assert jetParameters.size() == parameters.size(); -+ TypeExpression[] parameterTypeExpressions = new TypeExpression[parameters.size()]; -+ JetNameValidator dummyValidator = new DummyJetNameValidator(project); -+ for (int i = 0; i < parameters.size(); i++) { -+ Parameter parameter = parameters.get(i); -+ JetParameter jetParameter = jetParameters.get(i); -+ -+ // add parameter type to the template -+ parameterTypeExpressions[i] = new TypeExpression(parameter.getType()); -+ JetTypeReference parameterTypeRef = jetParameter.getTypeReference(); -+ assert parameterTypeRef != null; -+ builder.replaceElement(parameterTypeRef, parameterTypeExpressions[i]); -+ -+ // add parameter name to the template -+ String[] possibleNamesFromExpression = parameter.getType().getPossibleNamesFromExpression(); -+ String preferredName = parameter.getPreferredName(); -+ String[] possibleNames; -+ if (preferredName != null) { -+ possibleNames = new String[possibleNamesFromExpression.length + 1]; -+ possibleNames[0] = preferredName; -+ System.arraycopy(possibleNamesFromExpression, 0, possibleNames, 1, possibleNamesFromExpression.length); -+ } else { -+ possibleNames = possibleNamesFromExpression; -+ } -+ -+ // figure out suggested names for each type option -+ Map parameterTypeToNamesMap = new HashMap(); -+ for (TypeCandidate typeCandidate : parameter.getType().getTypeCandidates()) { -+ String[] suggestedNames = JetNameSuggester.suggestNamesForType(typeCandidate.getType(), dummyValidator); -+ parameterTypeToNamesMap.put(typeCandidate.getRenderedType(), suggestedNames); -+ } -+ -+ // add expression to builder -+ Expression parameterNameExpression = new ParameterNameExpression(possibleNames, parameterTypeToNamesMap); -+ PsiElement parameterNameIdentifier = jetParameter.getNameIdentifier(); -+ assert parameterNameIdentifier != null; -+ builder.replaceElement(parameterNameIdentifier, parameterNameExpression); -+ } -+ return parameterTypeExpressions; -+ } -+ -+ private void replaceWithLongerName(@NotNull Project project, @NotNull JetTypeReference typeRef, @NotNull JetType type) { -+ JetTypeReference fullyQualifiedReceiverTypeRef = JetPsiFactory.createType(project, renderTypeLong(type, typeParameterNameMap)); -+ typeRef.replace(fullyQualifiedReceiverTypeRef); -+ } -+ -+ @NotNull -+ private static JetType substituteType(@NotNull JetType type, @NotNull TypeSubstitution substitution, @NotNull Variance variance) { -+ switch (variance) { -+ case INVARIANT: -+ // for invariant, can replace only when they're equal -+ if (type.equals(substitution.getForType())) { -+ return substitution.getByType(); -+ } -+ break; -+ case IN_VARIANCE: -+ // for covariant (e.g. function parameter), can replace type with any of its supertypes -+ if (JetTypeChecker.INSTANCE.isSubtypeOf(type, substitution.getForType())) { -+ return substitution.getByType(); -+ } -+ break; -+ case OUT_VARIANCE: -+ // for contravariant (e.g. function return value), can replace type with any of its subtypes -+ if (JetTypeChecker.INSTANCE.isSubtypeOf(substitution.getForType(), type)) { -+ return substitution.getByType(); -+ } -+ break; -+ } -+ -+ List newArguments = new ArrayList(); -+ List typeParameters = type.getConstructor().getParameters(); -+ int i = 0; -+ for (TypeProjection projection : type.getArguments()) { -+ TypeParameterDescriptor typeParameter = typeParameters.get(i); -+ JetType newArgument = substituteType(projection.getType(), substitution, typeParameter.getVariance()); -+ newArguments.add(new TypeProjection(Variance.INVARIANT, newArgument)); -+ i++; -+ } -+ return new JetTypeImpl(type.getAnnotations(), type.getConstructor(), -+ type.isNullable(), newArguments, type.getMemberScope()); -+ } -+ -+ private static boolean containsType(JetType outer, JetType inner) { -+ if (outer.equals(inner)) { -+ return true; -+ } -+ -+ for (TypeProjection projection : outer.getArguments()) { -+ if (containsType(projection.getType(), inner)) { -+ return true; -+ } -+ } -+ -+ return false; -+ } -+ -+ @NotNull -+ private static String renderDescriptor( -+ @NotNull DeclarationDescriptor declarationDescriptor, -+ @NotNull Map typeParameterNameMap, -+ boolean fq -+ ) { -+ if (declarationDescriptor instanceof TypeParameterDescriptor) { -+ String replacement = typeParameterNameMap.get(declarationDescriptor); -+ return replacement == null ? declarationDescriptor.getName().getName() : replacement; -+ } else { -+ return fq ? DescriptorUtils.getFQName(declarationDescriptor).getFqName() : declarationDescriptor.getName().getName(); -+ } -+ } -+ -+ @NotNull -+ private static String renderDescriptor(@NotNull DeclarationDescriptor declarationDescriptor, boolean fq) { -+ return renderDescriptor(declarationDescriptor, Collections.emptyMap(), fq); -+ } -+ -+ private static String renderType(@NotNull JetType type, @NotNull Map typeParameterNameMap, boolean fq) { -+ List projections = type.getArguments(); -+ DeclarationDescriptor declarationDescriptor = type.getConstructor().getDeclarationDescriptor(); -+ assert declarationDescriptor != null; -+ if (projections.isEmpty()) { -+ return renderDescriptor(declarationDescriptor, typeParameterNameMap, fq); -+ } -+ -+ List arguments = new ArrayList(); -+ for (TypeProjection projection : projections) { -+ arguments.add(renderType(projection.getType(), typeParameterNameMap, fq)); -+ } -+ return renderDescriptor(declarationDescriptor, typeParameterNameMap, fq) + ""<"" + StringUtil.join(arguments, "", "") + "">""; -+ } -+ -+ @NotNull -+ private static String renderTypeShort(@NotNull JetType type, @NotNull Map typeParameterNameMap) { -+ return renderType(type, typeParameterNameMap, false); -+ } -+ -+ @NotNull -+ private static String renderTypeLong(@NotNull JetType type, @NotNull Map typeParameterNameMap) { -+ return renderType(type, typeParameterNameMap, true); -+ } -+ -+ @NotNull -+ private static TypeParameterDescriptor[] getTypeParameterNamesNotInScope( -+ @NotNull Collection typeParameters, -+ @NotNull JetScope scope -+ ) { -+ List typeParameterNames = new ArrayList(); -+ for (TypeParameterDescriptor typeParameter : typeParameters) { -+ ClassifierDescriptor classifier = scope.getClassifier(typeParameter.getName()); -+ if (classifier == null || !classifier.equals(typeParameter)) { -+ typeParameterNames.add(typeParameter); -+ } -+ } -+ return typeParameterNames.toArray(new TypeParameterDescriptor[typeParameterNames.size()]); -+ } -+ -+ @NotNull -+ private static Set getTypeParametersInType(@NotNull JetType type) { -+ Set typeParameters = new LinkedHashSet(); -+ List arguments = type.getArguments(); -+ if (arguments.isEmpty()) { -+ ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); -+ if (descriptor instanceof TypeParameterDescriptor) { -+ typeParameters.add((TypeParameterDescriptor) descriptor); -+ } -+ } else { -+ for (TypeProjection projection : arguments) { -+ typeParameters.addAll(getTypeParametersInType(projection.getType())); -+ } -+ } -+ return typeParameters; -+ } -+ -+ @NotNull -+ private static String getNextAvailableName(@NotNull String name, @NotNull Collection existingNames) { -+ if (existingNames.contains(name)) { -+ int j = 1; -+ while (existingNames.contains(name + j)) j++; -+ name += j; -+ } -+ return name; -+ } -+ -+ @NotNull -+ private static String getNextAvailableName(@NotNull String name, @NotNull Collection existingNames, @NotNull JetScope scope) { -+ if (existingNames.contains(name) || scope.getClassifier(Name.identifier(name)) != null) { -+ int j = 1; -+ while (existingNames.contains(name + j) || scope.getClassifier(Name.identifier(name + j)) != null) j++; -+ name += j; -+ } -+ return name; -+ } -+ -+ @NotNull -+ private static JetType[] guessTypeForExpression(@NotNull JetExpression expr, @NotNull BindingContext context) { -+ JetType type = context.get(BindingContext.EXPRESSION_TYPE, expr); -+ JetNamedDeclaration declaration = null; -+ -+ // if we know the actual type of the expression -+ if (type != null) { -+ return new JetType[] {type}; -+ } -+ -+ // expression has an expected type -+ else if ((type = context.get(BindingContext.EXPECTED_EXPRESSION_TYPE, expr)) != null) { -+ return new JetType[] {type}; -+ } -+ -+ // expression itself is a type assertion -+ else if (expr instanceof JetTypeConstraint) { // expression itself is a type assertion -+ JetTypeConstraint constraint = (JetTypeConstraint) expr; -+ return new JetType[] {context.get(BindingContext.TYPE, constraint.getBoundTypeReference())}; -+ } -+ -+ // expression is on the left side of a type assertion -+ else if (expr.getParent() instanceof JetTypeConstraint) { -+ JetTypeConstraint constraint = (JetTypeConstraint) expr.getParent(); -+ return new JetType[] {context.get(BindingContext.TYPE, constraint.getBoundTypeReference())}; -+ } -+ -+ // expression is on the lhs of a multi-declaration -+ else if (expr instanceof JetMultiDeclarationEntry) { -+ JetMultiDeclarationEntry entry = (JetMultiDeclarationEntry) expr; -+ JetTypeReference typeRef = entry.getTypeRef(); -+ if (typeRef != null) { // and has a specified type -+ return new JetType[] {context.get(BindingContext.TYPE, typeRef)}; -+ } -+ declaration = entry; // otherwise fall through and guess -+ } -+ -+ // expression is a parameter (e.g. declared in a for-loop) -+ else if (expr instanceof JetParameter) { -+ JetParameter parameter = (JetParameter) expr; -+ JetTypeReference typeRef = parameter.getTypeReference(); -+ if (typeRef != null) { // and has a specified type -+ return new JetType[] {context.get(BindingContext.TYPE, typeRef)}; -+ } -+ declaration = parameter; // otherwise fall through and guess -+ } -+ -+ // the expression is the RHS of a variable assignment with a specified type -+ else if (expr.getParent() instanceof JetVariableDeclaration) { -+ JetVariableDeclaration variable = (JetVariableDeclaration) expr.getParent(); -+ JetTypeReference typeRef = variable.getTypeRef(); -+ if (typeRef != null) { // and has a specified type -+ return new JetType[] {context.get(BindingContext.TYPE, typeRef)}; -+ } -+ declaration = variable; // otherwise fall through and guess, based on LHS -+ } -+ -+ // guess based on declaration -+ SearchScope scope = expr.getContainingFile().getUseScope(); -+ Set expectedTypes = new HashSet(); -+ if (declaration != null) { -+ for (PsiReference ref : SearchUtils.findAllReferences(declaration, scope)) { -+ if (ref instanceof JetSimpleNameReference) { -+ JetSimpleNameReference simpleNameRef = (JetSimpleNameReference) ref; -+ JetType expectedType = context.get(BindingContext.EXPECTED_EXPRESSION_TYPE, simpleNameRef.getExpression()); -+ if (expectedType != null) { -+ expectedTypes.add(expectedType); -+ } -+ } -+ } -+ } -+ if (expectedTypes.isEmpty()) { -+ return new JetType[0]; -+ } -+ type = TypeUtils.intersect(JetTypeChecker.INSTANCE, expectedTypes); -+ if (type != null) { -+ return new JetType[] {type}; -+ } else { // intersection doesn't exist; let user make an imperfect choice -+ return expectedTypes.toArray(new JetType[expectedTypes.size()]); -+ } -+ } -+ -+ private static boolean isUnit(@NotNull JetType type) {","Method is trivial and used once. It's redundant. -",Why is this needed? Looks like a duplicate file. -112,"@@ -0,0 +1,147 @@ -+/* -+ * Copyright 2010-2017 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.kotlin.idea.intentions -+ -+import com.intellij.codeInsight.intention.IntentionAction -+import com.intellij.codeInsight.intention.JvmCommonIntentionActionsFactory -+import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiElement -+import com.intellij.psi.PsiFile -+import com.intellij.psi.PsiModifier -+import com.intellij.psi.PsiType -+import org.jetbrains.kotlin.asJava.elements.KtLightElement -+import org.jetbrains.kotlin.builtins.DefaultBuiltIns -+import org.jetbrains.kotlin.descriptors.Visibilities -+import org.jetbrains.kotlin.idea.core.insertMembersAfter -+import org.jetbrains.kotlin.idea.quickfix.AddModifierFix -+import org.jetbrains.kotlin.idea.quickfix.RemoveModifierFix -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.platform.JavaToKotlinClassMap -+import org.jetbrains.kotlin.psi.KtClassOrObject -+import org.jetbrains.kotlin.psi.KtElement -+import org.jetbrains.kotlin.psi.KtModifierListOwner -+import org.jetbrains.kotlin.psi.KtPsiFactory -+import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe -+import org.jetbrains.uast.UClass -+import org.jetbrains.uast.UDeclaration -+import org.jetbrains.uast.UElement -+ -+ -+class KotlinCommonIntentionActionsFactory : JvmCommonIntentionActionsFactory() { -+ override fun createChangeModifierAction(declaration: UDeclaration, modifier: String, shouldPresent: Boolean): IntentionAction? { -+ val kModifierOwner = declaration.asKtElement() -+ ?: throw IllegalArgumentException(""$declaration is expected to contain KtLightElement with KtModifierListOwner"") -+ -+ val (kToken, shouldPresentMapped) = if (PsiModifier.FINAL == modifier) -+ KtTokens.OPEN_KEYWORD to !shouldPresent -+ else -+ javaPsiModifiersMapping[modifier] to shouldPresent -+ -+ if (kToken == null) return null -+ return if (shouldPresentMapped) -+ AddModifierFix.createIfApplicable(kModifierOwner, kToken) -+ else -+ RemoveModifierFix(kModifierOwner, kToken, false) -+ } -+ -+ private inline fun UElement.asKtElement(): T? = -+ (psi as? KtLightElement<*, *>?)?.kotlinOrigin as? T -+ -+ companion object { -+ val javaPsiModifiersMapping = mapOf( -+ PsiModifier.PRIVATE to KtTokens.PRIVATE_KEYWORD, -+ PsiModifier.PUBLIC to KtTokens.PUBLIC_KEYWORD, -+ PsiModifier.PROTECTED to KtTokens.PUBLIC_KEYWORD, -+ PsiModifier.ABSTRACT to KtTokens.ABSTRACT_KEYWORD -+ ) -+ -+ val javaVisibilityMapping: Map = mapOf( -+ PsiModifier.PRIVATE to Visibilities.PRIVATE.displayName, -+ PsiModifier.PUBLIC to """", -+ PsiModifier.PROTECTED to Visibilities.PROTECTED.displayName, -+ PsiModifier.PACKAGE_LOCAL to Visibilities.INTERNAL.displayName -+ ).withDefault { Visibilities.DEFAULT_VISIBILITY.displayName } -+ } -+ -+ override fun createAddMethodAction(uClass: UClass, methodName: String, visibilityModifier: String, returnType: PsiType, vararg parameters: PsiType): IntentionAction? { -+ val returnTypeString: String = typeString(returnType).let { -+ when { -+ it.isEmpty() -> """" -+ else -> "": $it"" -+ } -+ } -+ val paramsStr = parameters.mapIndexed { index, psiType -> ""arg${index + 1}: ${typeString(psiType)}"" }.joinToString() -+ return object : LocalQuickFixAndIntentionActionOnPsiElement(uClass) { -+ override fun getFamilyName(): String = ""Add method"" -+ -+ private val text = ""Add method '$methodName' to '${uClass.name}'"" -+ -+ override fun getText(): String = text -+ -+ override fun invoke(project: Project, file: PsiFile, editor: Editor?, startElement: PsiElement, endElement: PsiElement) { -+ val visibilityStr = javaVisibilityMapping.getValue(visibilityModifier) -+ val psiFactory = KtPsiFactory(uClass) -+ val function = psiFactory.createFunction(""$visibilityStr fun $methodName($paramsStr)$returnTypeString{}"")",You should use `KtPsiFactory.CallableBuilder` instead of building the text manually.,Should the file be named `IdeaAction.java` instead of `PsiAction.java`? -113,"@@ -0,0 +1,15 @@ -+// ""Replace with safe (?.) call"" ""false"" -+// ACTION: Add non-null asserted (!!) call -+// ACTION: Convert to expression body -+// ACTION: Replace with safe (this?.) call -+// ACTION: Wrap with '?.let { ... }' call -+// ERROR: Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type A? -+ -+class A { -+ fun foo() { -+ } -+} -+ -+fun A?.bar() { -+ foo() -+}","Why does this test have so strange name? I see no `invoke` here, either safe or unsafe",Not sure what is going on here. -114,"@@ -0,0 +1,15 @@ -+// WITH_RUNTIME -+ -+fun contains(set: Set, x: Int): Boolean = when { -+ set.size == 0 -> false -+ else -> x in set as Set -+} -+ -+fun box(): String { -+ val set = setOf(1) -+ if (contains(set, 1)) { -+ return ""OK"" -+ } -+ -+ return ""Fail"" -+}","This test in not related to Range#contains, but at some point I had implementation which passed all tests (without this one), but ant build was failed. -",Not sure if the compiler is smart enough to optimize this into one line -115,"@@ -0,0 +1,15 @@ -+class TestingUse { -+ fun test(sum: Int.(a: Int) -> Int, b: Int): Int { -+ return b.sum(b) -+ } -+ fun test2(sum: (a: Int, b: Int) -> Int, c: Int): Int {","Basically you've used the same test data file in all tests on `makeTypeExplicitInLambda`, altering the calling function in each case. This is not a good idea, because once one of such tests fails, the investigating person might think that the fact that there are several functions in this file is relevant to the test case, while in reality it's not. - -Please try to make your tests as minimal as possible, i.e. only include relevant data in each test. -",nit: how about `test1` instead of `test2`? -116,"@@ -0,0 +1,15 @@ -+data class Foo(val a: String) { -+ fun copy(i: Int) {} -+} -+ -+class Foo2() { -+ fun copy(i: Int) {} -+} -+","I'd add an example that clearly shows all should be named, like this: -``` -data class SomeName(a: Int, b: Int, c: String) -f.copy(2, c = """") -```",This class does not need to have `a: String` and `b: Int`. It's redunda -117,"@@ -0,0 +1,150 @@ -+/* -+ * 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.effectsystem.adapters -+ -+import org.jetbrains.kotlin.config.LanguageFeature -+import org.jetbrains.kotlin.config.LanguageVersionSettings -+import org.jetbrains.kotlin.descriptors.ModuleDescriptor -+import org.jetbrains.kotlin.effectsystem.effects.ESCalls -+import org.jetbrains.kotlin.effectsystem.effects.ESReturns -+import org.jetbrains.kotlin.effectsystem.factories.UNKNOWN_CONSTANT -+import org.jetbrains.kotlin.effectsystem.factories.lift -+import org.jetbrains.kotlin.effectsystem.resolving.FunctorResolver -+import org.jetbrains.kotlin.effectsystem.structure.ESEffect -+import org.jetbrains.kotlin.effectsystem.structure.EffectSchema -+import org.jetbrains.kotlin.effectsystem.visitors.Reducer -+import org.jetbrains.kotlin.effectsystem.visitors.SchemaBuilder -+import org.jetbrains.kotlin.psi.KtCallExpression -+import org.jetbrains.kotlin.psi.KtDeclaration -+import org.jetbrains.kotlin.psi.KtExpression -+import org.jetbrains.kotlin.psi.KtLambdaExpression -+import org.jetbrains.kotlin.resolve.BindingContext -+import org.jetbrains.kotlin.resolve.BindingTrace -+import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall -+import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo -+import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory -+ -+class EffectSystem(val languageVersionSettings: LanguageVersionSettings) { -+ private val functorResolver = FunctorResolver() -+ -+ fun getResultDataFlowInfo( -+ resolvedCall: ResolvedCall<*>, -+ bindingTrace: BindingTrace, -+ moduleDescriptor: ModuleDescriptor -+ ): DataFlowInfo { -+ if (!languageVersionSettings.supportsFeature(LanguageFeature.ContractEffects)) return DataFlowInfo.EMPTY -+ -+ // Prevent launch of effect system machinery on pointless cases (constants/enums/constructors/etc.) -+ val callExpression = resolvedCall.call.callElement as? KtCallExpression ?: return DataFlowInfo.EMPTY -+ if (callExpression is KtDeclaration) return DataFlowInfo.EMPTY -+ -+ val resultContextInfo = getContextInfoWhen(ESReturns(UNKNOWN_CONSTANT), callExpression, bindingTrace, moduleDescriptor) -+ -+ return resultContextInfo.toDataFlowInfo(languageVersionSettings) -+ } -+ -+ fun recordDefiniteInvocations(resolvedCall: ResolvedCall<*>, bindingTrace: BindingTrace, moduleDescriptor: ModuleDescriptor) {",In this function we have some strange combination of `getResultDataFlowInfo` and `checkAndRecordDefiniteInvocations`. I think some refactoring is needed here.,remove this file? -118,"@@ -0,0 +1,150 @@ -+/* -+ * 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.effectsystem.adapters -+ -+import org.jetbrains.kotlin.config.LanguageFeature -+import org.jetbrains.kotlin.config.LanguageVersionSettings -+import org.jetbrains.kotlin.descriptors.ModuleDescriptor -+import org.jetbrains.kotlin.effectsystem.effects.ESCalls -+import org.jetbrains.kotlin.effectsystem.effects.ESReturns -+import org.jetbrains.kotlin.effectsystem.factories.UNKNOWN_CONSTANT -+import org.jetbrains.kotlin.effectsystem.factories.lift -+import org.jetbrains.kotlin.effectsystem.resolving.FunctorResolver -+import org.jetbrains.kotlin.effectsystem.structure.ESEffect -+import org.jetbrains.kotlin.effectsystem.structure.EffectSchema -+import org.jetbrains.kotlin.effectsystem.visitors.Reducer -+import org.jetbrains.kotlin.effectsystem.visitors.SchemaBuilder -+import org.jetbrains.kotlin.psi.KtCallExpression -+import org.jetbrains.kotlin.psi.KtDeclaration -+import org.jetbrains.kotlin.psi.KtExpression -+import org.jetbrains.kotlin.psi.KtLambdaExpression -+import org.jetbrains.kotlin.resolve.BindingContext -+import org.jetbrains.kotlin.resolve.BindingTrace -+import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall -+import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo -+import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory -+ -+class EffectSystem(val languageVersionSettings: LanguageVersionSettings) { -+ private val functorResolver = FunctorResolver() -+ -+ fun getResultDataFlowInfo( -+ resolvedCall: ResolvedCall<*>, -+ bindingTrace: BindingTrace, -+ moduleDescriptor: ModuleDescriptor -+ ): DataFlowInfo { -+ if (!languageVersionSettings.supportsFeature(LanguageFeature.ContractEffects)) return DataFlowInfo.EMPTY -+ -+ // Prevent launch of effect system machinery on pointless cases (constants/enums/constructors/etc.) -+ val callExpression = resolvedCall.call.callElement as? KtCallExpression ?: return DataFlowInfo.EMPTY -+ if (callExpression is KtDeclaration) return DataFlowInfo.EMPTY -+ -+ val resultContextInfo = getContextInfoWhen(ESReturns(UNKNOWN_CONSTANT), callExpression, bindingTrace, moduleDescriptor) -+ -+ return resultContextInfo.toDataFlowInfo(languageVersionSettings) -+ } -+ -+ fun recordDefiniteInvocations(resolvedCall: ResolvedCall<*>, bindingTrace: BindingTrace, moduleDescriptor: ModuleDescriptor) { -+ if (!languageVersionSettings.supportsFeature(LanguageFeature.CalledInPlaceEffect)) return -+ -+ // Prevent launch of effect system machinery on pointless cases (constants/enums/constructors/etc.) -+ val callExpression = resolvedCall.call.callElement as? KtCallExpression ?: return -+ if (callExpression is KtDeclaration) return -+ -+ val resultingContextInfo = getContextInfoWhen(ESReturns(UNKNOWN_CONSTANT), callExpression, bindingTrace, moduleDescriptor) -+ for (effect in resultingContextInfo.firedEffects) { -+ val callsEffect = effect as? ESCalls ?: continue -+ val id = callsEffect.callable.id as DataFlowValueID -+ -+ // Could be also IdentifierInfo.Variable when call passes non-anonymous lambda for callable parameter -+ val lambdaExpr = (id.dfv.identifierInfo as? DataFlowValueFactory.ExpressionIdentifierInfo)?.expression ?: continue -+ assert(lambdaExpr is KtLambdaExpression) { ""Unexpected argument of Calls-effect: expected KtLambdaExpression, got $lambdaExpr"" } -+ -+ bindingTrace.record(BindingContext.LAMBDA_INVOCATIONS, lambdaExpr as KtLambdaExpression, callsEffect.kind) -+ } -+ } -+ -+ fun getConditionalInfoForThenBranch( -+ condition: KtExpression?, -+ bindingTrace: BindingTrace, -+ moduleDescriptor: ModuleDescriptor -+ ): DataFlowInfo { -+ if (!languageVersionSettings.supportsFeature(LanguageFeature.ContractEffects)) return DataFlowInfo.EMPTY -+ if (condition == null) return DataFlowInfo.EMPTY -+ -+ return getContextInfoWhen(ESReturns(true.lift()), condition, bindingTrace, moduleDescriptor) -+ .toDataFlowInfo(languageVersionSettings) -+ } -+ -+ fun getConditionalInfoForElseBranch( -+ condition: KtExpression?, -+ bindingTrace: BindingTrace, -+ moduleDescriptor: ModuleDescriptor -+ ): DataFlowInfo { -+ if (!languageVersionSettings.supportsFeature(LanguageFeature.ContractEffects)) return DataFlowInfo.EMPTY -+ if (condition == null) return DataFlowInfo.EMPTY -+ -+ return getContextInfoWhen(ESReturns(false.lift()), condition, bindingTrace, moduleDescriptor) -+ .toDataFlowInfo(languageVersionSettings) -+ } -+ -+ private fun getContextInfoWhen( -+ observedEffect: ESEffect, -+ expression: KtExpression, -+ bindingTrace: BindingTrace, -+ moduleDescriptor: ModuleDescriptor -+ ): MutableContextInfo { -+ val schema = getSchema(expression, bindingTrace, moduleDescriptor) ?: return MutableContextInfo.EMPTY -+ -+ val extractedContextInfo = InfoCollector(observedEffect).collectFromSchema(schema) -+ -+ return extractedContextInfo -+ } -+ -+ private fun getSchema(expression: KtExpression, bindingTrace: BindingTrace, moduleDescriptor: ModuleDescriptor): EffectSchema? { -+ if (bindingTrace[BindingContext.EXPRESSION_EFFECTS, expression] == null) { -+ val evaluatedSchema = evaluateSchema(expression, bindingTrace.bindingContext, moduleDescriptor) ?: return null -+ bindingTrace.record(BindingContext.EXPRESSION_EFFECTS, expression, evaluatedSchema) -+ } -+ -+ return bindingTrace[BindingContext.EXPRESSION_EFFECTS, expression]",I'd try to avoid repeated access to `bindingTrace` here.,remove this file? -119,"@@ -0,0 +1,150 @@ -+/* -+ * 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.effectsystem.adapters -+ -+import org.jetbrains.kotlin.config.LanguageFeature -+import org.jetbrains.kotlin.config.LanguageVersionSettings -+import org.jetbrains.kotlin.descriptors.ModuleDescriptor -+import org.jetbrains.kotlin.effectsystem.effects.ESCalls -+import org.jetbrains.kotlin.effectsystem.effects.ESReturns -+import org.jetbrains.kotlin.effectsystem.factories.UNKNOWN_CONSTANT -+import org.jetbrains.kotlin.effectsystem.factories.lift -+import org.jetbrains.kotlin.effectsystem.resolving.FunctorResolver -+import org.jetbrains.kotlin.effectsystem.structure.ESEffect -+import org.jetbrains.kotlin.effectsystem.structure.EffectSchema -+import org.jetbrains.kotlin.effectsystem.visitors.Reducer -+import org.jetbrains.kotlin.effectsystem.visitors.SchemaBuilder -+import org.jetbrains.kotlin.psi.KtCallExpression -+import org.jetbrains.kotlin.psi.KtDeclaration -+import org.jetbrains.kotlin.psi.KtExpression -+import org.jetbrains.kotlin.psi.KtLambdaExpression -+import org.jetbrains.kotlin.resolve.BindingContext -+import org.jetbrains.kotlin.resolve.BindingTrace -+import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall -+import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo -+import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory -+ -+class EffectSystem(val languageVersionSettings: LanguageVersionSettings) { -+ private val functorResolver = FunctorResolver() -+ -+ fun getResultDataFlowInfo( -+ resolvedCall: ResolvedCall<*>, -+ bindingTrace: BindingTrace, -+ moduleDescriptor: ModuleDescriptor -+ ): DataFlowInfo { -+ if (!languageVersionSettings.supportsFeature(LanguageFeature.ContractEffects)) return DataFlowInfo.EMPTY -+ -+ // Prevent launch of effect system machinery on pointless cases (constants/enums/constructors/etc.) -+ val callExpression = resolvedCall.call.callElement as? KtCallExpression ?: return DataFlowInfo.EMPTY -+ if (callExpression is KtDeclaration) return DataFlowInfo.EMPTY -+ -+ val resultContextInfo = getContextInfoWhen(ESReturns(UNKNOWN_CONSTANT), callExpression, bindingTrace, moduleDescriptor) -+ -+ return resultContextInfo.toDataFlowInfo(languageVersionSettings) -+ } -+ -+ fun recordDefiniteInvocations(resolvedCall: ResolvedCall<*>, bindingTrace: BindingTrace, moduleDescriptor: ModuleDescriptor) { -+ if (!languageVersionSettings.supportsFeature(LanguageFeature.CalledInPlaceEffect)) return -+ -+ // Prevent launch of effect system machinery on pointless cases (constants/enums/constructors/etc.) -+ val callExpression = resolvedCall.call.callElement as? KtCallExpression ?: return -+ if (callExpression is KtDeclaration) return -+ -+ val resultingContextInfo = getContextInfoWhen(ESReturns(UNKNOWN_CONSTANT), callExpression, bindingTrace, moduleDescriptor) -+ for (effect in resultingContextInfo.firedEffects) { -+ val callsEffect = effect as? ESCalls ?: continue -+ val id = callsEffect.callable.id as DataFlowValueID -+ -+ // Could be also IdentifierInfo.Variable when call passes non-anonymous lambda for callable parameter -+ val lambdaExpr = (id.dfv.identifierInfo as? DataFlowValueFactory.ExpressionIdentifierInfo)?.expression ?: continue -+ assert(lambdaExpr is KtLambdaExpression) { ""Unexpected argument of Calls-effect: expected KtLambdaExpression, got $lambdaExpr"" } -+ -+ bindingTrace.record(BindingContext.LAMBDA_INVOCATIONS, lambdaExpr as KtLambdaExpression, callsEffect.kind) -+ } -+ } -+ -+ fun getConditionalInfoForThenBranch( -+ condition: KtExpression?, -+ bindingTrace: BindingTrace, -+ moduleDescriptor: ModuleDescriptor -+ ): DataFlowInfo { -+ if (!languageVersionSettings.supportsFeature(LanguageFeature.ContractEffects)) return DataFlowInfo.EMPTY -+ if (condition == null) return DataFlowInfo.EMPTY -+ -+ return getContextInfoWhen(ESReturns(true.lift()), condition, bindingTrace, moduleDescriptor) -+ .toDataFlowInfo(languageVersionSettings) -+ } -+ -+ fun getConditionalInfoForElseBranch( -+ condition: KtExpression?, -+ bindingTrace: BindingTrace, -+ moduleDescriptor: ModuleDescriptor -+ ): DataFlowInfo { -+ if (!languageVersionSettings.supportsFeature(LanguageFeature.ContractEffects)) return DataFlowInfo.EMPTY -+ if (condition == null) return DataFlowInfo.EMPTY -+ -+ return getContextInfoWhen(ESReturns(false.lift()), condition, bindingTrace, moduleDescriptor) -+ .toDataFlowInfo(languageVersionSettings) -+ } -+ -+ private fun getContextInfoWhen( -+ observedEffect: ESEffect, -+ expression: KtExpression, -+ bindingTrace: BindingTrace, -+ moduleDescriptor: ModuleDescriptor -+ ): MutableContextInfo { -+ val schema = getSchema(expression, bindingTrace, moduleDescriptor) ?: return MutableContextInfo.EMPTY -+ -+ val extractedContextInfo = InfoCollector(observedEffect).collectFromSchema(schema) -+ -+ return extractedContextInfo -+ } -+ -+ private fun getSchema(expression: KtExpression, bindingTrace: BindingTrace, moduleDescriptor: ModuleDescriptor): EffectSchema? { -+ if (bindingTrace[BindingContext.EXPRESSION_EFFECTS, expression] == null) { -+ val evaluatedSchema = evaluateSchema(expression, bindingTrace.bindingContext, moduleDescriptor) ?: return null -+ bindingTrace.record(BindingContext.EXPRESSION_EFFECTS, expression, evaluatedSchema) -+ } -+ -+ return bindingTrace[BindingContext.EXPRESSION_EFFECTS, expression] -+ } -+ -+ private fun evaluateSchema(expression: KtExpression, bindingContext: BindingContext, moduleDescriptor: ModuleDescriptor): EffectSchema? { -+ val ctBuilder = CallTreeBuilder(bindingContext, moduleDescriptor, functorResolver) -+ val callTree = expression.accept(ctBuilder, Unit) -+ -+ val esBuilder = SchemaBuilder() -+ val schema = callTree.accept(esBuilder) ?: return null -+ -+ val reducedSchema = Reducer().reduceSchema(schema) -+ -+ return reducedSchema -+ } -+ -+ private fun checkAndRecordDefiniteInvocations(bindingTrace: BindingTrace, contextInfo: MutableContextInfo) {",BTW this guy is not in use now,remove this file? -120,"@@ -0,0 +1,16 @@ -+fun testIsNullOrBlank(x: String?) {","This test has no annotation of some language feature on. Looks strange. I'd check all new tests, and most probably all of them should have some annotation. Otherwise backward compatibility can be broken",What does it mean for a null value to be treated as empty string? -121,"@@ -0,0 +1,160 @@ -+/* -+ * 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.wrappers.trees -+ -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.tree.JCTree -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.descriptors.Visibilities -+import org.jetbrains.kotlin.descriptors.Visibility -+import org.jetbrains.kotlin.load.java.structure.* -+import org.jetbrains.kotlin.name.FqName -+ -+abstract class ClassifierType(tree: T,",May be it should be `sealed`,Please do not use wildcard imports. -122,"@@ -0,0 +1,160 @@ -+/* -+ * 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.wrappers.trees -+ -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.tree.JCTree -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.descriptors.Visibilities -+import org.jetbrains.kotlin.descriptors.Visibility -+import org.jetbrains.kotlin.load.java.structure.* -+import org.jetbrains.kotlin.name.FqName -+ -+abstract class ClassifierType(tree: T, -+ treePath: TreePath, -+ javac: Javac) : JCType(tree, treePath, javac), JavaClassifierType { -+ override val classifier by lazy { getClassifier(treePath, javac) } -+ -+ override val canonicalText -+ get() = (classifier as? JavaClass)?.fqName?.asString() ?: treePath.leaf.toString() -+ -+ override val presentableText -+ get() = canonicalText -+ -+ private val typeParameter by lazy { -+ treePath.filter { it is JCTree.JCClassDecl || it is JCTree.JCMethodDecl } -+ .flatMap { -+ when (it) { -+ is JCTree.JCClassDecl -> it.typarams -+ is JCTree.JCMethodDecl -> it.typarams -+ else -> emptyList>()",May be throw an exception here? We should not achieve this point,Please put this on one line. -123,"@@ -0,0 +1,160 @@ -+/* -+ * 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.wrappers.trees -+ -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.tree.JCTree -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.descriptors.Visibilities -+import org.jetbrains.kotlin.descriptors.Visibility -+import org.jetbrains.kotlin.load.java.structure.* -+import org.jetbrains.kotlin.name.FqName -+ -+abstract class ClassifierType(tree: T, -+ treePath: TreePath, -+ javac: Javac) : JCType(tree, treePath, javac), JavaClassifierType { -+ override val classifier by lazy { getClassifier(treePath, javac) } -+ -+ override val canonicalText -+ get() = (classifier as? JavaClass)?.fqName?.asString() ?: treePath.leaf.toString() -+ -+ override val presentableText -+ get() = canonicalText -+ -+ private val typeParameter by lazy { -+ treePath.filter { it is JCTree.JCClassDecl || it is JCTree.JCMethodDecl } -+ .flatMap { -+ when (it) { -+ is JCTree.JCClassDecl -> it.typarams -+ is JCTree.JCMethodDecl -> it.typarams -+ else -> emptyList>() -+ } -+ } -+ .find { it.toString().substringBefore("" "") == treePath.leaf.toString() } -+ } -+ -+} -+ -+class JCClassifierType(tree: T, -+ treePath: TreePath, -+ javac: Javac) : ClassifierType(tree, treePath, javac) { -+ -+ override val typeArguments: List -+ get() = emptyList() -+ -+ override val isRaw: Boolean -+ get() = (classifier as? JavaClass)?.typeParameters?.isNotEmpty() ?: false -+ -+} -+ -+class JCClassifierTypeWithTypeArgument(tree: T, -+ treePath: TreePath, -+ javac: Javac) : ClassifierType(tree, treePath, javac) { -+ -+ override val typeArguments: List -+ get() = tree.arguments.map { create(it, treePath, javac) } -+ -+ override val isRaw: Boolean -+ get() = false -+ -+} -+ -+private fun getClassifier(treePath: TreePath, javac: Javac) = treePath.resolve(javac).let { -+ it.second -+ ?: stubs[it.first] -+ ?: typeParameter(treePath, javac) -+ ?: createStubClassifier(it.first) -+} -+ -+private fun typeParameter(treePath: TreePath, javac: Javac) = treePath -+ .filter { it is JCTree.JCClassDecl || it is JCTree.JCMethodDecl } -+ .flatMap { -+ when (it) { -+ is JCTree.JCClassDecl -> it.typarams -+ is JCTree.JCMethodDecl -> it.typarams -+ else -> emptyList() -+ } -+ } -+ .find { it.toString().substringBefore("" "") == treePath.leaf.toString() } -+ ?.let { JCTypeParameter(it, -+ javac.getTreePath(it, treePath.compilationUnit), -+ javac) -+ } -+ -+private val stubs = hashMapOf()","Is it true we have some stub cache here? If yes, consider creating some class / object and integrate both `stubs` and `createStubClassifier` inside. I do not like mutable global properties, even private.",Please put this on one line. -124,"@@ -0,0 +1,169 @@ -+# Annotation Options -+ -+Goals: -+* Support annotation options, such as retention policy and targeting -+ -+See [related discussion about Scala](http://lampwww.epfl.ch/~mihaylov/attributes.html). -+ -+## Discussion -+ -+For each option of annotations there's a general dichotomy of how it can be specified in code. -+ -+Option 0: Separate annotations -+ -+``` kotlin -+retention(SOURCE) -+target(CLASSIFIER, FIELD) -+annotation class example -+``` -+ -+Option 1: Make `annotation` into an annotation, and use its properties -+ -+``` kotlin -+annotation( -+ retention = SOURCE, -+ targets = array(CLASSIFIER, FIELD) -+) -+class example -+``` -+ -+A variation of this is -+ -+``` kotlin -+annotation(target(CLASSIFIER, FIELD), retention = SOURCE) class example -+``` -+ -+Annotations can be parameters to other annotations. -+ -+Having option as separate annotation is what Java has and seems more extensible, although it actually isn't (adding new parameters to one annotation is no better or worse than adding new annotation recognized by the compiler). -+ -+Having those as parameters is more discoverable, but has some syntactic shortcomings: no varargs can be used. -+ -+## Targeting -+ -+To check applicability, we can use the following constants: -+ -+| Kotlin constant | Java constant | -+|-----------------|---------------| -+| PACKAGE | \ | -+| CLASSIFIER | TYPE | -+| ANNOTATION_CLASS | ANNOTATION_TYPE | -+| TYPE_PARAMETER | \ -+| PROPERTY | \ | -+| FIELD | \ -+| LOCAL_VARIABLE | \ | -+| VALUE_PARAMETER | PARAMETER | -+| CONSTRUCTOR | \ | -+| FUNCITON | METHOD | -+| PROPERTY_GETTER | METHOD | -+| PROPERTY_SETTER | METHOD | -+| TYPE | TYPE_USE |","Is it ok that it called the same as other Java constant? Can it mislead? -","This isn't true. `retention` is an object, not a string." -125,"@@ -0,0 +1,169 @@ -+# Annotation Options -+ -+Goals: -+* Support annotation options, such as retention policy and targeting -+ -+See [related discussion about Scala](http://lampwww.epfl.ch/~mihaylov/attributes.html). -+ -+## Discussion -+ -+For each option of annotations there's a general dichotomy of how it can be specified in code. -+ -+Option 0: Separate annotations -+ -+``` kotlin -+retention(SOURCE) -+target(CLASSIFIER, FIELD) -+annotation class example -+``` -+ -+Option 1: Make `annotation` into an annotation, and use its properties -+ -+``` kotlin -+annotation( -+ retention = SOURCE, -+ targets = array(CLASSIFIER, FIELD) -+) -+class example -+``` -+ -+A variation of this is -+ -+``` kotlin -+annotation(target(CLASSIFIER, FIELD), retention = SOURCE) class example -+``` -+ -+Annotations can be parameters to other annotations. -+ -+Having option as separate annotation is what Java has and seems more extensible, although it actually isn't (adding new parameters to one annotation is no better or worse than adding new annotation recognized by the compiler). -+ -+Having those as parameters is more discoverable, but has some syntactic shortcomings: no varargs can be used. -+ -+## Targeting -+ -+To check applicability, we can use the following constants: -+ -+| Kotlin constant | Java constant | -+|-----------------|---------------| -+| PACKAGE | \ | -+| CLASSIFIER | TYPE | -+| ANNOTATION_CLASS | ANNOTATION_TYPE | -+| TYPE_PARAMETER | \ -+| PROPERTY | \ | -+| FIELD | \ -+| LOCAL_VARIABLE | \ | -+| VALUE_PARAMETER | PARAMETER | -+| CONSTRUCTOR | \ | -+| FUNCITON | METHOD | -+| PROPERTY_GETTER | METHOD | -+| PROPERTY_SETTER | METHOD | -+| TYPE | TYPE_USE | -+| EXPRESSION | \ | -+","What about a file as target? -",This isn't true. `retention` is an array. -126,"@@ -0,0 +1,169 @@ -+# Annotation Options -+ -+Goals: -+* Support annotation options, such as retention policy and trageting","Typo: trageting -> targeting -",I think we should add a note that these options are not supported by Pr -127,"@@ -0,0 +1,169 @@ -+# Annotation Options -+ -+Goals: -+* Support annotation options, such as retention policy and trageting -+ -+See [related discussion about Scala](http://lampwww.epfl.ch/~mihaylov/attributes.html). -+ -+## Discussion -+ -+For each option of annotations there's a general dichotomy of how it can be specified in code. -+ -+Option 0: Separate annotations -+ -+``` kotlin -+retention(SOURCE) -+target(CLASSIFIER, FIELD) -+annotation class example -+``` -+ -+Option 1: Make `annotation` into an annotation, and use its properties -+ -+``` kotlin -+annotation( -+ retention = SOURCE, -+ targets = array(CLASSIFIER, FIELD) -+) -+class example -+``` -+ -+A variation of this is -+ -+``` kotlin -+annotation(target(CLASSIFIER, FIELD), retention = SOURCE) class example -+``` -+ -+Annotations can be parameters to other annotations. -+ -+Having option as separate annotation is what Java has and seems more extensible, although it actually isn't (adding new parameters to one annotation is no better or worse than adding new annotation recognized by the compiler). -+ -+Having those as parameters is more discoverable, but has some syntactic shortcomings: no varargs can be used. -+ -+## Targeting -+ -+To check applicability, we can use the following constants: -+ -+| Kotlin constant | Java constant | -+|-----------------|---------------| -+| PACKAGE | \ | -+| CLASSIFIER | TYPE | -+| ANNOTATION_CLASS | ANNOTATION_TYPE | -+| TYPE_PARAMETER | \ -+| PROPERTY | \ | -+| FIELD | \ -+| LOCAL_VARIABLE | \ | -+| VALUE_PARAMETER | PARAMETER | -+| CONSTRUCTOR | \ | -+| FUNCITON | METHOD | -+| PROPERTY_GETTER | METHOD | -+| PROPERTY_SETTER | METHOD | -+| TYPE | TYPE_USE | -+| EXPRESSION | \ | -+ -+Putting an annotation on an element that is not allowed by the specified target is a compile-time error. -+No targets specified means that all targets are accepted. -+ -+> NOTE: Java has the following [targets](https://docs.oracle.com/javase/8/docs/api/java/lang/annotation/ElementType.html): -+ -+ -+**TODO** Open question: what about traits/classes/objects? -+**TODO** local variables are just like properties, but local -+ -+> Possbile platform-specific targets","Typo: Possbile -> Possible -","This isn't true. `retention` is an object, not a string." -128,"@@ -0,0 +1,169 @@ -+# Annotation Options -+ -+Goals: -+* Support annotation options, such as retention policy and trageting -+ -+See [related discussion about Scala](http://lampwww.epfl.ch/~mihaylov/attributes.html). -+ -+## Discussion -+ -+For each option of annotations there's a general dichotomy of how it can be specified in code. -+ -+Option 0: Separate annotations -+ -+``` kotlin -+retention(SOURCE) -+target(CLASSIFIER, FIELD) -+annotation class example -+``` -+ -+Option 1: Make `annotation` into an annotation, and use its properties -+ -+``` kotlin -+annotation( -+ retention = SOURCE, -+ targets = array(CLASSIFIER, FIELD) -+) -+class example -+``` -+ -+A variation of this is -+ -+``` kotlin -+annotation(target(CLASSIFIER, FIELD), retention = SOURCE) class example -+``` -+ -+Annotations can be parameters to other annotations. -+ -+Having option as separate annotation is what Java has and seems more extensible, although it actually isn't (adding new parameters to one annotation is no better or worse than adding new annotation recognized by the compiler). -+ -+Having those as parameters is more discoverable, but has some syntactic shortcomings: no varargs can be used. -+ -+## Targeting -+ -+To check applicability, we can use the following constants: -+ -+| Kotlin constant | Java constant | -+|-----------------|---------------| -+| PACKAGE | \ | -+| CLASSIFIER | TYPE | -+| ANNOTATION_CLASS | ANNOTATION_TYPE | -+| TYPE_PARAMETER | \ -+| PROPERTY | \ | -+| FIELD | \ -+| LOCAL_VARIABLE | \ | -+| VALUE_PARAMETER | PARAMETER | -+| CONSTRUCTOR | \ | -+| FUNCITON | METHOD | -+| PROPERTY_GETTER | METHOD | -+| PROPERTY_SETTER | METHOD | -+| TYPE | TYPE_USE | -+| EXPRESSION | \ | -+ -+Putting an annotation on an element that is not allowed by the specified target is a compile-time error. -+No targets specified means that all targets are accepted. -+ -+> NOTE: Java has the following [targets](https://docs.oracle.com/javase/8/docs/api/java/lang/annotation/ElementType.html): -+ -+ -+**TODO** Open question: what about traits/classes/objects? -+**TODO** local variables are just like properties, but local -+ -+> Possbile platform-specific targets -+* SINGLETON_FIELD for objects -+* PROPERTY_FIELD -+* (?) DEFAULT_FUNCTION -+* (?) LAMBDA_METHOD -+* PACKAGE_FACADE -+* PACKAGE_PART -+ -+### Mapping onto Java -+ -+Kotlin has more possible targets than Java, so there's an issue of mapping back and forth. The table above give a correspondence.","give -> gives -","This isn't true. `retention` is an object, not a string." -129,"@@ -0,0 +1,169 @@ -+# Annotation Options -+ -+Goals: -+* Support annotation options, such as retention policy and trageting -+ -+See [related discussion about Scala](http://lampwww.epfl.ch/~mihaylov/attributes.html). -+ -+## Discussion -+ -+For each option of annotations there's a general dichotomy of how it can be specified in code. -+ -+Option 0: Separate annotations -+ -+``` kotlin -+retention(SOURCE) -+target(CLASSIFIER, FIELD) -+annotation class example -+``` -+ -+Option 1: Make `annotation` into an annotation, and use its properties -+ -+``` kotlin -+annotation( -+ retention = SOURCE, -+ targets = array(CLASSIFIER, FIELD) -+) -+class example -+``` -+ -+A variation of this is -+ -+``` kotlin -+annotation(target(CLASSIFIER, FIELD), retention = SOURCE) class example -+``` -+ -+Annotations can be parameters to other annotations. -+ -+Having option as separate annotation is what Java has and seems more extensible, although it actually isn't (adding new parameters to one annotation is no better or worse than adding new annotation recognized by the compiler). -+ -+Having those as parameters is more discoverable, but has some syntactic shortcomings: no varargs can be used. -+ -+## Targeting -+ -+To check applicability, we can use the following constants: -+ -+| Kotlin constant | Java constant | -+|-----------------|---------------| -+| PACKAGE | \ | -+| CLASSIFIER | TYPE | -+| ANNOTATION_CLASS | ANNOTATION_TYPE | -+| TYPE_PARAMETER | \ -+| PROPERTY | \ | -+| FIELD | \ -+| LOCAL_VARIABLE | \ | -+| VALUE_PARAMETER | PARAMETER | -+| CONSTRUCTOR | \ | -+| FUNCITON | METHOD | -+| PROPERTY_GETTER | METHOD | -+| PROPERTY_SETTER | METHOD | -+| TYPE | TYPE_USE | -+| EXPRESSION | \ | -+ -+Putting an annotation on an element that is not allowed by the specified target is a compile-time error. -+No targets specified means that all targets are accepted. -+ -+> NOTE: Java has the following [targets](https://docs.oracle.com/javase/8/docs/api/java/lang/annotation/ElementType.html): -+ -+ -+**TODO** Open question: what about traits/classes/objects? -+**TODO** local variables are just like properties, but local -+ -+> Possbile platform-specific targets -+* SINGLETON_FIELD for objects -+* PROPERTY_FIELD -+* (?) DEFAULT_FUNCTION -+* (?) LAMBDA_METHOD -+* PACKAGE_FACADE -+* PACKAGE_PART -+ -+### Mapping onto Java -+ -+Kotlin has more possible targets than Java, so there's an issue of mapping back and forth. The table above give a correspondence. -+ -+When we compile a Kotlin class to Java, we write a `@java.lang.annotation.Target` annotation that reflects the targets. For targets having no correspondent ones in Java (e.g. `EXPRESSION`) nothing is written to `j.l.a.Target`. If the set of Java targets is empy, `j.l.a.Target` is not written to the class file. -+ -+In addition to `java.lang.annotation.Target`, a Kotlin-specific annotation `kotlin.target` is written containing all the Kotlin targets listed: -+ -+``` kotlin -+package kotlin -+ -+enum class AnnotationTarget { -+ PACKAGE -+ ... -+} -+ -+target(ANNOTATION_CLASS) -+annotation(RUNTIME) class target(vararg targets: AnnotationTarget) -+``` -+ -+When loading an annotation, we only read `kotlin.target`. When `kotlin.target` is missing, on the JVM, we read `j.l.a.Target` and map its values to Kotlin ones according to the table above. This implies that we can load pure Java annotations that know nothing about Kotlin, and that an annotation written in Java can be targeted, e.g. for Kotlin expressions, because one can simply manually specify `kotlin.target` for it. -+ -+### Syntax -+ -+It makes sense to use `kotlin.target` explicitly in Kotlin code: -+ -+``` kotlin -+target(EXPRESSION, TYPE) -+annotation class MyAnn -+``` -+ -+> An alternative would be to make target a aproperty of `kotlin.annotation`, but then we'd","aproperty -> property -","This isn't true. `retention` is an object, not a string." -130,"@@ -0,0 +1,169 @@ -+# Annotation Options -+ -+Goals: -+* Support annotation options, such as retention policy and trageting -+ -+See [related discussion about Scala](http://lampwww.epfl.ch/~mihaylov/attributes.html). -+ -+## Discussion -+ -+For each option of annotations there's a general dichotomy of how it can be specified in code. -+ -+Option 0: Separate annotations -+ -+``` kotlin -+retention(SOURCE) -+target(CLASSIFIER, FIELD) -+annotation class example -+``` -+ -+Option 1: Make `annotation` into an annotation, and use its properties -+ -+``` kotlin -+annotation( -+ retention = SOURCE, -+ targets = array(CLASSIFIER, FIELD) -+) -+class example -+``` -+ -+A variation of this is -+ -+``` kotlin -+annotation(target(CLASSIFIER, FIELD), retention = SOURCE) class example -+``` -+ -+Annotations can be parameters to other annotations. -+ -+Having option as separate annotation is what Java has and seems more extensible, although it actually isn't (adding new parameters to one annotation is no better or worse than adding new annotation recognized by the compiler). -+ -+Having those as parameters is more discoverable, but has some syntactic shortcomings: no varargs can be used. -+ -+## Targeting -+ -+To check applicability, we can use the following constants: -+ -+| Kotlin constant | Java constant | -+|-----------------|---------------| -+| PACKAGE | \ | -+| CLASSIFIER | TYPE | -+| ANNOTATION_CLASS | ANNOTATION_TYPE | -+| TYPE_PARAMETER | \ -+| PROPERTY | \ | -+| FIELD | \ -+| LOCAL_VARIABLE | \ | -+| VALUE_PARAMETER | PARAMETER | -+| CONSTRUCTOR | \ | -+| FUNCITON | METHOD | -+| PROPERTY_GETTER | METHOD | -+| PROPERTY_SETTER | METHOD | -+| TYPE | TYPE_USE | -+| EXPRESSION | \ | -+ -+Putting an annotation on an element that is not allowed by the specified target is a compile-time error. -+No targets specified means that all targets are accepted. -+ -+> NOTE: Java has the following [targets](https://docs.oracle.com/javase/8/docs/api/java/lang/annotation/ElementType.html): -+ -+ -+**TODO** Open question: what about traits/classes/objects? -+**TODO** local variables are just like properties, but local -+ -+> Possbile platform-specific targets -+* SINGLETON_FIELD for objects -+* PROPERTY_FIELD -+* (?) DEFAULT_FUNCTION -+* (?) LAMBDA_METHOD -+* PACKAGE_FACADE -+* PACKAGE_PART -+ -+### Mapping onto Java -+ -+Kotlin has more possible targets than Java, so there's an issue of mapping back and forth. The table above give a correspondence. -+ -+When we compile a Kotlin class to Java, we write a `@java.lang.annotation.Target` annotation that reflects the targets. For targets having no correspondent ones in Java (e.g. `EXPRESSION`) nothing is written to `j.l.a.Target`. If the set of Java targets is empy, `j.l.a.Target` is not written to the class file. -+ -+In addition to `java.lang.annotation.Target`, a Kotlin-specific annotation `kotlin.target` is written containing all the Kotlin targets listed: -+ -+``` kotlin -+package kotlin -+ -+enum class AnnotationTarget { -+ PACKAGE -+ ... -+} -+ -+target(ANNOTATION_CLASS) -+annotation(RUNTIME) class target(vararg targets: AnnotationTarget) -+``` -+ -+When loading an annotation, we only read `kotlin.target`. When `kotlin.target` is missing, on the JVM, we read `j.l.a.Target` and map its values to Kotlin ones according to the table above. This implies that we can load pure Java annotations that know nothing about Kotlin, and that an annotation written in Java can be targeted, e.g. for Kotlin expressions, because one can simply manually specify `kotlin.target` for it. -+ -+### Syntax -+ -+It makes sense to use `kotlin.target` explicitly in Kotlin code: -+ -+``` kotlin -+target(EXPRESSION, TYPE) -+annotation class MyAnn -+``` -+ -+> An alternative would be to make target a aproperty of `kotlin.annotation`, but then we'd -+* lose the advantage of varargs, because there are more optional parameters -+* be non-uniform with Java, thus making it harder to figure how to make a Java annotation Kotlin-friendly -+ -+## Retention -+ -+> NOTE: Retention is a Java-specific concern, more or less. CLR retains all attributes at runtime, and JS too -+ -+It makes a lot of sense to make `RUNTIME` the default retention. -+ -+Since `RetentionPolicy.CLASS` is not a good fit for Kotlin that has functions outside any class, it's better to have `BINARY` instead. Also, we could have use `java.lang.annotation.RetentionPolicy` anyways, since it's platform-specific. Thus, we need to have our own enum: -+","could have use -> could not use (?) -","This isn't true. `retention` is an object, not a string." -131,"@@ -0,0 +1,169 @@ -+# Annotation Options -+ -+Goals: -+* Support annotation options, such as retention policy and trageting -+ -+See [related discussion about Scala](http://lampwww.epfl.ch/~mihaylov/attributes.html). -+ -+## Discussion -+ -+For each option of annotations there's a general dichotomy of how it can be specified in code. -+ -+Option 0: Separate annotations -+ -+``` kotlin -+retention(SOURCE) -+target(CLASSIFIER, FIELD) -+annotation class example -+``` -+ -+Option 1: Make `annotation` into an annotation, and use its properties -+ -+``` kotlin -+annotation( -+ retention = SOURCE, -+ targets = array(CLASSIFIER, FIELD) -+) -+class example -+``` -+ -+A variation of this is -+ -+``` kotlin -+annotation(target(CLASSIFIER, FIELD), retention = SOURCE) class example -+``` -+ -+Annotations can be parameters to other annotations. -+ -+Having option as separate annotation is what Java has and seems more extensible, although it actually isn't (adding new parameters to one annotation is no better or worse than adding new annotation recognized by the compiler). -+ -+Having those as parameters is more discoverable, but has some syntactic shortcomings: no varargs can be used. -+ -+## Targeting -+ -+To check applicability, we can use the following constants: -+ -+| Kotlin constant | Java constant | -+|-----------------|---------------| -+| PACKAGE | \ | -+| CLASSIFIER | TYPE | -+| ANNOTATION_CLASS | ANNOTATION_TYPE | -+| TYPE_PARAMETER | \ -+| PROPERTY | \ | -+| FIELD | \ -+| LOCAL_VARIABLE | \ | -+| VALUE_PARAMETER | PARAMETER | -+| CONSTRUCTOR | \ | -+| FUNCITON | METHOD | -+| PROPERTY_GETTER | METHOD | -+| PROPERTY_SETTER | METHOD | -+| TYPE | TYPE_USE | -+| EXPRESSION | \ | -+ -+Putting an annotation on an element that is not allowed by the specified target is a compile-time error. -+No targets specified means that all targets are accepted. -+ -+> NOTE: Java has the following [targets](https://docs.oracle.com/javase/8/docs/api/java/lang/annotation/ElementType.html): -+ -+ -+**TODO** Open question: what about traits/classes/objects? -+**TODO** local variables are just like properties, but local -+ -+> Possbile platform-specific targets -+* SINGLETON_FIELD for objects -+* PROPERTY_FIELD -+* (?) DEFAULT_FUNCTION -+* (?) LAMBDA_METHOD -+* PACKAGE_FACADE -+* PACKAGE_PART -+ -+### Mapping onto Java -+ -+Kotlin has more possible targets than Java, so there's an issue of mapping back and forth. The table above give a correspondence. -+ -+When we compile a Kotlin class to Java, we write a `@java.lang.annotation.Target` annotation that reflects the targets. For targets having no correspondent ones in Java (e.g. `EXPRESSION`) nothing is written to `j.l.a.Target`. If the set of Java targets is empy, `j.l.a.Target` is not written to the class file. -+ -+In addition to `java.lang.annotation.Target`, a Kotlin-specific annotation `kotlin.target` is written containing all the Kotlin targets listed: -+ -+``` kotlin -+package kotlin -+ -+enum class AnnotationTarget { -+ PACKAGE -+ ... -+} -+ -+target(ANNOTATION_CLASS) -+annotation(RUNTIME) class target(vararg targets: AnnotationTarget) -+``` -+ -+When loading an annotation, we only read `kotlin.target`. When `kotlin.target` is missing, on the JVM, we read `j.l.a.Target` and map its values to Kotlin ones according to the table above. This implies that we can load pure Java annotations that know nothing about Kotlin, and that an annotation written in Java can be targeted, e.g. for Kotlin expressions, because one can simply manually specify `kotlin.target` for it. -+ -+### Syntax -+ -+It makes sense to use `kotlin.target` explicitly in Kotlin code: -+ -+``` kotlin -+target(EXPRESSION, TYPE) -+annotation class MyAnn -+``` -+ -+> An alternative would be to make target a aproperty of `kotlin.annotation`, but then we'd -+* lose the advantage of varargs, because there are more optional parameters -+* be non-uniform with Java, thus making it harder to figure how to make a Java annotation Kotlin-friendly -+ -+## Retention -+ -+> NOTE: Retention is a Java-specific concern, more or less. CLR retains all attributes at runtime, and JS too -+ -+It makes a lot of sense to make `RUNTIME` the default retention. -+ -+Since `RetentionPolicy.CLASS` is not a good fit for Kotlin that has functions outside any class, it's better to have `BINARY` instead. Also, we could have use `java.lang.annotation.RetentionPolicy` anyways, since it's platform-specific. Thus, we need to have our own enum: -+ -+``` kotlin -+package kotlin -+ -+enum class AnnotationRetention { -+ SOURCE -+ BINARY -+ RUNTIME -+} -+``` -+ -+> Now, we could map `java.lang.annotation.Retention` and `RetentionPolicy` to `kotlin.retention` and `kotlin.AnnotationRetention`, and then map `CLASS` to `BINARY`, but that is a little too much -+ -+Then, it makes sense to make `retention` a property of `kotlin.annotation`: -+ -+``` kotlin -+target(TYPE) -+annotation(SOURCE) class MyAnn -+``` -+ -+The following checks must be performed at compile time: -+* `EXPRESSION`-targeted annotations can only have retention `SOURCE` -+ -+## Repeatable -+ -+> Java has `Repeatable` as an annotation, but we cannot map a Kotlin type to it, because it is only present since JDK 8, and cannot be written to class files with version lower than 8. -+ -+We make `repeatable` a boolean property of `kotlin.annotation`, with default value `false` (as in Java and C#). -+ -+If a non-repeatable annotation is used multiple times on the same element, it is a compile-time error. -+ -+If a repeatable annotation is used multiple times on the same element, but the target byte code version is lower than Java 8, it is a compile-time error. -+ -+## Inherited and Documented -+ -+These two options have ratehr unclear value, and we do not supprt them in Kotlin. One can use platform-specific annotations to express them. -+ -+## Appendix. Definition of kotlin.annotation -+ -+``` kotlin -+package kotlin -+ -+target(CLASSIFIER)","Should it be `ANNOTATION_CLASS`? -","This isn't true. `retention` is an object, not a string." -132,"@@ -0,0 +1,17 @@ -+// !DIAGNOSTICS: -UNUSED_PARAMETER -+class C { -+ [kotlin.jvm.overloads] private fun foo(s: String = ""OK"") { -+ } -+} -+ -+fun foo() { -+ class D { -+ [kotlin.jvm.overloads] fun foo(s: String = ""OK"") { -+ } -+ } -+ -+ val x = object { -+ [kotlin.jvm.overloads] fun foo(s: String = ""OK"") { -+ } -+ } -+}","Please also add an `internal` member with `overloads` here, to ensure the warning is not reported on it -",Shouldn't this be `-UNUSED_PARAMETER`? -133,"@@ -0,0 +1,17 @@ -+package test -+open class Foo() { -+open fun execute() : Unit { -+} -+} -+open class Bar() { -+var fooNotNull : Foo = Foo() -+var fooNullable : Foo? = null -+} -+open class Test() { -+public open fun test(barNotNull : Bar, barNullable : Bar?) : Unit { -+barNotNull.fooNotNull.execute() -+barNotNull.fooNullable?.execute() -+barNullable?.fooNotNull?.execute() -+barNullable?.fooNullable?.execute() -+} -+} -\ No newline at end of file","Please fix code formatting in this test -",missing new line at the end of file -134,"@@ -0,0 +1,181 @@ -+/* -+ * 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.wrappers.trees -+ -+import com.sun.source.tree.Tree -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.tree.JCTree -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.java.structure.JavaClassifier -+import org.jetbrains.kotlin.name.FqName -+ -+class TreePathResolverCache(private val javac: JavacWrapper) { -+ -+ private val cache = hashMapOf() -+ -+ fun resolve(treePath: TreePath): JavaClassifier? = with(treePath) { -+ if (cache.containsKey(leaf)) return cache[leaf] -+ -+ return tryToGetClassifier().apply { cache[leaf] = this } -+ } -+ -+ private fun TreePath.tryToGetClassifier(): JavaClassifier? { -+ val name = leaf.toString().substringBefore(""<"").substringAfter(""@"") -+ val nameParts = name.split(""."") -+ -+ with(compilationUnit as JCTree.JCCompilationUnit) { -+ tryToResolveInner(name, javac, nameParts)?.let { return it } -+ tryToResolvePackageClass(name, javac, nameParts)?.let { return it } -+ tryToResolveByFqName(name, javac)?.let { return it } -+ tryToResolveSingleTypeImport(name, javac, nameParts)?.let { return it } -+ tryToResolveTypeImportOnDemand(name, javac, nameParts)?.let { return it } -+ tryToResolveInJavaLang(name, javac)?.let { return it } -+ } -+ -+ return tryToResolveTypeParameter(javac) -+ } -+ -+ private fun TreePath.tryToResolveInner(name: String, -+ javac: JavacWrapper, -+ nameParts: List = emptyList()): JavaClass? = findEnclosingClasses(javac) -+ ?.forEach { -+ it.findInner(name, javac, nameParts)?.let { return it } -+ }.let { return null } -+ -+ private fun TreePath.findEnclosingClasses(javac: JavacWrapper) = filterIsInstance() -+ .filter { it.extending != leaf && !it.implementing.contains(leaf) } -+ .reversed() -+ .joinToString(separator = ""."", prefix = ""${compilationUnit.packageName}."") { it.simpleName } -+ .let { javac.findClass(FqName(it)) } -+ ?.let { -+ arrayListOf(it).apply { -+ var enclosingClass = it.outerClass -+ while (enclosingClass != null) { -+ add(enclosingClass) -+ enclosingClass = enclosingClass.outerClass -+ } -+ } -+ } -+ -+ private fun JCTree.JCCompilationUnit.tryToResolveSingleTypeImport(name: String, -+ javac: JavacWrapper, -+ nameParts: List = emptyList()): JavaClass? { -+ nameParts.size -+ .takeIf { it > 1 } -+ ?.let { -+ imports.filter { it.qualifiedIdentifier.toString().endsWith("".${nameParts.first()}"") } -+ .forEach { find(FqName(""${it.qualifiedIdentifier}""), javac, nameParts)?.let { return it } } -+ .let { return null } -+ } -+ -+ return imports -+ .find { it.qualifiedIdentifier.toString().endsWith("".$name"") } -+ ?.let { -+ FqName(it.qualifiedIdentifier.toString()) -+ .let { javac.findClass(it) ?: javac.getKotlinClassifier(it) } -+ } -+ } -+ -+ private fun JCTree.JCCompilationUnit.tryToResolvePackageClass(name: String, -+ javac: JavacWrapper, -+ nameParts: List = emptyList()): JavaClass? { -+ return nameParts.size -+ .takeIf { it > 1 } -+ ?.let { -+ find(FqName(""$packageName.${nameParts.first()}""), javac, nameParts) -+ } ?: javac.findClass(FqName(""$packageName.$name"")) ?: javac.getKotlinClassifier(FqName(""$packageName.$name"")) -+ } -+ -+ private fun JCTree.JCCompilationUnit.tryToResolveTypeImportOnDemand(name: String, -+ javac: JavacWrapper, -+ nameParts: List = emptyList()): JavaClass? { -+ with(imports.filter { it.qualifiedIdentifier.toString().endsWith(""*"") }) { -+ nameParts.size -+ .takeIf { it > 1 } -+ ?.let { -+ forEach { pack -> -+ find(FqName(""${pack.qualifiedIdentifier.toString().substringBefore(""*"")}${nameParts.first()}""), javac, nameParts) -+ ?.let { return it } -+ }.let { return null } -+ } -+ -+ forEach { -+ val fqName = ""${it.qualifiedIdentifier.toString().substringBefore(""*"")}$name"".let(::FqName) -+ (javac.findClass(fqName) ?: javac.getKotlinClassifier(fqName))?.let { return it } -+ }.let { return null } -+ } -+ } -+ -+ private fun TreePath.tryToResolveTypeParameter(javac: JavacWrapper) = -+ filter { it is JCTree.JCClassDecl || it is JCTree.JCMethodDecl }",This `filter` is not needed,Move this to `TreePathResolver` in order to use it in th -135,"@@ -0,0 +1,183 @@ -+/* -+ * 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.rmi -+ -+import java.io.File -+import java.io.Serializable -+import java.security.DigestInputStream -+import java.security.MessageDigest -+import kotlin.platform.platformStatic -+import kotlin.reflect.KMutableProperty1 -+import kotlin.reflect.KProperty1 -+ -+ -+public val COMPILER_JAR_NAME: String = ""kotlin-compiler.jar"" -+public val COMPILER_SERVICE_RMI_NAME: String = ""KotlinJvmCompilerService"" -+public val COMPILER_DAEMON_CLASS_FQN: String = ""org.jetbrains.kotlin.rmi.service.CompileDaemon"" -+public val COMPILE_DAEMON_DEFAULT_PORT: Int = 17031 -+public val COMPILE_DAEMON_ENABLED_PROPERTY: String =""kotlin.daemon.enabled"" -+public val COMPILE_DAEMON_JVM_OPTIONS_PROPERTY: String =""kotlin.daemon.jvm.options"" -+ -+ -+fun> C.propToParams(p: P, conv: ((v: V) -> String) = { it.toString() } ) = -+ listOf(""--daemon-"" + p.name, conv(p.get(this))) -+ -+open class PropParser>(val dest: C, val prop: P, val parse: (s: String) -> V) { -+ fun apply(s: String) = prop.set(dest, parse(s)) -+} -+ -+class BoolPropParser>(dest: C, prop: P): PropParser(dest, prop, { true }) -+ -+fun Iterable.propParseFilter(parsers: List>) : Iterable { -+ var currentParser: PropParser<*,*,*>? = null -+ return filter { param -> -+ if (currentParser == null) { -+ currentParser = parsers.find { param.equals(""--daemon-"" + it.prop.name) } -+ if (currentParser != null) { -+ if (currentParser is BoolPropParser<*,*>) { -+ currentParser!!.apply("""") -+ currentParser = null -+ } -+ false -+ } -+ else true -+ } -+ else { -+ currentParser!!.apply(param) -+ currentParser = null -+ false -+ } -+ } -+} -+ -+// TODO: find out how to create more generic variant using first constructor -+//fun C.propsToParams() { -+// val kc = C::class -+// kc.constructors.first(). -+//} -+ -+public interface CmdlineParams : Serializable { -+ public val asParams: Iterable -+ public val parsers: List> -+} -+ -+public fun Iterable.propParseFilter(vararg cs: CmdlineParams) : Iterable = -+ propParseFilter(cs.flatMap { it.parsers }) -+ -+ -+public data class DaemonLaunchingOptions( -+ public var jvmParams: List = listOf() -+) : CmdlineParams { -+ -+ override val asParams: Iterable -+ get() = -+ propToParams(::jvmParams, { it.joinToString(""##"") }) // TODO: consider some other options rather than using potentially dangerous delimiter -+ -+ override val parsers: List> -+ get() = listOf( PropParser(this, ::jvmParams, { it.split(""##"")})) // TODO: see appropriate comment in asParams -+} -+ -+public data class DaemonOptions( -+ public var port: Int = COMPILE_DAEMON_DEFAULT_PORT, -+ public var autoshutdownMemoryThreshold: Long = 0 /* 0 means unchecked */, -+ public var autoshutdownIdleSeconds: Int = 0 /* 0 means unchecked */, -+ public var startEcho: String = COMPILER_SERVICE_RMI_NAME -+) : CmdlineParams { -+ -+ override val asParams: Iterable -+ get() = -+ propToParams(::port) + -+ propToParams(::autoshutdownMemoryThreshold) + -+ propToParams(::autoshutdownIdleSeconds) + -+ propToParams(::startEcho) -+ -+ override val parsers: List> -+ get() = listOf( PropParser(this, ::port, { it.toInt()}), -+ PropParser(this, ::autoshutdownMemoryThreshold, { it.toLong()}), -+ PropParser(this, ::autoshutdownIdleSeconds, { it.toInt()}), -+ PropParser(this, ::startEcho, { it.trim('""') })) -+} -+ -+ -+val COMPILER_ID_DIGEST = ""MD5"" -+ -+ -+fun updateSingleFileDigest(file: File, md: MessageDigest) { -+ val stream = DigestInputStream(file.inputStream(), md) -+ val buf = ByteArray(1024) -+ while (stream.read(buf) == buf.size()) {}","It is not guaranteed that the `read` operation reads the same amount of bytes as buffer can contain and it even may read zero bytes even if the file pointer is not at the end -",Maybe use a more descriptive name? `kotlin.rmi.service.C -136,"@@ -0,0 +1,183 @@ -+/* -+ * 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.rmi -+ -+import java.io.File -+import java.io.Serializable -+import java.security.DigestInputStream -+import java.security.MessageDigest -+import kotlin.platform.platformStatic -+import kotlin.reflect.KMutableProperty1 -+import kotlin.reflect.KProperty1 -+ -+ -+public val COMPILER_JAR_NAME: String = ""kotlin-compiler.jar"" -+public val COMPILER_SERVICE_RMI_NAME: String = ""KotlinJvmCompilerService"" -+public val COMPILER_DAEMON_CLASS_FQN: String = ""org.jetbrains.kotlin.rmi.service.CompileDaemon"" -+public val COMPILE_DAEMON_DEFAULT_PORT: Int = 17031 -+public val COMPILE_DAEMON_ENABLED_PROPERTY: String =""kotlin.daemon.enabled"" -+public val COMPILE_DAEMON_JVM_OPTIONS_PROPERTY: String =""kotlin.daemon.jvm.options"" -+ -+ -+fun> C.propToParams(p: P, conv: ((v: V) -> String) = { it.toString() } ) = -+ listOf(""--daemon-"" + p.name, conv(p.get(this))) -+ -+open class PropParser>(val dest: C, val prop: P, val parse: (s: String) -> V) { -+ fun apply(s: String) = prop.set(dest, parse(s)) -+} -+ -+class BoolPropParser>(dest: C, prop: P): PropParser(dest, prop, { true }) -+ -+fun Iterable.propParseFilter(parsers: List>) : Iterable { -+ var currentParser: PropParser<*,*,*>? = null -+ return filter { param -> -+ if (currentParser == null) { -+ currentParser = parsers.find { param.equals(""--daemon-"" + it.prop.name) } -+ if (currentParser != null) { -+ if (currentParser is BoolPropParser<*,*>) { -+ currentParser!!.apply("""") -+ currentParser = null -+ } -+ false -+ } -+ else true -+ } -+ else { -+ currentParser!!.apply(param) -+ currentParser = null -+ false -+ } -+ } -+} -+ -+// TODO: find out how to create more generic variant using first constructor -+//fun C.propsToParams() { -+// val kc = C::class -+// kc.constructors.first(). -+//} -+ -+public interface CmdlineParams : Serializable { -+ public val asParams: Iterable -+ public val parsers: List> -+} -+ -+public fun Iterable.propParseFilter(vararg cs: CmdlineParams) : Iterable = -+ propParseFilter(cs.flatMap { it.parsers }) -+ -+ -+public data class DaemonLaunchingOptions( -+ public var jvmParams: List = listOf() -+) : CmdlineParams { -+ -+ override val asParams: Iterable -+ get() = -+ propToParams(::jvmParams, { it.joinToString(""##"") }) // TODO: consider some other options rather than using potentially dangerous delimiter -+ -+ override val parsers: List> -+ get() = listOf( PropParser(this, ::jvmParams, { it.split(""##"")})) // TODO: see appropriate comment in asParams -+} -+ -+public data class DaemonOptions( -+ public var port: Int = COMPILE_DAEMON_DEFAULT_PORT, -+ public var autoshutdownMemoryThreshold: Long = 0 /* 0 means unchecked */, -+ public var autoshutdownIdleSeconds: Int = 0 /* 0 means unchecked */, -+ public var startEcho: String = COMPILER_SERVICE_RMI_NAME -+) : CmdlineParams { -+ -+ override val asParams: Iterable -+ get() = -+ propToParams(::port) + -+ propToParams(::autoshutdownMemoryThreshold) + -+ propToParams(::autoshutdownIdleSeconds) + -+ propToParams(::startEcho) -+ -+ override val parsers: List> -+ get() = listOf( PropParser(this, ::port, { it.toInt()}), -+ PropParser(this, ::autoshutdownMemoryThreshold, { it.toLong()}), -+ PropParser(this, ::autoshutdownIdleSeconds, { it.toInt()}), -+ PropParser(this, ::startEcho, { it.trim('""') })) -+} -+ -+ -+val COMPILER_ID_DIGEST = ""MD5"" -+ -+ -+fun updateSingleFileDigest(file: File, md: MessageDigest) { -+ val stream = DigestInputStream(file.inputStream(), md) -+ val buf = ByteArray(1024) -+ while (stream.read(buf) == buf.size()) {} -+ stream.close()","shouldn't we use [`use` function](http://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/use.html) here: - -``` -DigestInputStream(file.inputStream(), md).use { stream -> - // do stuff -} -``` -",Maybe use a more descriptive name? `kotlin.rmi.service.C -137,"@@ -0,0 +1,185 @@ -+/* -+* Copyright 2010-2014 JetBrains s.r.o. -+* -+* Licensed under the Apache License, Version 2.0 (the ""License""); -+* you may not use this file except in compliance with the License. -+* You may obtain a copy of the License at -+* -+* http://www.apache.org/licenses/LICENSE-2.0 -+* -+* Unless required by applicable law or agreed to in writing, software -+* distributed under the License is distributed on an ""AS IS"" BASIS, -+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+* See the License for the specific language governing permissions and -+* limitations under the License. -+*/ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetPrefixExpression -+import org.jetbrains.jet.lang.psi.JetPostfixExpression -+import org.jetbrains.jet.lang.psi.JetBinaryExpression -+import org.jetbrains.jet.lang.psi.JetArrayAccessExpression -+import org.jetbrains.jet.lang.psi.JetCallExpression -+import org.jetbrains.jet.lexer.JetTokens -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetElement -+import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.resolve.BindingContext -+import org.jetbrains.jet.lang.psi.psiUtil.getQualifiedElementSelector -+ -+public class OperatorToFunctionIntention : JetSelfTargetingIntention(""operator.to.function"", javaClass()) { -+ fun isApplicablePrefix(element: JetPrefixExpression): Boolean { -+ return when (element.getOperationReference().getReferencedNameElementType()) { -+ JetTokens.PLUS, JetTokens.MINUS, JetTokens.PLUSPLUS, JetTokens.MINUSMINUS, JetTokens.EXCL -> true -+ else -> false -+ } -+ } -+ -+ fun isApplicablePostfix(element: JetPostfixExpression): Boolean { -+ return when (element.getOperationReference().getReferencedNameElementType()) { -+ JetTokens.PLUSPLUS, JetTokens.MINUSMINUS -> true -+ else -> false -+ } -+ } -+ -+ fun isApplicableBinary(element: JetBinaryExpression): Boolean { -+ return when (element.getOperationReference().getReferencedNameElementType()) { -+ JetTokens.PLUS, JetTokens.MINUS, JetTokens.MUL, JetTokens.DIV, JetTokens.PERC, JetTokens.RANGE, JetTokens.IN_KEYWORD, JetTokens.NOT_IN, JetTokens.PLUSEQ, JetTokens.MINUSEQ, JetTokens.MULTEQ, JetTokens.DIVEQ, JetTokens.PERCEQ, JetTokens.EQEQ, JetTokens.EXCLEQ, JetTokens.GT, JetTokens.LT, JetTokens.GTEQ, JetTokens.LTEQ -> true -+ JetTokens.EQ -> element.getLeft() is JetArrayAccessExpression -+ else -> false -+ } -+ } -+ -+ fun isApplicableArrayAccess(element: JetArrayAccessExpression): Boolean { -+ return true -+ } -+ -+ fun isApplicableCall(element: JetCallExpression): Boolean { -+ return element.getParent() !is JetDotQualifiedExpression && element.getValueArgumentList() != null -+ } -+ -+ override fun isApplicableTo(element: JetExpression): Boolean { -+ return when (element) { -+ is JetPrefixExpression -> isApplicablePrefix(element) -+ // is JetPostfixExpression -> isApplicablePostfix(element) -+ is JetBinaryExpression -> isApplicableBinary(element) -+ is JetArrayAccessExpression -> isApplicableArrayAccess(element) -+ is JetCallExpression -> isApplicableCall(element) -+ else -> false -+ } -+ } -+ -+ -+ fun convertPrefix(element: JetPrefixExpression) { -+ val op = element.getOperationReference().getReferencedNameElementType() -+ val base = element.getBaseExpression()!!.getText() -+ -+ val call = when (op) { -+ JetTokens.PLUS -> ""plus()"" -+ JetTokens.MINUS -> ""minus()"" -+ JetTokens.PLUSPLUS -> ""inc()"" -+ JetTokens.MINUSMINUS -> ""dec()"" -+ JetTokens.EXCL -> ""not()"" -+ else -> return -+ } -+ -+ val transformation = ""$base.$call"" -+ val transformed = JetPsiFactory.createExpression(element.getProject(), transformation) -+ element.replace(transformed) -+ } -+ -+ fun convertBinary(element: JetBinaryExpression) { -+ val op = element.getOperationReference().getReferencedNameElementType() -+ val left = element.getLeft()!! -+ val right = element.getRight()!! -+ val leftText = left.getText() -+ val rightText = right.getText() -+ -+ if (op == JetTokens.EQ) { -+ if (left is JetArrayAccessExpression) { -+ convertArrayAccess(left as JetArrayAccessExpression) -+ } -+ return -+ } -+ -+ val transformation = when (op) { -+ JetTokens.PLUS -> ""$leftText.plus($rightText)"" -+ JetTokens.MINUS -> ""$leftText.minus($rightText)"" -+ JetTokens.MUL -> ""$leftText.times($rightText)"" -+ JetTokens.DIV -> ""$leftText.div($rightText)"" -+ JetTokens.PERC -> ""$leftText.mod($rightText)"" -+ JetTokens.RANGE -> ""$leftText.rangeTo($rightText)"" -+ JetTokens.IN_KEYWORD -> ""$rightText.contains($leftText)"" -+ JetTokens.NOT_IN -> ""!$rightText.contains($leftText)"" -+ JetTokens.PLUSEQ -> ""$leftText.plusAssign($rightText)"" -+ JetTokens.MINUSEQ -> ""$leftText.minusAssign($rightText)"" -+ JetTokens.MULTEQ -> ""$leftText.timesAssign($rightText)"" -+ JetTokens.DIVEQ -> ""$leftText.divAssign($rightText)"" -+ JetTokens.PERCEQ -> ""$leftText.modAssign($rightText)"" -+ JetTokens.EQEQ -> ""$leftText?.equals($rightText) ?: $rightText.identityEquals(null)"" -+ JetTokens.EXCLEQ -> ""!($leftText?.equals($rightText) ?: $rightText.identityEquals(null))"" -+ JetTokens.GT -> ""$leftText.compareTo($rightText) > 0"" -+ JetTokens.LT -> ""$leftText.compareTo($rightText) < 0"" -+ JetTokens.GTEQ -> ""$leftText.compareTo($rightText) >= 0"" -+ JetTokens.LTEQ -> ""$leftText.compareTo($rightText) <= 0"" -+ else -> return -+ } -+ -+ val transformed = JetPsiFactory.createExpression(element.getProject(), transformation) -+ -+ val newCalleeExpression = left -+ val context = AnalyzerFacadeWithCache.getContextForElement(newCalleeExpression) -+ val functionCandidates = context[BindingContext.AMBIGUOUS_REFERENCE_TARGET, newCalleeExpression]","`functionCandidates` is always null for me here. I think it has to do with me using a the `PsiElement` `left` rather than a `JetElement`. I can't seem to figure out what it is, though. Is there a way to create a `JetElement` from a string? -",missing license header -138,"@@ -0,0 +1,192 @@ -+/* -+ * 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.service -+ -+import org.jetbrains.kotlin.cli.common.CLICompiler -+import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler -+import org.jetbrains.kotlin.config.Services -+import org.jetbrains.kotlin.incremental.components.LookupTracker -+import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache -+import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents -+import org.jetbrains.kotlin.rmi.* -+import org.jetbrains.kotlin.rmi.service.RemoteIncrementalCacheClient -+import org.jetbrains.kotlin.rmi.service.RemoteOutputStreamClient -+import java.io.File -+import java.io.FileNotFoundException -+import java.io.IOException -+import java.io.PrintStream -+import java.net.URLClassLoader -+import java.rmi.registry.Registry -+import java.rmi.server.UnicastRemoteObject -+import java.util.* -+import java.util.concurrent.TimeUnit -+import java.util.concurrent.locks.ReentrantReadWriteLock -+import java.util.jar.Manifest -+import java.util.logging.Logger -+import kotlin.concurrent.read -+import kotlin.concurrent.write -+ -+ -+class CompileServiceImpl>( -+ val registry: Registry, -+ val compiler: Compiler, -+ val selfCompilerId: CompilerId, -+ val daemonOptions: DaemonOptions -+) : CompileService, UnicastRemoteObject() { -+ -+ val log by lazy { Logger.getLogger(""compiler"") } -+ -+ private val rwlock = ReentrantReadWriteLock() -+ private var alive = false -+ -+ // TODO: consider matching compilerId coming from outside with actual one -+// private val selfCompilerId by lazy { -+// CompilerId( -+// compilerClasspath = System.getProperty(""java.class.path"") -+// ?.split(File.pathSeparator) -+// ?.map { File(it) } -+// ?.filter { it.exists() } -+// ?.map { it.absolutePath } -+// ?: listOf(), -+// compilerVersion = loadKotlinVersionFromResource() -+// ) -+// } -+ -+ init { -+ // assuming logically synchronized -+ try { -+ // cleanup for the case of incorrect restart -+ UnicastRemoteObject.unexportObject(this, false) -+ } -+ catch (e: java.rmi.NoSuchObjectException) { -+ // ignoring if object already exported -+ } -+ -+ val stub = UnicastRemoteObject.exportObject(this, 0) as CompileService -+ // TODO: use version-specific name -+ registry.rebind (COMPILER_SERVICE_RMI_NAME, stub); -+ alive = true -+ } -+ -+ public class IncrementalCompilationComponentsImpl(val idToCache: Map): IncrementalCompilationComponents { -+ // perf: cheap object, but still the pattern may be costly if there are too many calls to cache with the same id (which seems not to be the case now) -+ override fun getIncrementalCache(moduleId: String): IncrementalCache = RemoteIncrementalCacheClient(idToCache[moduleId]!!) -+ override fun getLookupTracker(): LookupTracker = LookupTracker.DO_NOTHING -+ } -+ -+ private fun createCompileServices(incrementalCaches: Map): Services = -+ Services.Builder() -+ .register(javaClass(), IncrementalCompilationComponentsImpl(incrementalCaches)) -+// .register(javaClass(), object: CompilationCanceledStatus { -+// override fun checkCanceled(): Unit = if (context.getCancelStatus().isCanceled()) throw CompilationCanceledException() -+// }) -+ .build() -+ -+ -+ fun usedMemory(): Long { -+ System.gc() -+ val rt = Runtime.getRuntime() -+ return (rt.totalMemory() - rt.freeMemory())","I think you can get more accurate information using the MemoryMXBean class. -",Please avoid wildcard imports. -139,"@@ -0,0 +1,194 @@ -+/* -+ * 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.effectsystem.adapters -+ -+import org.jetbrains.kotlin.builtins.DefaultBuiltIns -+import org.jetbrains.kotlin.descriptors.ModuleDescriptor -+import org.jetbrains.kotlin.effectsystem.factories.createConstant -+import org.jetbrains.kotlin.effectsystem.functors.* -+import org.jetbrains.kotlin.effectsystem.resolving.FunctorResolver -+import org.jetbrains.kotlin.effectsystem.structure.ESFunctor -+import org.jetbrains.kotlin.effectsystem.structure.EffectSchema -+import org.jetbrains.kotlin.effectsystem.structure.UNIT_ID -+import org.jetbrains.kotlin.effectsystem.structure.calltree.* -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.* -+import org.jetbrains.kotlin.resolve.BindingContext -+import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall -+import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument -+import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue -+import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory -+import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant -+import org.jetbrains.kotlin.types.KotlinType -+import org.jetbrains.kotlin.utils.addToStdlib.cast -+import org.jetbrains.kotlin.utils.ifEmpty -+ -+/** -+ * Visits Psi-tree and builds Call Tree -+ */ -+class CallTreeBuilder( -+ private val bindingContext: BindingContext, -+ private val moduleDescriptor: ModuleDescriptor, -+ private val functorResolver: FunctorResolver -+) : KtVisitor() { -+ -+ override fun visitKtElement(element: KtElement, data: Unit): CTNode = UNKNOWN_CALL -+ -+ override fun visitConstantExpression(expression: KtConstantExpression, data: Unit): CTNode { -+ val bindingContext = bindingContext -+ -+ val type: KotlinType = bindingContext.getType(expression) ?: return UNKNOWN_CALL -+ -+ val compileTimeConstant: CompileTimeConstant<*> -+ = bindingContext.get(BindingContext.COMPILE_TIME_VALUE, expression) ?: return UNKNOWN_CALL -+ val value: Any? = compileTimeConstant.getValue(type) -+ return CTConstant(ValueIdsFactory.idForConstant(value), type, value) -+ } -+ -+ override fun visitSimpleNameExpression(expression: KtSimpleNameExpression, data: Unit): CTNode { -+ // TODO: make proper resolving -+ if (expression.text == ""Unit"") return CTConstant(UNIT_ID, DefaultBuiltIns.Instance.unitType, Unit) -+ return tryCreateVariable(expression) -+ } -+ -+ override fun visitParenthesizedExpression(expression: KtParenthesizedExpression, data: Unit): CTNode { -+ val deparenthesized = KtPsiUtil.safeDeparenthesize(expression) -+ return if (deparenthesized == expression) UNKNOWN_CALL else deparenthesized.accept(this, data) -+ } -+ -+ override fun visitUnaryExpression(expression: KtUnaryExpression, data: Unit): CTCall { -+ tryGetCachedCall(expression)?.let { return it } -+ -+ val argNode = expression.baseExpression?.accept(this, data) ?: return UNKNOWN_CALL -+ return when (expression.operationToken) { -+ KtTokens.EXCL -> CTCall(NotFunctor(), listOf(argNode)) -+ else -> return UNKNOWN_CALL -+ } -+ } -+ -+ override fun visitDotQualifiedExpression(expression: KtDotQualifiedExpression, data: Unit): CTCall { -+ tryGetCachedCall(expression)?.let { return it } -+ -+ val receiver = expression.receiverExpression.accept(this, data) -+ -+ val resolvedCall = expression.selectorExpression.getResolvedCall(bindingContext) ?: return UNKNOWN_CALL -+ val argNodes = resolvedCall.valueArgumentsByIndex?.map { -+ (it as? ExpressionValueArgument)?.valueArgument?.getArgumentExpression()?.accept(this, data) ?: return UNKNOWN_CALL -+ } ?: return UNKNOWN_CALL -+ -+ val functor = functorResolver.resolveFunctor(resolvedCall) ?: return UNKNOWN_CALL -+ return CTCall(functor, listOf(receiver) + argNodes) -+ } -+ -+ override fun visitThisExpression(expression: KtThisExpression, data: Unit?): CTNode { -+ val dfv = expression.createDataFlowValue() ?: return UNKNOWN_CALL // Could be possible for unavailable/incorrect this -+ return CTVariable(ValueIdsFactory.dfvBased(dfv), dfv.type) -+ } -+ -+ override fun visitClassLiteralExpression(expression: KtClassLiteralExpression, data: Unit?): CTNode = tryCreateVariable(expression) -+ -+ override fun visitLabeledExpression(expression: KtLabeledExpression, data: Unit): CTNode = expression.baseExpression?.accept(this, data) ?: UNKNOWN_CALL -+ -+ override fun visitBinaryExpression(expression: KtBinaryExpression, data: Unit): CTCall { -+ tryGetCachedCall(expression)?.let { return it } -+ -+ val leftNode = expression.left?.accept(this, data) ?: return UNKNOWN_CALL -+ val rightNode = expression.right?.accept(this, data) ?: return UNKNOWN_CALL -+ -+ val functor = when (expression.operationToken) { -+ KtTokens.EQEQ, KtTokens.EQEQEQ -> {",Not quite sure should reference comparison be here.,We discourage the wildcard imports. -140,"@@ -0,0 +1,2 @@ -+// ""Change type argument list to <*>"" ""true"" -+fun isStringList(list : Any?) = list is (List<String>)","At first, I've added the parentheses because this way it's more readable to me. But as I was trying to implement the quickfix I realised that it would be possible to make mistake in this case: change ""(List)"" to ""List<*>"". That's why I left the parentheses in one test case. -",This should be `list : Any` -141,"@@ -0,0 +1,202 @@ -+# @-based Syntax For Annotations -+ -+Goals: -+* Spare `[...]` in expression position for future use -+* Support targeting for annotations (`field`, `getter` etc) -+* Preserve affected/clashing functionality (`@labels`) -+* Support `open` and other modifiers on local classes -+ -+## Examples -+ -+Annotation: -+``` kotlin -+@AnnotationName(args) -+class Foo -+``` -+ -+Targeted annotation: -+``` kotlin -+class C(@field:Foo val x: Int, @field,parameter:Bar val y: Int) -+``` -+ -+another option (like in Scala): -+``` kotlin -+class C(@(Foo@field) val x: Int, @(Bar@(field,parameter)) val y: Int) -+``` -+ -+yet another option (requires allowing annotation arrays at least in source-retained annotations): -+ -+``` kotlin -+class C(@field(@Foo) val x: Int, @field(@Bar) @parameter(@Bar) val y: Int) -+``` -+ -+Labels: -+``` kotlin -+loop@ // declaring a label -+for (x in foo) { -+ if (x > 0) continue@loop // using a label -+} -+``` -+ -+## Syntactic Disambiguation -+ -+How can we avoid confusion between `continue@loop` and -+ -+``` kotlin -+if (foo) continue -+@ann val x = 1 -+``` -+ -+or `return@label (x + 1) + 5` and `return @ann(x + 1) +5` -+ -+Rules: -+* no newline allowed between `continue`/`break`/`this`/`super`/`return` and `@label` -+* only one label allowed after these keywords, everything after the first label is an annotation -+* for `return` we prefer `return@label` to `return @ann expr`, so one should say `return (@ann expr)` -+ -+## Targeting -+ -+Possible targets are -+* `field` -+* `get` -+* `set` -+* `property` -+* `parameter` - for constructor parameters that are also properties -+ -+Reasonable defaults would probably be: -+* `field` if there's a backing field -+* `get` otherwise","Maybe it's worth to mention default target for constructor parameters? Will it be `parameter` for simple parameters and for fields? -",This line needs to be indented by 4 more spaces to pass -142,"@@ -0,0 +1,202 @@ -+# @-based Syntax For Annotations -+ -+Goals: -+* Spare `[...]` in expression position for future use -+* Support targeting for annotations (`field`, `getter` etc) -+* Preserve affected/clashing functionality (`@labels`) -+* Support `open` and other modifiers on local classes -+ -+## Examples -+ -+Annotation: -+``` kotlin -+@AnnotationName(args) -+class Foo -+``` -+ -+Targeted annotation: -+``` kotlin -+class C(@field:Foo val x: Int, @field,parameter:Bar val y: Int) -+``` -+ -+another option (like in Scala): -+``` kotlin -+class C(@(Foo@field) val x: Int, @(Bar@(field,parameter)) val y: Int) -+``` -+ -+yet another option (requires allowing annotation arrays at least in source-retained annotations): -+ -+``` kotlin -+class C(@field(@Foo) val x: Int, @field(@Bar) @parameter(@Bar) val y: Int) -+``` -+ -+Labels: -+``` kotlin -+loop@ // declaring a label -+for (x in foo) { -+ if (x > 0) continue@loop // using a label -+} -+``` -+ -+## Syntactic Disambiguation -+ -+How can we avoid confusion between `continue@loop` and -+ -+``` kotlin -+if (foo) continue -+@ann val x = 1 -+``` -+ -+or `return@label (x + 1) + 5` and `return @ann(x + 1) +5` -+ -+Rules: -+* no newline allowed between `continue`/`break`/`this`/`super`/`return` and `@label` -+* only one label allowed after these keywords, everything after the first label is an annotation -+* for `return` we prefer `return@label` to `return @ann expr`, so one should say `return (@ann expr)` -+ -+## Targeting -+ -+Possible targets are -+* `field` -+* `get` -+* `set` -+* `property` -+* `parameter` - for constructor parameters that are also properties -+ -+Reasonable defaults would probably be: -+* `field` if there's a backing field -+* `get` otherwise -+ -+Otherwise, determined by the settings of the annotation itself (applicable to fields only -> goes to a field)","Shall we really allow omitting the non-default target in code? It's a clear message with quick-fix for a code writter and possible source of misunderstanding for a reader that can't be resolved without navigating to annotation declaration. And annotation target settings modification can lead to unexpected tools failures without any compiler messages on rebuild. -",This line needs to be indented by 4 more spaces to pass -143,"@@ -0,0 +1,202 @@ -+# @-based Syntax For Annotations -+ -+Goals: -+* Spare `[...]` in expression position for future use -+* Support targeting for annotations (`field`, `getter` etc) -+* Preserve affected/clashing functionality (`@labels`) -+* Support `open` and other modifiers on local classes -+ -+## Examples -+ -+Annotation: -+``` kotlin -+@AnnotationName(args) -+class Foo -+``` -+ -+Targeted annotation: -+``` kotlin -+class C(@field:Foo val x: Int, @field,parameter:Bar val y: Int) -+``` -+ -+another option (like in Scala): -+``` kotlin -+class C(@(Foo@field) val x: Int, @(Bar@(field,parameter)) val y: Int) -+``` -+ -+yet another option (requires allowing annotation arrays at least in source-retained annotations): -+ -+``` kotlin -+class C(@field(@Foo) val x: Int, @field(@Bar) @parameter(@Bar) val y: Int) -+``` -+ -+Labels: -+``` kotlin -+loop@ // declaring a label -+for (x in foo) { -+ if (x > 0) continue@loop // using a label -+} -+``` -+ -+## Syntactic Disambiguation -+ -+How can we avoid confusion between `continue@loop` and -+ -+``` kotlin -+if (foo) continue -+@ann val x = 1 -+``` -+ -+or `return@label (x + 1) + 5` and `return @ann(x + 1) +5` -+ -+Rules: -+* no newline allowed between `continue`/`break`/`this`/`super`/`return` and `@label` -+* only one label allowed after these keywords, everything after the first label is an annotation -+* for `return` we prefer `return@label` to `return @ann expr`, so one should say `return (@ann expr)` -+ -+## Targeting -+ -+Possible targets are -+* `field` -+* `get` -+* `set` -+* `property` -+* `parameter` - for constructor parameters that are also properties -+ -+Reasonable defaults would probably be: -+* `field` if there's a backing field -+* `get` otherwise -+ -+Otherwise, determined by the settings of the annotation itself (applicable to fields only -> goes to a field) -+ -+### Possible Syntax for Targeting -+ -+Special syntax: -+ -+``` kotlin -+class C(@field:Ann(""arg"") var foo: Int) -+``` -+ -+This is a rather limited dedicated solution: it is unclear, for example, how you define a new target, also this syntax can not be used for anything else but targeting. -+ -+Scala-like syntax: -+ -+``` kotlin -+class C(@(Ann@field)(""arg"") var foo: Int) -+``` -+ -+Too many parentheses, but the mechanism is generic. -+ -+Annotation-array-based syntax: -+ -+``` kotlin -+class C(@field(@Ann1(""arg""), @Ann2) var foo: Int) -+``` -+ -+Downside: to put the same annotation on two targets, we'd need to duplicate it. -+ -+For this, we need to allow annotation attributes of type `Array`: -+ -+``` kotlin -+annotation class field(vararg val annotations: Annotation) -+``` -+**NOTE**: This is only relatively easilty achievable for source-retained annotations, for class- or runtime-retained it's a lot more involved and relies on an undocumented features of JVM.","eastlty -> easily -",This line needs to be indented by 4 more spaces to pass -144,"@@ -0,0 +1,202 @@ -+/* -+ * 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.service -+ -+import org.jetbrains.kotlin.cli.common.CLICompiler -+import org.jetbrains.kotlin.config.Services -+import org.jetbrains.kotlin.incremental.components.LookupTracker -+import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache -+import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents -+import org.jetbrains.kotlin.rmi.* -+import org.jetbrains.kotlin.rmi.service.RemoteIncrementalCacheClient -+import org.jetbrains.kotlin.rmi.service.RemoteOutputStreamClient -+import java.io.IOException -+import java.io.PrintStream -+import java.lang.management.ManagementFactory -+import java.net.URLClassLoader -+import java.rmi.registry.Registry -+import java.rmi.server.UnicastRemoteObject -+import java.util.concurrent.TimeUnit -+import java.util.concurrent.locks.ReentrantReadWriteLock -+import java.util.jar.Manifest -+import java.util.logging.Logger -+import kotlin.concurrent.read -+import kotlin.concurrent.write -+ -+ -+class CompileServiceImpl>( -+ val registry: Registry, -+ val compiler: Compiler, -+ val selfCompilerId: CompilerId, -+ val daemonOptions: DaemonOptions -+) : CompileService, UnicastRemoteObject() { -+ -+ val log by lazy { Logger.getLogger(""compiler"") } -+ -+ private val rwlock = ReentrantReadWriteLock() -+ private var alive = false -+ -+ // TODO: consider matching compilerId coming from outside with actual one -+// private val selfCompilerId by lazy { -+// CompilerId( -+// compilerClasspath = System.getProperty(""java.class.path"") -+// ?.split(File.pathSeparator) -+// ?.map { File(it) } -+// ?.filter { it.exists() } -+// ?.map { it.absolutePath } -+// ?: listOf(), -+// compilerVersion = loadKotlinVersionFromResource() -+// ) -+// } -+ -+ init { -+ // assuming logically synchronized -+ try { -+ // cleanup for the case of incorrect restart -+ UnicastRemoteObject.unexportObject(this, false) -+ } -+ catch (e: java.rmi.NoSuchObjectException) { -+ // ignoring if object already exported -+ } -+ -+ val stub = UnicastRemoteObject.exportObject(this, 0) as CompileService -+ // TODO: use version-specific name -+ registry.rebind (COMPILER_SERVICE_RMI_NAME, stub); -+ alive = true -+ } -+ -+ public class IncrementalCompilationComponentsImpl(val idToCache: Map): IncrementalCompilationComponents { -+ // perf: cheap object, but still the pattern may be costly if there are too many calls to cache with the same id (which seems not to be the case now) -+ override fun getIncrementalCache(moduleId: String): IncrementalCache = RemoteIncrementalCacheClient(idToCache[moduleId]!!) -+ // TODO: add appropriate proxy into interaction when lookup tracker is needed -+ override fun getLookupTracker(): LookupTracker = LookupTracker.DO_NOTHING -+ } -+ -+ private fun createCompileServices(incrementalCaches: Map): Services = -+ Services.Builder() -+ .register(IncrementalCompilationComponents::class.java, IncrementalCompilationComponentsImpl(incrementalCaches)) -+ // TODO: add remote proxy for cancellation status tracking -+// .register(javaClass(), object: CompilationCanceledStatus { -+// override fun checkCanceled(): Unit = if (context.getCancelStatus().isCanceled()) throw CompilationCanceledException() -+// }) -+ .build() -+ -+ -+ fun usedMemory(): Long { -+ System.gc() -+ val rt = Runtime.getRuntime() -+ return (rt.totalMemory() - rt.freeMemory()) -+ } -+ -+ fun usedMemoryMX(): Long { -+ System.gc() -+ val memoryMXBean= ManagementFactory.getMemoryMXBean() -+ val memHeap=memoryMXBean.getHeapMemoryUsage() -+ return memHeap.used -+ } -+ -+ // TODO: consider using version as a part of compiler ID or drop this function -+ private fun loadKotlinVersionFromResource(): String { -+ (javaClass.classLoader as? URLClassLoader) -+ ?.findResource(""META-INF/MANIFEST.MF"") -+ ?.let { -+ try { -+ return Manifest(it.openStream()).mainAttributes.getValue(""Implementation-Version"") ?: """" -+ } -+ catch (e: IOException) {} -+ } -+ return """" -+ } -+ -+ -+ fun checkedCompile(args: Array, body: () -> R): R { -+ try { -+ if (args.none()) -+ throw IllegalArgumentException(""Error: empty arguments list."") -+ log.info(""Starting compilation with args: "" + args.joinToString("" "")) -+ val startMemMX = usedMemoryMX() / 1024 -+ val startMem = usedMemory() / 1024 -+ val startTime = System.nanoTime() -+ val res = body() -+ val endTime = System.nanoTime() -+ val endMem = usedMemory() / 1024 -+ val endMemMX = usedMemoryMX() / 1024 -+ log.info(""Done with result "" + res.toString()) -+ log.info(""Elapsed time: "" + TimeUnit.NANOSECONDS.toMillis(endTime - startTime) + "" ms"") -+ log.info(""Used memory: $endMem kb (${""%+d"".format(endMem - startMem)} kb)"") -+ log.info(""Used memory (from MemoryMXBean): $endMemMX kb (${""%+d"".format(endMemMX - startMemMX)} kb)"") -+ return res -+ } -+ catch (e: Exception) { -+ log.info(""Error: $e"") -+ throw e -+ } -+ } -+ -+ fun ifAlive(body: () -> R): R = rwlock.read { -+ if (!alive) throw IllegalStateException(""Kotlin Compiler Service is not in alive state"") -+ else body() -+ } -+ -+ fun ifAliveExclusive(body: () -> R): R = rwlock.write { -+ if (!alive) throw IllegalStateException(""Kotlin Compiler Service is not in alive state"") -+ else body() -+ } -+ -+ // sometimes used for debugging -+ fun spy(msg: String, body: () -> R): R { -+ val res = body() -+ log.info(msg + "" = "" + res.toString()) -+ return res -+ } -+ -+ override fun getCompilerId(): CompilerId = ifAlive { selfCompilerId } -+ -+ override fun getUsedMemory(): Long = ifAlive { usedMemory() } -+ -+ override fun shutdown() { -+ ifAliveExclusive { -+ log.info(""Shutdown started"") -+ alive = false -+ UnicastRemoteObject.unexportObject(this, true) -+ log.info(""Shutdown complete"") -+ } -+ } -+ -+ override fun remoteCompile(args: Array, errStream: RemoteOutputStream, outputFormat: CompileService.OutputFormat): Int = -+ doCompile(args, errStream) { printStream -> -+ when (outputFormat) { -+ CompileService.OutputFormat.PLAIN -> compiler.exec(printStream, *args) -+ CompileService.OutputFormat.XML -> compiler.execAndOutputXml(printStream, Services.EMPTY, *args) -+ }.code -+ } -+ -+ override fun remoteIncrementalCompile(args: Array, caches: Map, outputStream: RemoteOutputStream, outputFormat: CompileService.OutputFormat): Int = -+ doCompile(args, outputStream) { printStream -> -+ when (outputFormat) { -+ CompileService.OutputFormat.PLAIN -> throw NotImplementedError(""Only XML output is supported in remote incremental compilation"") -+ CompileService.OutputFormat.XML -> compiler.execAndOutputXml(printStream, createCompileServices(caches), *args) -+ }.code -+ } -+ -+ fun doCompile(args: Array, errStream: RemoteOutputStream, body: (PrintStream) -> Int): Int =","I'd write something like: - -``` kotlin - override fun remoteCompile(args: Array, errStream: RemoteOutputStream, outputFormat: CompileService.OutputFormat): Int = - doCompile(args, errStream, outputFormat) { compiler.exec(it, *args) } - - override fun remoteIncrementalCompile(args: Array, caches: Map, outputStream: RemoteOutputStream, outputFormat: CompileService.OutputFormat): Int = - doCompile(args, outputStream, outputFormat) { throw NotImplementedError(""Only XML output is supported in remote incremental compilation"") } - - fun doCompile(args: Array, errStream: RemoteOutputStream, outputFormat: CompileService.OutputFormat, compileWithPlainOut: (PrintStream) -> ExitCode): Int = - ifAlive { - checkedCompile(args) { - val remoteStreamClient = RemoteOutputStreamClient(errStream) - val printStream = PrintStream(remoteStreamClient) - when (outputFormat) { - CompileService.OutputFormat.PLAIN -> compileWithPlainOut(printStream) - CompileService.OutputFormat.XML -> compiler.execAndOutputXml(printStream, Services.EMPTY, *args) - }.code - } - } -``` -",Please annotate all the classes in this package with `@VisibleForTesting`. -145,"@@ -0,0 +1,203 @@ -+/*","As far as I understand these functions are copies of functions at KotlinBuilder. Why not to reuse them at KotlinBuilder? I mean, these functions are in build common, so their originals from KotlinBuilder can be removed. -",Please remove this file. -146,"@@ -0,0 +1,204 @@ -+/* -+ * 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.codegen -+ -+import org.jetbrains.kotlin.codegen.binding.CodegenBinding -+import org.jetbrains.kotlin.codegen.context.CodegenContext -+import org.jetbrains.kotlin.codegen.state.GenerationState -+import org.jetbrains.kotlin.descriptors.* -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.psi.JetClass -+import org.jetbrains.kotlin.psi.JetClassOrObject -+import org.jetbrains.kotlin.psi.JetElement -+import org.jetbrains.kotlin.psi.JetNamedFunction -+import org.jetbrains.kotlin.resolve.jvm.AsmTypes -+import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin -+import org.jetbrains.org.objectweb.asm.Opcodes -+import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter -+ -+/** -+ * Generates Java overloads for functions and constructors that have the default -+ * parameter values substituted. -+ */ -+public class DefaultParameterValueSubstitutor(val state: GenerationState) { -+ /** -+ * If all of the parameters of the specified constructor declare default values, -+ * generates a no-argument constructor that passes default values for all arguments. -+ */ -+ fun generateDefaultConstructorIfNeeded(constructorDescriptor: ConstructorDescriptor, -+ classBuilder: ClassBuilder, -+ context: CodegenContext<*>, -+ classOrObject: JetClassOrObject) { -+ if (!isEmptyConstructorNeeded(constructorDescriptor, classOrObject)) { -+ return -+ } -+ -+ generateOverloadWithSubstitutedParameters(constructorDescriptor, constructorDescriptor, classBuilder, classOrObject, -+ context, -+ constructorDescriptor.countDefaultParameters()) -+ } -+ -+ /** -+ * If the function is annotated with [kotlin.jvm.overloads], generates Java methods that -+ * have the default parameter values substituted. If a method has N parameters and M of which -+ * have default values, M overloads are generated: the first one takes N-1 parameters (all but -+ * the last one that takes a default value), the second takes N-2 parameters, and so on. -+ * -+ * @param functionDescriptor the method for which the overloads are generated -+ * @param delegateFunctionDescriptor the method descriptor for the implementation that we need to call -+ * (same as [functionDescriptor] in all cases except for companion object methods annotated with [platformStatic], -+ * where [functionDescriptor] is the static method in the main class and [delegateFunctionDescriptor] is the -+ * implementation in the companion object class) -+ */ -+ fun generateOverloadsIfNeeded(function: JetNamedFunction, -+ functionDescriptor: FunctionDescriptor, -+ delegateFunctionDescriptor: FunctionDescriptor, -+ owner: CodegenContext<*>, -+ classBuilder: ClassBuilder) { -+ val overloadsFqName = FqName.fromSegments(listOf(""kotlin"", ""jvm"", ""overloads""))","`FqName(""kotlin.jvm.overloads"")` would be more grep-friendly. Also I would make it a constant (either top-level or in the companion) -",Add a brief description of what this class is doing. -147,"@@ -0,0 +1,204 @@ -+/* -+ * 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.codegen -+ -+import org.jetbrains.kotlin.codegen.binding.CodegenBinding -+import org.jetbrains.kotlin.codegen.context.CodegenContext -+import org.jetbrains.kotlin.codegen.state.GenerationState -+import org.jetbrains.kotlin.descriptors.* -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.psi.JetClass -+import org.jetbrains.kotlin.psi.JetClassOrObject -+import org.jetbrains.kotlin.psi.JetElement -+import org.jetbrains.kotlin.psi.JetNamedFunction -+import org.jetbrains.kotlin.resolve.jvm.AsmTypes -+import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin -+import org.jetbrains.org.objectweb.asm.Opcodes -+import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter -+ -+/** -+ * Generates Java overloads for functions and constructors that have the default -+ * parameter values substituted. -+ */ -+public class DefaultParameterValueSubstitutor(val state: GenerationState) { -+ /** -+ * If all of the parameters of the specified constructor declare default values, -+ * generates a no-argument constructor that passes default values for all arguments. -+ */ -+ fun generateDefaultConstructorIfNeeded(constructorDescriptor: ConstructorDescriptor, -+ classBuilder: ClassBuilder, -+ context: CodegenContext<*>, -+ classOrObject: JetClassOrObject) { -+ if (!isEmptyConstructorNeeded(constructorDescriptor, classOrObject)) { -+ return -+ } -+ -+ generateOverloadWithSubstitutedParameters(constructorDescriptor, constructorDescriptor, classBuilder, classOrObject, -+ context, -+ constructorDescriptor.countDefaultParameters()) -+ } -+ -+ /** -+ * If the function is annotated with [kotlin.jvm.overloads], generates Java methods that -+ * have the default parameter values substituted. If a method has N parameters and M of which -+ * have default values, M overloads are generated: the first one takes N-1 parameters (all but -+ * the last one that takes a default value), the second takes N-2 parameters, and so on. -+ * -+ * @param functionDescriptor the method for which the overloads are generated -+ * @param delegateFunctionDescriptor the method descriptor for the implementation that we need to call -+ * (same as [functionDescriptor] in all cases except for companion object methods annotated with [platformStatic], -+ * where [functionDescriptor] is the static method in the main class and [delegateFunctionDescriptor] is the -+ * implementation in the companion object class) -+ */ -+ fun generateOverloadsIfNeeded(function: JetNamedFunction, -+ functionDescriptor: FunctionDescriptor, -+ delegateFunctionDescriptor: FunctionDescriptor, -+ owner: CodegenContext<*>, -+ classBuilder: ClassBuilder) { -+ val overloadsFqName = FqName.fromSegments(listOf(""kotlin"", ""jvm"", ""overloads"")) -+ if (functionDescriptor.getAnnotations().findAnnotation(overloadsFqName) == null) return -+ -+ val count = functionDescriptor.countDefaultParameters() -+ val context = owner.intoFunction(functionDescriptor) -+ -+ for (i in 1..count) { -+ generateOverloadWithSubstitutedParameters(functionDescriptor, delegateFunctionDescriptor, classBuilder, function, context, i) -+ } -+ } -+ -+ private fun FunctionDescriptor.countDefaultParameters() = -+ getValueParameters().count { it.hasDefaultValue() } -+ -+ /** -+ * Generates an overload for [functionDescriptor] that substitutes default values for the last -+ * [substituteCount] parameters that have default values. -+ * -+ * @param functionDescriptor the method for which the overloads are generated -+ * @param delegateFunctionDescriptor the method descriptor for the implementation that we need to call -+ * (same as [functionDescriptor] in all cases except for companion object methods annotated with [platformStatic], -+ * where [functionDescriptor] is the static method in the main class and [delegateFunctionDescriptor] is the -+ * implementation in the companion object class) -+ * @param methodElement the PSI element for the method implementation (used in diagnostic messages only) -+ */ -+ fun generateOverloadWithSubstitutedParameters(functionDescriptor: FunctionDescriptor, -+ delegateFunctionDescriptor: FunctionDescriptor, -+ classBuilder: ClassBuilder, -+ methodElement: JetElement?, -+ context: CodegenContext<*>, -+ substituteCount: Int) { -+ val isStatic = AsmUtil.isStaticMethod(context.getContextKind(), functionDescriptor) -+ val flags = AsmUtil.getVisibilityAccessFlag(functionDescriptor) or (if (isStatic) Opcodes.ACC_STATIC else 0) -+ val remainingParameters = getRemainingParameters(functionDescriptor.getOriginal(), substituteCount) -+ val signature = state.getTypeMapper().mapSignature(functionDescriptor, context.getContextKind(),","Please extract `state.getTypeMapper()` to a property -",Add a brief description of what this class is doing. -148,"@@ -0,0 +1,204 @@ -+/* -+ * 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.codegen -+ -+import org.jetbrains.kotlin.codegen.binding.CodegenBinding -+import org.jetbrains.kotlin.codegen.context.CodegenContext -+import org.jetbrains.kotlin.codegen.state.GenerationState -+import org.jetbrains.kotlin.descriptors.* -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.psi.JetClass -+import org.jetbrains.kotlin.psi.JetClassOrObject -+import org.jetbrains.kotlin.psi.JetElement -+import org.jetbrains.kotlin.psi.JetNamedFunction -+import org.jetbrains.kotlin.resolve.jvm.AsmTypes -+import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin -+import org.jetbrains.org.objectweb.asm.Opcodes -+import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter -+ -+/** -+ * Generates Java overloads for functions and constructors that have the default -+ * parameter values substituted. -+ */ -+public class DefaultParameterValueSubstitutor(val state: GenerationState) { -+ /** -+ * If all of the parameters of the specified constructor declare default values, -+ * generates a no-argument constructor that passes default values for all arguments. -+ */ -+ fun generateDefaultConstructorIfNeeded(constructorDescriptor: ConstructorDescriptor, -+ classBuilder: ClassBuilder, -+ context: CodegenContext<*>, -+ classOrObject: JetClassOrObject) { -+ if (!isEmptyConstructorNeeded(constructorDescriptor, classOrObject)) { -+ return -+ } -+ -+ generateOverloadWithSubstitutedParameters(constructorDescriptor, constructorDescriptor, classBuilder, classOrObject, -+ context, -+ constructorDescriptor.countDefaultParameters()) -+ } -+ -+ /** -+ * If the function is annotated with [kotlin.jvm.overloads], generates Java methods that -+ * have the default parameter values substituted. If a method has N parameters and M of which -+ * have default values, M overloads are generated: the first one takes N-1 parameters (all but -+ * the last one that takes a default value), the second takes N-2 parameters, and so on. -+ * -+ * @param functionDescriptor the method for which the overloads are generated -+ * @param delegateFunctionDescriptor the method descriptor for the implementation that we need to call -+ * (same as [functionDescriptor] in all cases except for companion object methods annotated with [platformStatic], -+ * where [functionDescriptor] is the static method in the main class and [delegateFunctionDescriptor] is the -+ * implementation in the companion object class) -+ */ -+ fun generateOverloadsIfNeeded(function: JetNamedFunction, -+ functionDescriptor: FunctionDescriptor, -+ delegateFunctionDescriptor: FunctionDescriptor, -+ owner: CodegenContext<*>, -+ classBuilder: ClassBuilder) { -+ val overloadsFqName = FqName.fromSegments(listOf(""kotlin"", ""jvm"", ""overloads"")) -+ if (functionDescriptor.getAnnotations().findAnnotation(overloadsFqName) == null) return -+ -+ val count = functionDescriptor.countDefaultParameters() -+ val context = owner.intoFunction(functionDescriptor) -+ -+ for (i in 1..count) { -+ generateOverloadWithSubstitutedParameters(functionDescriptor, delegateFunctionDescriptor, classBuilder, function, context, i) -+ } -+ } -+ -+ private fun FunctionDescriptor.countDefaultParameters() = -+ getValueParameters().count { it.hasDefaultValue() } -+ -+ /** -+ * Generates an overload for [functionDescriptor] that substitutes default values for the last -+ * [substituteCount] parameters that have default values. -+ * -+ * @param functionDescriptor the method for which the overloads are generated -+ * @param delegateFunctionDescriptor the method descriptor for the implementation that we need to call -+ * (same as [functionDescriptor] in all cases except for companion object methods annotated with [platformStatic], -+ * where [functionDescriptor] is the static method in the main class and [delegateFunctionDescriptor] is the -+ * implementation in the companion object class) -+ * @param methodElement the PSI element for the method implementation (used in diagnostic messages only) -+ */ -+ fun generateOverloadWithSubstitutedParameters(functionDescriptor: FunctionDescriptor, -+ delegateFunctionDescriptor: FunctionDescriptor, -+ classBuilder: ClassBuilder, -+ methodElement: JetElement?, -+ context: CodegenContext<*>, -+ substituteCount: Int) { -+ val isStatic = AsmUtil.isStaticMethod(context.getContextKind(), functionDescriptor) -+ val flags = AsmUtil.getVisibilityAccessFlag(functionDescriptor) or (if (isStatic) Opcodes.ACC_STATIC else 0) -+ val remainingParameters = getRemainingParameters(functionDescriptor.getOriginal(), substituteCount) -+ val signature = state.getTypeMapper().mapSignature(functionDescriptor, context.getContextKind(), -+ remainingParameters) -+ val mv = classBuilder.newMethod(OtherOrigin(functionDescriptor), flags, -+ signature.getAsmMethod().getName(), -+ signature.getAsmMethod().getDescriptor(), null, -+ FunctionCodegen.getThrownExceptions(functionDescriptor, state.getTypeMapper())) -+ -+ if (state.getClassBuilderMode() == ClassBuilderMode.LIGHT_CLASSES) return -+ -+ val frameMap = FrameMap() -+ val v = InstructionAdapter(mv) -+ mv.visitCode() -+ -+ val methodOwner = state.getTypeMapper().mapToCallableMethod(delegateFunctionDescriptor, false, context).getOwner() -+ if (!isStatic) { -+ frameMap.enterTemp(AsmTypes.OBJECT_TYPE) -+ v.load(0, methodOwner) // Load this on stack","Maybe use the value returned by `enterTemp` instead of `0` for better readability -",Add a brief description of what this class is doing. -149,"@@ -0,0 +1,204 @@ -+/* -+ * 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.codegen -+ -+import org.jetbrains.kotlin.codegen.binding.CodegenBinding -+import org.jetbrains.kotlin.codegen.context.CodegenContext -+import org.jetbrains.kotlin.codegen.state.GenerationState -+import org.jetbrains.kotlin.descriptors.* -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.psi.JetClass -+import org.jetbrains.kotlin.psi.JetClassOrObject -+import org.jetbrains.kotlin.psi.JetElement -+import org.jetbrains.kotlin.psi.JetNamedFunction -+import org.jetbrains.kotlin.resolve.jvm.AsmTypes -+import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin -+import org.jetbrains.org.objectweb.asm.Opcodes -+import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter -+ -+/** -+ * Generates Java overloads for functions and constructors that have the default -+ * parameter values substituted. -+ */ -+public class DefaultParameterValueSubstitutor(val state: GenerationState) { -+ /** -+ * If all of the parameters of the specified constructor declare default values, -+ * generates a no-argument constructor that passes default values for all arguments. -+ */ -+ fun generateDefaultConstructorIfNeeded(constructorDescriptor: ConstructorDescriptor, -+ classBuilder: ClassBuilder, -+ context: CodegenContext<*>, -+ classOrObject: JetClassOrObject) { -+ if (!isEmptyConstructorNeeded(constructorDescriptor, classOrObject)) { -+ return -+ } -+ -+ generateOverloadWithSubstitutedParameters(constructorDescriptor, constructorDescriptor, classBuilder, classOrObject, -+ context, -+ constructorDescriptor.countDefaultParameters()) -+ } -+ -+ /** -+ * If the function is annotated with [kotlin.jvm.overloads], generates Java methods that -+ * have the default parameter values substituted. If a method has N parameters and M of which -+ * have default values, M overloads are generated: the first one takes N-1 parameters (all but -+ * the last one that takes a default value), the second takes N-2 parameters, and so on. -+ * -+ * @param functionDescriptor the method for which the overloads are generated -+ * @param delegateFunctionDescriptor the method descriptor for the implementation that we need to call -+ * (same as [functionDescriptor] in all cases except for companion object methods annotated with [platformStatic], -+ * where [functionDescriptor] is the static method in the main class and [delegateFunctionDescriptor] is the -+ * implementation in the companion object class) -+ */ -+ fun generateOverloadsIfNeeded(function: JetNamedFunction, -+ functionDescriptor: FunctionDescriptor, -+ delegateFunctionDescriptor: FunctionDescriptor, -+ owner: CodegenContext<*>, -+ classBuilder: ClassBuilder) { -+ val overloadsFqName = FqName.fromSegments(listOf(""kotlin"", ""jvm"", ""overloads"")) -+ if (functionDescriptor.getAnnotations().findAnnotation(overloadsFqName) == null) return -+ -+ val count = functionDescriptor.countDefaultParameters() -+ val context = owner.intoFunction(functionDescriptor) -+ -+ for (i in 1..count) { -+ generateOverloadWithSubstitutedParameters(functionDescriptor, delegateFunctionDescriptor, classBuilder, function, context, i) -+ } -+ } -+ -+ private fun FunctionDescriptor.countDefaultParameters() = -+ getValueParameters().count { it.hasDefaultValue() } -+ -+ /** -+ * Generates an overload for [functionDescriptor] that substitutes default values for the last -+ * [substituteCount] parameters that have default values. -+ * -+ * @param functionDescriptor the method for which the overloads are generated -+ * @param delegateFunctionDescriptor the method descriptor for the implementation that we need to call -+ * (same as [functionDescriptor] in all cases except for companion object methods annotated with [platformStatic], -+ * where [functionDescriptor] is the static method in the main class and [delegateFunctionDescriptor] is the -+ * implementation in the companion object class) -+ * @param methodElement the PSI element for the method implementation (used in diagnostic messages only) -+ */ -+ fun generateOverloadWithSubstitutedParameters(functionDescriptor: FunctionDescriptor, -+ delegateFunctionDescriptor: FunctionDescriptor, -+ classBuilder: ClassBuilder, -+ methodElement: JetElement?, -+ context: CodegenContext<*>, -+ substituteCount: Int) { -+ val isStatic = AsmUtil.isStaticMethod(context.getContextKind(), functionDescriptor) -+ val flags = AsmUtil.getVisibilityAccessFlag(functionDescriptor) or (if (isStatic) Opcodes.ACC_STATIC else 0) -+ val remainingParameters = getRemainingParameters(functionDescriptor.getOriginal(), substituteCount) -+ val signature = state.getTypeMapper().mapSignature(functionDescriptor, context.getContextKind(), -+ remainingParameters) -+ val mv = classBuilder.newMethod(OtherOrigin(functionDescriptor), flags, -+ signature.getAsmMethod().getName(), -+ signature.getAsmMethod().getDescriptor(), null, -+ FunctionCodegen.getThrownExceptions(functionDescriptor, state.getTypeMapper())) -+ -+ if (state.getClassBuilderMode() == ClassBuilderMode.LIGHT_CLASSES) return -+ -+ val frameMap = FrameMap() -+ val v = InstructionAdapter(mv) -+ mv.visitCode() -+ -+ val methodOwner = state.getTypeMapper().mapToCallableMethod(delegateFunctionDescriptor, false, context).getOwner() -+ if (!isStatic) { -+ frameMap.enterTemp(AsmTypes.OBJECT_TYPE) -+ v.load(0, methodOwner) // Load this on stack -+ } else {","`else` should be on the next line :) Several times in this file -",Add a brief description of what this class is doing. -150,"@@ -0,0 +1,204 @@ -+/* -+ * 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.codegen -+ -+import org.jetbrains.kotlin.codegen.binding.CodegenBinding -+import org.jetbrains.kotlin.codegen.context.CodegenContext -+import org.jetbrains.kotlin.codegen.state.GenerationState -+import org.jetbrains.kotlin.descriptors.* -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.psi.JetClass -+import org.jetbrains.kotlin.psi.JetClassOrObject -+import org.jetbrains.kotlin.psi.JetElement -+import org.jetbrains.kotlin.psi.JetNamedFunction -+import org.jetbrains.kotlin.resolve.jvm.AsmTypes -+import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin -+import org.jetbrains.org.objectweb.asm.Opcodes -+import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter -+ -+/** -+ * Generates Java overloads for functions and constructors that have the default -+ * parameter values substituted. -+ */ -+public class DefaultParameterValueSubstitutor(val state: GenerationState) { -+ /** -+ * If all of the parameters of the specified constructor declare default values, -+ * generates a no-argument constructor that passes default values for all arguments. -+ */ -+ fun generateDefaultConstructorIfNeeded(constructorDescriptor: ConstructorDescriptor, -+ classBuilder: ClassBuilder, -+ context: CodegenContext<*>, -+ classOrObject: JetClassOrObject) { -+ if (!isEmptyConstructorNeeded(constructorDescriptor, classOrObject)) { -+ return -+ } -+ -+ generateOverloadWithSubstitutedParameters(constructorDescriptor, constructorDescriptor, classBuilder, classOrObject, -+ context, -+ constructorDescriptor.countDefaultParameters()) -+ } -+ -+ /** -+ * If the function is annotated with [kotlin.jvm.overloads], generates Java methods that -+ * have the default parameter values substituted. If a method has N parameters and M of which -+ * have default values, M overloads are generated: the first one takes N-1 parameters (all but -+ * the last one that takes a default value), the second takes N-2 parameters, and so on. -+ * -+ * @param functionDescriptor the method for which the overloads are generated -+ * @param delegateFunctionDescriptor the method descriptor for the implementation that we need to call -+ * (same as [functionDescriptor] in all cases except for companion object methods annotated with [platformStatic], -+ * where [functionDescriptor] is the static method in the main class and [delegateFunctionDescriptor] is the -+ * implementation in the companion object class) -+ */ -+ fun generateOverloadsIfNeeded(function: JetNamedFunction, -+ functionDescriptor: FunctionDescriptor, -+ delegateFunctionDescriptor: FunctionDescriptor, -+ owner: CodegenContext<*>, -+ classBuilder: ClassBuilder) { -+ val overloadsFqName = FqName.fromSegments(listOf(""kotlin"", ""jvm"", ""overloads"")) -+ if (functionDescriptor.getAnnotations().findAnnotation(overloadsFqName) == null) return -+ -+ val count = functionDescriptor.countDefaultParameters() -+ val context = owner.intoFunction(functionDescriptor) -+ -+ for (i in 1..count) { -+ generateOverloadWithSubstitutedParameters(functionDescriptor, delegateFunctionDescriptor, classBuilder, function, context, i) -+ } -+ } -+ -+ private fun FunctionDescriptor.countDefaultParameters() = -+ getValueParameters().count { it.hasDefaultValue() } -+ -+ /** -+ * Generates an overload for [functionDescriptor] that substitutes default values for the last -+ * [substituteCount] parameters that have default values. -+ * -+ * @param functionDescriptor the method for which the overloads are generated -+ * @param delegateFunctionDescriptor the method descriptor for the implementation that we need to call -+ * (same as [functionDescriptor] in all cases except for companion object methods annotated with [platformStatic], -+ * where [functionDescriptor] is the static method in the main class and [delegateFunctionDescriptor] is the -+ * implementation in the companion object class) -+ * @param methodElement the PSI element for the method implementation (used in diagnostic messages only) -+ */ -+ fun generateOverloadWithSubstitutedParameters(functionDescriptor: FunctionDescriptor, -+ delegateFunctionDescriptor: FunctionDescriptor, -+ classBuilder: ClassBuilder, -+ methodElement: JetElement?, -+ context: CodegenContext<*>, -+ substituteCount: Int) { -+ val isStatic = AsmUtil.isStaticMethod(context.getContextKind(), functionDescriptor) -+ val flags = AsmUtil.getVisibilityAccessFlag(functionDescriptor) or (if (isStatic) Opcodes.ACC_STATIC else 0) -+ val remainingParameters = getRemainingParameters(functionDescriptor.getOriginal(), substituteCount) -+ val signature = state.getTypeMapper().mapSignature(functionDescriptor, context.getContextKind(), -+ remainingParameters) -+ val mv = classBuilder.newMethod(OtherOrigin(functionDescriptor), flags, -+ signature.getAsmMethod().getName(), -+ signature.getAsmMethod().getDescriptor(), null, -+ FunctionCodegen.getThrownExceptions(functionDescriptor, state.getTypeMapper())) -+ -+ if (state.getClassBuilderMode() == ClassBuilderMode.LIGHT_CLASSES) return -+ -+ val frameMap = FrameMap() -+ val v = InstructionAdapter(mv) -+ mv.visitCode() -+ -+ val methodOwner = state.getTypeMapper().mapToCallableMethod(delegateFunctionDescriptor, false, context).getOwner() -+ if (!isStatic) { -+ frameMap.enterTemp(AsmTypes.OBJECT_TYPE) -+ v.load(0, methodOwner) // Load this on stack -+ } else { -+ val delegateOwner = delegateFunctionDescriptor.getContainingDeclaration() -+ if (delegateOwner is ClassDescriptor && delegateOwner.isCompanionObject()) { -+ val singletonValue = StackValue.singleton(delegateOwner, state.getTypeMapper()) -+ singletonValue.put(singletonValue.type, v); -+ } -+ } -+ -+ val receiver = functionDescriptor.getExtensionReceiverParameter() -+ if (receiver != null) { -+ val receiverType = state.getTypeMapper().mapType(receiver) -+ val receiverIndex = frameMap.enter(receiver, receiverType) -+ StackValue.local(receiverIndex, receiverType).put(receiverType, v) -+ } -+ remainingParameters.forEach { -+ frameMap.enter(it, state.getTypeMapper().mapType(it)) -+ } -+ -+ var mask = 0 -+ val masks = arrayListOf() -+ for (parameterDescriptor in functionDescriptor.getValueParameters()) { -+ val paramType = state.getTypeMapper().mapType(parameterDescriptor.getType()) -+ if (parameterDescriptor in remainingParameters) { -+ val index = frameMap.getIndex(parameterDescriptor) -+ val type = state.getTypeMapper().mapType(parameterDescriptor)","Already calculated a little earlier (`paramType`) -",Add a brief description of what this class is doing. -151,"@@ -0,0 +1,205 @@ -+/* -+ * 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.jvm.compiler -+ -+import com.intellij.testFramework.TestDataPath -+import org.jetbrains.kotlin.test.JUnit3RunnerWithInners -+import org.jetbrains.kotlin.test.KotlinTestUtils -+import org.jetbrains.kotlin.test.TestMetadata -+import org.junit.runner.RunWith -+ -+@SuppressWarnings(""all"") -+@TestMetadata(""compiler/testData/compileKotlinAgainstJava"") -+@TestDataPath(""\$PROJECT_ROOT"") -+@RunWith(JUnit3RunnerWithInners::class) -+class CompileKotlinAgainstJavaTest : AbstractCompileJavaAgainstKotlinTest() {",`CompileKotlinAgainstJava` but `AbstractCompilerJavaAgainstKotlin`? Looks very strange,Shouldn't this be `@RunWith(JUnitRunnerWithInners.class)`? -152,"@@ -0,0 +1,207 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.codeInsight.template.*; -+import com.intellij.openapi.editor.CaretModel; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.project.Project; -+import com.intellij.psi.PsiDocumentManager; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.util.PsiTreeUtil; -+import com.intellij.refactoring.rename.inplace.MyLookupExpression; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.descriptors.ClassDescriptor; -+import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory1; -+import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1; -+import org.jetbrains.jet.lang.diagnostics.Errors; -+import org.jetbrains.jet.lang.psi.*; -+import org.jetbrains.jet.lang.resolve.BindingContext; -+import org.jetbrains.jet.plugin.JetBundle; -+import org.jetbrains.jet.plugin.caches.resolve.KotlinCacheManager; -+import org.jetbrains.jet.renderer.DescriptorRenderer; -+ -+import java.util.ArrayList; -+import java.util.Collection; -+import java.util.LinkedHashSet; -+import java.util.List; -+ -+public class MapPlatformClassToKotlinFix extends JetIntentionAction { -+ private static final String PRIMARY_USAGE = ""PrimaryUsage""; -+ private static final String OTHER_USAGE = ""OtherUsage""; -+ -+ private final ClassDescriptor platformClass; -+ private final Collection possibleClasses; -+ -+ public MapPlatformClassToKotlinFix(@NotNull JetReferenceExpression element, @NotNull ClassDescriptor platformClass, -+ @NotNull Collection possibleClasses) { -+ super(element); -+ this.platformClass = platformClass; -+ this.possibleClasses = possibleClasses; -+ } -+ -+ @NotNull -+ @Override -+ public String getText() { -+ -+ String platformClassQualifiedName = DescriptorRenderer.TEXT.renderType(platformClass.getDefaultType()); -+ return possibleClasses.size() == 1 -+ ? JetBundle.message(""map.platform.class.to.kotlin"", platformClassQualifiedName, -+ DescriptorRenderer.TEXT.renderType(possibleClasses.iterator().next().getDefaultType())) -+ : JetBundle.message(""map.platform.class.to.kotlin.multiple"", platformClassQualifiedName); -+ } -+ -+ @NotNull -+ @Override -+ public String getFamilyName() { -+ return JetBundle.message(""map.platform.class.to.kotlin.family""); -+ } -+ -+ @Override -+ public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {","This method is pretty long. Consider extracting methods for it. First candidate for extracting is code about live template in the end of the method. -",Please avoid using `import *;` -153,"@@ -0,0 +1,207 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.codeInsight.template.*; -+import com.intellij.openapi.editor.CaretModel; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.project.Project; -+import com.intellij.psi.PsiDocumentManager; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.util.PsiTreeUtil; -+import com.intellij.refactoring.rename.inplace.MyLookupExpression; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.descriptors.ClassDescriptor; -+import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory1; -+import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1; -+import org.jetbrains.jet.lang.diagnostics.Errors; -+import org.jetbrains.jet.lang.psi.*; -+import org.jetbrains.jet.lang.resolve.BindingContext; -+import org.jetbrains.jet.plugin.JetBundle; -+import org.jetbrains.jet.plugin.caches.resolve.KotlinCacheManager; -+import org.jetbrains.jet.renderer.DescriptorRenderer; -+ -+import java.util.ArrayList; -+import java.util.Collection; -+import java.util.LinkedHashSet; -+import java.util.List; -+ -+public class MapPlatformClassToKotlinFix extends JetIntentionAction { -+ private static final String PRIMARY_USAGE = ""PrimaryUsage""; -+ private static final String OTHER_USAGE = ""OtherUsage""; -+ -+ private final ClassDescriptor platformClass; -+ private final Collection possibleClasses; -+ -+ public MapPlatformClassToKotlinFix(@NotNull JetReferenceExpression element, @NotNull ClassDescriptor platformClass, -+ @NotNull Collection possibleClasses) { -+ super(element); -+ this.platformClass = platformClass; -+ this.possibleClasses = possibleClasses; -+ } -+ -+ @NotNull -+ @Override -+ public String getText() { -+ -+ String platformClassQualifiedName = DescriptorRenderer.TEXT.renderType(platformClass.getDefaultType()); -+ return possibleClasses.size() == 1 -+ ? JetBundle.message(""map.platform.class.to.kotlin"", platformClassQualifiedName, -+ DescriptorRenderer.TEXT.renderType(possibleClasses.iterator().next().getDefaultType())) -+ : JetBundle.message(""map.platform.class.to.kotlin.multiple"", platformClassQualifiedName); -+ } -+ -+ @NotNull -+ @Override -+ public String getFamilyName() { -+ return JetBundle.message(""map.platform.class.to.kotlin.family""); -+ } -+ -+ @Override -+ public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { -+ BindingContext context = KotlinCacheManager.getInstance(project).getDeclarationsFromProject().getBindingContext(); -+ Collection diagnostics = context.getDiagnostics(); -+ List imports = new ArrayList(); -+ List usages = new ArrayList(); -+ -+ for (Diagnostic diagnostic : diagnostics) { -+ if (diagnostic.getFactory() != Errors.PLATFORM_CLASS_MAPPED_TO_KOTLIN) continue; -+ JetReferenceExpression refExpr = getImportOrUsageFromDiagnostic(diagnostic); -+ if (refExpr == null) continue; -+ DeclarationDescriptor descriptor = context.get(BindingContext.REFERENCE_TARGET, refExpr); -+ if (descriptor == null || !(descriptor.equals(platformClass))) continue;","Is this check necessary? Maybe remove it or replace with assert? -",Please avoid using `import *;` -154,"@@ -0,0 +1,207 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.codeInsight.template.*; -+import com.intellij.openapi.editor.CaretModel; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.project.Project; -+import com.intellij.psi.PsiDocumentManager; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.util.PsiTreeUtil; -+import com.intellij.refactoring.rename.inplace.MyLookupExpression; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.descriptors.ClassDescriptor; -+import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory1; -+import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1; -+import org.jetbrains.jet.lang.diagnostics.Errors; -+import org.jetbrains.jet.lang.psi.*; -+import org.jetbrains.jet.lang.resolve.BindingContext; -+import org.jetbrains.jet.plugin.JetBundle; -+import org.jetbrains.jet.plugin.caches.resolve.KotlinCacheManager; -+import org.jetbrains.jet.renderer.DescriptorRenderer; -+ -+import java.util.ArrayList; -+import java.util.Collection; -+import java.util.LinkedHashSet; -+import java.util.List; -+ -+public class MapPlatformClassToKotlinFix extends JetIntentionAction { -+ private static final String PRIMARY_USAGE = ""PrimaryUsage""; -+ private static final String OTHER_USAGE = ""OtherUsage""; -+ -+ private final ClassDescriptor platformClass; -+ private final Collection possibleClasses; -+ -+ public MapPlatformClassToKotlinFix(@NotNull JetReferenceExpression element, @NotNull ClassDescriptor platformClass, -+ @NotNull Collection possibleClasses) { -+ super(element); -+ this.platformClass = platformClass; -+ this.possibleClasses = possibleClasses; -+ } -+ -+ @NotNull -+ @Override -+ public String getText() { -+ -+ String platformClassQualifiedName = DescriptorRenderer.TEXT.renderType(platformClass.getDefaultType()); -+ return possibleClasses.size() == 1 -+ ? JetBundle.message(""map.platform.class.to.kotlin"", platformClassQualifiedName, -+ DescriptorRenderer.TEXT.renderType(possibleClasses.iterator().next().getDefaultType())) -+ : JetBundle.message(""map.platform.class.to.kotlin.multiple"", platformClassQualifiedName); -+ } -+ -+ @NotNull -+ @Override -+ public String getFamilyName() { -+ return JetBundle.message(""map.platform.class.to.kotlin.family""); -+ } -+ -+ @Override -+ public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { -+ BindingContext context = KotlinCacheManager.getInstance(project).getDeclarationsFromProject().getBindingContext(); -+ Collection diagnostics = context.getDiagnostics(); -+ List imports = new ArrayList(); -+ List usages = new ArrayList(); -+ -+ for (Diagnostic diagnostic : diagnostics) { -+ if (diagnostic.getFactory() != Errors.PLATFORM_CLASS_MAPPED_TO_KOTLIN) continue; -+ JetReferenceExpression refExpr = getImportOrUsageFromDiagnostic(diagnostic); -+ if (refExpr == null) continue; -+ DeclarationDescriptor descriptor = context.get(BindingContext.REFERENCE_TARGET, refExpr); -+ if (descriptor == null || !(descriptor.equals(platformClass))) continue; -+ JetImportDirective imp = PsiTreeUtil.getParentOfType(refExpr, JetImportDirective.class); -+ if (imp == null) { -+ JetUserType type = PsiTreeUtil.getParentOfType(refExpr, JetUserType.class); -+ if (type == null) continue; -+ usages.add(type); -+ } else { -+ imports.add(imp); -+ } -+ } -+ -+ ClassDescriptor replacementClass = possibleClasses.iterator().next(); -+ String replacementClassName = replacementClass.getName().getName(); -+ List replacedExpressions = new ArrayList(); -+ for (JetImportDirective imp : imports) { -+ imp.delete(); -+ } -+ for (JetUserType usage : usages) { -+ JetTypeArgumentList typeArguments = usage.getTypeArgumentList(); -+ String typeArgumentsString = typeArguments == null ? """" : typeArguments.getText(); -+ JetTypeReference replacementType = JetPsiFactory.createType(project, replacementClassName + typeArgumentsString); -+ JetTypeElement replacementTypeElement = replacementType.getTypeElement(); -+ assert replacementTypeElement != null; -+ PsiElement replacedElement = usage.replace(replacementTypeElement); -+ PsiElement replacedExpression = replacedElement.getFirstChild(); -+ assert replacedExpression instanceof JetSimpleNameExpression; // assumption: the Kotlin class requires no imports -+ replacedExpressions.add((JetExpression) replacedExpression); -+ } -+ -+ if (replacedExpressions.size() == 0) { // if we didn't replace any usages, there's no reason to even give a choice","This condition is equivalent to usages.isEmpty(), which is more straightforward and can be checked before loop. -",Please avoid using `import *;` -155,"@@ -0,0 +1,207 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.codeInsight.template.*; -+import com.intellij.openapi.editor.CaretModel; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.project.Project; -+import com.intellij.psi.PsiDocumentManager; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.util.PsiTreeUtil; -+import com.intellij.refactoring.rename.inplace.MyLookupExpression; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.descriptors.ClassDescriptor; -+import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory1; -+import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1; -+import org.jetbrains.jet.lang.diagnostics.Errors; -+import org.jetbrains.jet.lang.psi.*; -+import org.jetbrains.jet.lang.resolve.BindingContext; -+import org.jetbrains.jet.plugin.JetBundle; -+import org.jetbrains.jet.plugin.caches.resolve.KotlinCacheManager; -+import org.jetbrains.jet.renderer.DescriptorRenderer; -+ -+import java.util.ArrayList; -+import java.util.Collection; -+import java.util.LinkedHashSet; -+import java.util.List; -+ -+public class MapPlatformClassToKotlinFix extends JetIntentionAction { -+ private static final String PRIMARY_USAGE = ""PrimaryUsage""; -+ private static final String OTHER_USAGE = ""OtherUsage""; -+ -+ private final ClassDescriptor platformClass; -+ private final Collection possibleClasses; -+ -+ public MapPlatformClassToKotlinFix(@NotNull JetReferenceExpression element, @NotNull ClassDescriptor platformClass, -+ @NotNull Collection possibleClasses) { -+ super(element); -+ this.platformClass = platformClass; -+ this.possibleClasses = possibleClasses; -+ } -+ -+ @NotNull -+ @Override -+ public String getText() { -+ -+ String platformClassQualifiedName = DescriptorRenderer.TEXT.renderType(platformClass.getDefaultType()); -+ return possibleClasses.size() == 1 -+ ? JetBundle.message(""map.platform.class.to.kotlin"", platformClassQualifiedName, -+ DescriptorRenderer.TEXT.renderType(possibleClasses.iterator().next().getDefaultType())) -+ : JetBundle.message(""map.platform.class.to.kotlin.multiple"", platformClassQualifiedName); -+ } -+ -+ @NotNull -+ @Override -+ public String getFamilyName() { -+ return JetBundle.message(""map.platform.class.to.kotlin.family""); -+ } -+ -+ @Override -+ public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { -+ BindingContext context = KotlinCacheManager.getInstance(project).getDeclarationsFromProject().getBindingContext(); -+ Collection diagnostics = context.getDiagnostics(); -+ List imports = new ArrayList(); -+ List usages = new ArrayList(); -+ -+ for (Diagnostic diagnostic : diagnostics) { -+ if (diagnostic.getFactory() != Errors.PLATFORM_CLASS_MAPPED_TO_KOTLIN) continue; -+ JetReferenceExpression refExpr = getImportOrUsageFromDiagnostic(diagnostic); -+ if (refExpr == null) continue; -+ DeclarationDescriptor descriptor = context.get(BindingContext.REFERENCE_TARGET, refExpr); -+ if (descriptor == null || !(descriptor.equals(platformClass))) continue; -+ JetImportDirective imp = PsiTreeUtil.getParentOfType(refExpr, JetImportDirective.class); -+ if (imp == null) { -+ JetUserType type = PsiTreeUtil.getParentOfType(refExpr, JetUserType.class); -+ if (type == null) continue; -+ usages.add(type); -+ } else { -+ imports.add(imp); -+ } -+ } -+ -+ ClassDescriptor replacementClass = possibleClasses.iterator().next(); -+ String replacementClassName = replacementClass.getName().getName(); -+ List replacedExpressions = new ArrayList(); -+ for (JetImportDirective imp : imports) { -+ imp.delete(); -+ } -+ for (JetUserType usage : usages) { -+ JetTypeArgumentList typeArguments = usage.getTypeArgumentList(); -+ String typeArgumentsString = typeArguments == null ? """" : typeArguments.getText(); -+ JetTypeReference replacementType = JetPsiFactory.createType(project, replacementClassName + typeArgumentsString); -+ JetTypeElement replacementTypeElement = replacementType.getTypeElement(); -+ assert replacementTypeElement != null; -+ PsiElement replacedElement = usage.replace(replacementTypeElement); -+ PsiElement replacedExpression = replacedElement.getFirstChild(); -+ assert replacedExpression instanceof JetSimpleNameExpression; // assumption: the Kotlin class requires no imports -+ replacedExpressions.add((JetExpression) replacedExpression); -+ } -+ -+ if (replacedExpressions.size() == 0) { // if we didn't replace any usages, there's no reason to even give a choice -+ return; -+ } -+ -+ if (possibleClasses.size() > 1) { -+ PsiDocumentManager.getInstance(project).commitAllDocuments(); -+ PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument()); -+ -+ PsiElement primaryReplacedExpression = replacedExpressions.iterator().next(); -+ -+ final CaretModel caretModel = editor.getCaretModel(); -+ final int oldOffset = caretModel.getOffset(); -+ caretModel.moveToOffset(file.getNode().getStartOffset()); -+ -+ LinkedHashSet possibleTypes = new LinkedHashSet(); -+ for (ClassDescriptor klass : possibleClasses) { -+ possibleTypes.add(klass.getName().getName()); -+ } -+ -+ TemplateBuilderImpl builder = new TemplateBuilderImpl(file); -+ Expression expression = new MyLookupExpression(primaryReplacedExpression.getText(), possibleTypes, null, false, -+ JetBundle.message(""map.platform.class.to.kotlin.advertisement"")); -+ -+ builder.replaceElement(primaryReplacedExpression, PRIMARY_USAGE, expression, true); -+ for (PsiElement replacedExpression : replacedExpressions) { -+ if (replacedExpression == primaryReplacedExpression) continue; -+ builder.replaceElement(replacedExpression, OTHER_USAGE, PRIMARY_USAGE, false); -+ } -+ TemplateManager.getInstance(project).startTemplate(editor, builder.buildInlineTemplate(), new TemplateEditingAdapter() { -+ @Override -+ public void templateFinished(Template template, boolean brokenOff) { -+ caretModel.moveToOffset(oldOffset); -+ } -+ }); -+ } -+ } -+ -+ private static JetReferenceExpression getImportOrUsageFromDiagnostic(@NotNull Diagnostic diagnostic) { -+ JetImportDirective imp = QuickFixUtil.getParentElementOfType(diagnostic, JetImportDirective.class); -+ JetReferenceExpression typeExpr; -+ if (imp == null) { -+ JetUserType type = QuickFixUtil.getParentElementOfType(diagnostic, JetUserType.class); -+ if (type == null) return null; -+ typeExpr = type.getReferenceExpression(); -+ } else { -+ JetExpression importRef = imp.getImportedReference(); -+ if (importRef == null || !(importRef instanceof JetDotQualifiedExpression)) return null; -+ JetExpression refExpr = ((JetDotQualifiedExpression) importRef).getSelectorExpression(); -+ if (refExpr == null || !(refExpr instanceof JetReferenceExpression)) return null; -+ typeExpr = (JetReferenceExpression) refExpr; -+ } -+ return typeExpr; -+ } -+ -+ public static JetIntentionActionFactory createFactory() { -+ return new JetIntentionActionFactory() { -+ @Nullable -+ @Override -+ public IntentionAction createAction(Diagnostic diagnostic) { -+ assert diagnostic.getFactory() instanceof DiagnosticFactory1; -+ -+ JetReferenceExpression typeExpr = getImportOrUsageFromDiagnostic(diagnostic); -+ if (typeExpr == null) return null; -+ -+ BindingContext context = KotlinCacheManager.getInstance(diagnostic.getPsiFile().getProject()).getDeclarationsFromProject().getBindingContext(); -+ DeclarationDescriptor descriptor = context.get(BindingContext.REFERENCE_TARGET, typeExpr); -+ if (descriptor == null || !(descriptor instanceof ClassDescriptor)) return null; -+ ClassDescriptor platformClass = (ClassDescriptor) descriptor; -+ -+ @SuppressWarnings(""unchecked"") -+ DiagnosticWithParameters1 parametrizedDiagnostic = (DiagnosticWithParameters1) diagnostic;","All the boilerplate starting from this line can be avoided by casting to DiagnosticWithParameters1> instead of raw type. -",Please avoid using `import *;` -156,"@@ -0,0 +1,208 @@ -+/* -+ * 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.j2k -+ -+import com.intellij.psi.CommonClassNames.* -+import com.intellij.psi.PsiField -+import org.jetbrains.kotlin.builtins.PrimitiveType -+import org.jetbrains.kotlin.j2k.ast.Expression -+import org.jetbrains.kotlin.j2k.ast.Identifier -+import org.jetbrains.kotlin.j2k.ast.QualifiedExpression -+ -+enum class SpecialFiled(val qualifiedClassName: String?, val fieldName: String) {","SpecialField -",Please annotate all the parameters with `@Nullable` -157,"@@ -0,0 +1,208 @@ -+/* -+ * 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.j2k -+ -+import com.intellij.psi.CommonClassNames.* -+import com.intellij.psi.PsiField -+import org.jetbrains.kotlin.builtins.PrimitiveType -+import org.jetbrains.kotlin.j2k.ast.Expression -+import org.jetbrains.kotlin.j2k.ast.Identifier -+import org.jetbrains.kotlin.j2k.ast.QualifiedExpression -+ -+enum class SpecialFiled(val qualifiedClassName: String?, val fieldName: String) { -+ -+ BYTE_MAX_VALUE(JAVA_LANG_BYTE, ""MAX_VALUE"") {","You should not hard-code all possible constants. -",Please annotate all the parameters with `@Nullable` -158,"@@ -0,0 +1,21 @@ -+//method","You need to include the generated test class into your commit. -",This file has nothing to do with this PR. -159,"@@ -0,0 +1,21 @@ -+//method -+void foo() {","Please try to ensure that testdata files are valid Java code. This file does not compile ('status' is undefined, the types do not match, etc.) -",missing new line at the end of file -160,"@@ -0,0 +1,21 @@ -+//method -+void foo() { -+ switch (status) { -+ case ""init"": -+ case ""dial"": -+ case ""transmit"": -+ return Color.BLACK; -+ -+ case ""ok"": -+ return 0xFF006600; -+ -+ case ""cancel"": -+ return 0xFF666666; -+ -+ case ""fail"": -+ case ""busy"": -+ case ""error"":","Please add a test for the case when 'default' is in the middle of the list of other cases (`case ""error"": default: case ""busy:""`) and make sure that this test passes. -","Rather than using the enum values for the status, just use the enum values for the status string and use the enum values for the enum values. The enum values are read-only, and the values are read-only." -161,"@@ -0,0 +1,212 @@ -+/* -+* Copyright 2010-2014 JetBrains s.r.o. -+* -+* Licensed under the Apache License, Version 2.0 (the ""License""); -+* you may not use this file except in compliance with the License. -+* You may obtain a copy of the License at -+* -+* http://www.apache.org/licenses/LICENSE-2.0 -+* -+* Unless required by applicable law or agreed to in writing, software -+* distributed under the License is distributed on an ""AS IS"" BASIS, -+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+* See the License for the specific language governing permissions and -+* limitations under the License. -+*/ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetPrefixExpression -+import org.jetbrains.jet.lang.psi.JetPostfixExpression -+import org.jetbrains.jet.lang.psi.JetBinaryExpression -+import org.jetbrains.jet.lang.psi.JetArrayAccessExpression -+import org.jetbrains.jet.lang.psi.JetCallExpression -+import org.jetbrains.jet.lexer.JetTokens -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetElement -+import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.resolve.BindingContext -+import org.jetbrains.jet.lang.psi.psiUtil.getQualifiedElementSelector -+import com.intellij.psi.util.PsiTreeUtil -+import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns -+import org.jetbrains.jet.lang.psi.JetFile -+ -+public class OperatorToFunctionIntention : JetSelfTargetingIntention(""operator.to.function"", javaClass()) { -+ fun isApplicablePrefix(element: JetPrefixExpression): Boolean { -+ return when (element.getOperationReference().getReferencedNameElementType()) { -+ JetTokens.PLUS, JetTokens.MINUS, JetTokens.PLUSPLUS, JetTokens.MINUSMINUS, JetTokens.EXCL -> true -+ else -> false -+ } -+ } -+ -+ fun isApplicablePostfix(element: JetPostfixExpression): Boolean { -+ return when (element.getOperationReference().getReferencedNameElementType()) { -+ JetTokens.PLUSPLUS, JetTokens.MINUSMINUS -> true -+ else -> false -+ } -+ } -+ -+ fun isApplicableBinary(element: JetBinaryExpression): Boolean { -+ return when (element.getOperationReference().getReferencedNameElementType()) { -+ JetTokens.PLUS, JetTokens.MINUS, JetTokens.MUL, JetTokens.DIV, JetTokens.PERC, JetTokens.RANGE, JetTokens.IN_KEYWORD, JetTokens.NOT_IN, JetTokens.PLUSEQ, JetTokens.MINUSEQ, JetTokens.MULTEQ, JetTokens.DIVEQ, JetTokens.PERCEQ, JetTokens.EQEQ, JetTokens.EXCLEQ, JetTokens.GT, JetTokens.LT, JetTokens.GTEQ, JetTokens.LTEQ -> true -+ JetTokens.EQ -> element.getLeft() is JetArrayAccessExpression -+ else -> false -+ } -+ } -+ -+ fun isApplicableArrayAccess(element: JetArrayAccessExpression): Boolean { -+ return true -+ } -+ -+ fun isApplicableCall(element: JetCallExpression): Boolean { -+ //element.getCalleeExpression()?.getClass()?.getMethods()?.forEach{println(""element has method "" + it.getName())} -+ //val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext() -+ //val calleeClass = context[BindingContext.CLASS, element.getCalleeExpression()] -+ //println(""calleeClass is "" + calleeClass?.getName()) -+ //calleeClass.javaClass.getMethods().forEach { println(""element has method "" + it.getName()) } -+ return element.getParent() !is JetDotQualifiedExpression && element.getValueArgumentList() != null","Basically, we need to retrieve ResolvedCall corresponding to call of interest and check if resulting function is `invoke`. - -``` -val resolvedCall = AnalyzerFacadeWithCache.getContextForElement(element)[BindingContext.RESOLVED_CALL, element.getCalleeExpression()] -val descriptor = resolvedCall?.getResultingDescriptor() -if (descriptor is FunctionDescriptor && descriptor.getName().asString == ""invoke"") { - // do whatever we need -} -``` -",please move intellij copyright year to header -162,"@@ -0,0 +1,212 @@ -+/* -+* Copyright 2010-2014 JetBrains s.r.o. -+* -+* Licensed under the Apache License, Version 2.0 (the ""License""); -+* you may not use this file except in compliance with the License. -+* You may obtain a copy of the License at -+* -+* http://www.apache.org/licenses/LICENSE-2.0 -+* -+* Unless required by applicable law or agreed to in writing, software -+* distributed under the License is distributed on an ""AS IS"" BASIS, -+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+* See the License for the specific language governing permissions and -+* limitations under the License. -+*/ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetPrefixExpression -+import org.jetbrains.jet.lang.psi.JetPostfixExpression -+import org.jetbrains.jet.lang.psi.JetBinaryExpression -+import org.jetbrains.jet.lang.psi.JetArrayAccessExpression -+import org.jetbrains.jet.lang.psi.JetCallExpression -+import org.jetbrains.jet.lexer.JetTokens -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetElement -+import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.resolve.BindingContext -+import org.jetbrains.jet.lang.psi.psiUtil.getQualifiedElementSelector -+import com.intellij.psi.util.PsiTreeUtil -+import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns -+import org.jetbrains.jet.lang.psi.JetFile -+ -+public class OperatorToFunctionIntention : JetSelfTargetingIntention(""operator.to.function"", javaClass()) { -+ fun isApplicablePrefix(element: JetPrefixExpression): Boolean { -+ return when (element.getOperationReference().getReferencedNameElementType()) { -+ JetTokens.PLUS, JetTokens.MINUS, JetTokens.PLUSPLUS, JetTokens.MINUSMINUS, JetTokens.EXCL -> true -+ else -> false -+ } -+ } -+ -+ fun isApplicablePostfix(element: JetPostfixExpression): Boolean { -+ return when (element.getOperationReference().getReferencedNameElementType()) { -+ JetTokens.PLUSPLUS, JetTokens.MINUSMINUS -> true -+ else -> false -+ } -+ } -+ -+ fun isApplicableBinary(element: JetBinaryExpression): Boolean { -+ return when (element.getOperationReference().getReferencedNameElementType()) { -+ JetTokens.PLUS, JetTokens.MINUS, JetTokens.MUL, JetTokens.DIV, JetTokens.PERC, JetTokens.RANGE, JetTokens.IN_KEYWORD, JetTokens.NOT_IN, JetTokens.PLUSEQ, JetTokens.MINUSEQ, JetTokens.MULTEQ, JetTokens.DIVEQ, JetTokens.PERCEQ, JetTokens.EQEQ, JetTokens.EXCLEQ, JetTokens.GT, JetTokens.LT, JetTokens.GTEQ, JetTokens.LTEQ -> true -+ JetTokens.EQ -> element.getLeft() is JetArrayAccessExpression -+ else -> false -+ } -+ } -+ -+ fun isApplicableArrayAccess(element: JetArrayAccessExpression): Boolean { -+ return true -+ } -+ -+ fun isApplicableCall(element: JetCallExpression): Boolean { -+ //element.getCalleeExpression()?.getClass()?.getMethods()?.forEach{println(""element has method "" + it.getName())} -+ //val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext() -+ //val calleeClass = context[BindingContext.CLASS, element.getCalleeExpression()] -+ //println(""calleeClass is "" + calleeClass?.getName()) -+ //calleeClass.javaClass.getMethods().forEach { println(""element has method "" + it.getName()) } -+ return element.getParent() !is JetDotQualifiedExpression && element.getValueArgumentList() != null -+ } -+ -+ override fun isApplicableTo(element: JetExpression): Boolean { -+ return when (element) { -+ is JetPrefixExpression -> isApplicablePrefix(element) -+ is JetPostfixExpression -> isApplicablePostfix(element) -+ is JetBinaryExpression -> isApplicableBinary(element) -+ is JetArrayAccessExpression -> isApplicableArrayAccess(element) -+ is JetCallExpression -> isApplicableCall(element) -+ else -> false -+ } -+ } -+ -+ -+ fun convertPrefix(element: JetPrefixExpression) { -+ val op = element.getOperationReference().getReferencedNameElementType() -+ val base = element.getBaseExpression()!!.getText() -+ -+ val call = when (op) { -+ JetTokens.PLUS -> ""plus()"" -+ JetTokens.MINUS -> ""minus()"" -+ JetTokens.PLUSPLUS -> ""inc()"" -+ JetTokens.MINUSMINUS -> ""dec()"" -+ JetTokens.EXCL -> ""not()"" -+ else -> return -+ } -+ -+ val transformation = ""$base.$call"" -+ val transformed = JetPsiFactory.createExpression(element.getProject(), transformation) -+ element.replace(transformed) -+ } -+ -+ fun convertPostFix(element: JetPostfixExpression) { -+ val op = element.getOperationReference().getReferencedNameElementType() -+ val base = element.getBaseExpression()!!.getText() -+ -+ val call = when (op) { -+ JetTokens.PLUSPLUS -> ""inc()"" -+ JetTokens.MINUSMINUS -> ""dec()"" -+ else -> return -+ } -+ -+ val transformation = ""$base.$call"" -+ val transformed = JetPsiFactory.createExpression(element.getProject(), transformation) -+ element.replace(transformed) -+ } -+ -+ fun convertBinary(element: JetBinaryExpression) { -+ val op = element.getOperationReference().getReferencedNameElementType() -+ val left = element.getLeft()!! -+ val right = element.getRight()!! -+ val leftText = left.getText() -+ val rightText = right.getText() -+ -+ if (op == JetTokens.EQ) { -+ if (left is JetArrayAccessExpression) { -+ convertArrayAccess(left as JetArrayAccessExpression) -+ } -+ return -+ } -+ -+ val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext()","This function is not available anymore. Please, rebase against current master and use `AnalyzerFacadeWithCache.getContextForElement(element)` instead -",please move intellij copyright year to header -163,"@@ -0,0 +1,212 @@ -+/* -+* Copyright 2010-2014 JetBrains s.r.o. -+* -+* Licensed under the Apache License, Version 2.0 (the ""License""); -+* you may not use this file except in compliance with the License. -+* You may obtain a copy of the License at -+* -+* http://www.apache.org/licenses/LICENSE-2.0 -+* -+* Unless required by applicable law or agreed to in writing, software -+* distributed under the License is distributed on an ""AS IS"" BASIS, -+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+* See the License for the specific language governing permissions and -+* limitations under the License. -+*/ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetPrefixExpression -+import org.jetbrains.jet.lang.psi.JetPostfixExpression -+import org.jetbrains.jet.lang.psi.JetBinaryExpression -+import org.jetbrains.jet.lang.psi.JetArrayAccessExpression -+import org.jetbrains.jet.lang.psi.JetCallExpression -+import org.jetbrains.jet.lexer.JetTokens -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetElement -+import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.resolve.BindingContext -+import org.jetbrains.jet.lang.psi.psiUtil.getQualifiedElementSelector -+import com.intellij.psi.util.PsiTreeUtil -+import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns -+import org.jetbrains.jet.lang.psi.JetFile -+ -+public class OperatorToFunctionIntention : JetSelfTargetingIntention(""operator.to.function"", javaClass()) { -+ fun isApplicablePrefix(element: JetPrefixExpression): Boolean { -+ return when (element.getOperationReference().getReferencedNameElementType()) { -+ JetTokens.PLUS, JetTokens.MINUS, JetTokens.PLUSPLUS, JetTokens.MINUSMINUS, JetTokens.EXCL -> true -+ else -> false -+ } -+ } -+ -+ fun isApplicablePostfix(element: JetPostfixExpression): Boolean { -+ return when (element.getOperationReference().getReferencedNameElementType()) { -+ JetTokens.PLUSPLUS, JetTokens.MINUSMINUS -> true -+ else -> false -+ } -+ } -+ -+ fun isApplicableBinary(element: JetBinaryExpression): Boolean { -+ return when (element.getOperationReference().getReferencedNameElementType()) { -+ JetTokens.PLUS, JetTokens.MINUS, JetTokens.MUL, JetTokens.DIV, JetTokens.PERC, JetTokens.RANGE, JetTokens.IN_KEYWORD, JetTokens.NOT_IN, JetTokens.PLUSEQ, JetTokens.MINUSEQ, JetTokens.MULTEQ, JetTokens.DIVEQ, JetTokens.PERCEQ, JetTokens.EQEQ, JetTokens.EXCLEQ, JetTokens.GT, JetTokens.LT, JetTokens.GTEQ, JetTokens.LTEQ -> true -+ JetTokens.EQ -> element.getLeft() is JetArrayAccessExpression -+ else -> false -+ } -+ } -+ -+ fun isApplicableArrayAccess(element: JetArrayAccessExpression): Boolean { -+ return true -+ } -+ -+ fun isApplicableCall(element: JetCallExpression): Boolean { -+ //element.getCalleeExpression()?.getClass()?.getMethods()?.forEach{println(""element has method "" + it.getName())} -+ //val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext() -+ //val calleeClass = context[BindingContext.CLASS, element.getCalleeExpression()] -+ //println(""calleeClass is "" + calleeClass?.getName()) -+ //calleeClass.javaClass.getMethods().forEach { println(""element has method "" + it.getName()) } -+ return element.getParent() !is JetDotQualifiedExpression && element.getValueArgumentList() != null -+ } -+ -+ override fun isApplicableTo(element: JetExpression): Boolean { -+ return when (element) { -+ is JetPrefixExpression -> isApplicablePrefix(element) -+ is JetPostfixExpression -> isApplicablePostfix(element) -+ is JetBinaryExpression -> isApplicableBinary(element) -+ is JetArrayAccessExpression -> isApplicableArrayAccess(element) -+ is JetCallExpression -> isApplicableCall(element) -+ else -> false -+ } -+ } -+ -+ -+ fun convertPrefix(element: JetPrefixExpression) { -+ val op = element.getOperationReference().getReferencedNameElementType() -+ val base = element.getBaseExpression()!!.getText() -+ -+ val call = when (op) { -+ JetTokens.PLUS -> ""plus()"" -+ JetTokens.MINUS -> ""minus()"" -+ JetTokens.PLUSPLUS -> ""inc()"" -+ JetTokens.MINUSMINUS -> ""dec()"" -+ JetTokens.EXCL -> ""not()"" -+ else -> return -+ } -+ -+ val transformation = ""$base.$call"" -+ val transformed = JetPsiFactory.createExpression(element.getProject(), transformation) -+ element.replace(transformed) -+ } -+ -+ fun convertPostFix(element: JetPostfixExpression) { -+ val op = element.getOperationReference().getReferencedNameElementType() -+ val base = element.getBaseExpression()!!.getText() -+ -+ val call = when (op) { -+ JetTokens.PLUSPLUS -> ""inc()"" -+ JetTokens.MINUSMINUS -> ""dec()"" -+ else -> return -+ } -+ -+ val transformation = ""$base.$call"" -+ val transformed = JetPsiFactory.createExpression(element.getProject(), transformation) -+ element.replace(transformed) -+ } -+ -+ fun convertBinary(element: JetBinaryExpression) { -+ val op = element.getOperationReference().getReferencedNameElementType() -+ val left = element.getLeft()!! -+ val right = element.getRight()!! -+ val leftText = left.getText() -+ val rightText = right.getText() -+ -+ if (op == JetTokens.EQ) { -+ if (left is JetArrayAccessExpression) { -+ convertArrayAccess(left as JetArrayAccessExpression) -+ } -+ return -+ } -+ -+ val context = AnalyzerFacadeWithCache.analyzeFileWithCache(element.getContainingFile() as JetFile).getBindingContext() -+ val functionCandidate = context[BindingContext.RESOLVED_CALL, element.getOperationReference()] -+ val functionName = functionCandidate?.getCandidateDescriptor()?.getName().toString() -+ -+ val elemType = context[BindingContext.EXPRESSION_TYPE, left] -+ -+ -+ val transformation = when (op) { -+ JetTokens.PLUS -> ""$leftText.plus($rightText)"" -+ JetTokens.MINUS -> ""$leftText.minus($rightText)"" -+ JetTokens.MUL -> ""$leftText.times($rightText)"" -+ JetTokens.DIV -> ""$leftText.div($rightText)"" -+ JetTokens.PERC -> ""$leftText.mod($rightText)"" -+ JetTokens.RANGE -> ""$leftText.rangeTo($rightText)"" -+ JetTokens.IN_KEYWORD -> ""$rightText.contains($leftText)"" -+ JetTokens.NOT_IN -> ""!$rightText.contains($leftText)"" -+ JetTokens.PLUSEQ -> if (functionName == ""plusAssign"") ""$leftText.plusAssign($rightText)"" else ""$leftText = $leftText.plus($rightText)"" -+ JetTokens.MINUSEQ -> if (functionName == ""minusAssign"") ""$leftText.minusAssign($rightText)"" else ""$leftText = $leftText.minus($rightText)"" -+ JetTokens.MULTEQ -> if (functionName == ""multAssign"") ""$leftText.multAssign($rightText)"" else ""$leftText = $leftText.mult($rightText)"" -+ JetTokens.DIVEQ -> if (functionName == ""divAssign"") ""$leftText.divAssign($rightText)"" else ""$leftText = $leftText.div($rightText)"" -+ JetTokens.PERCEQ -> if (functionName == ""modAssign"") ""$leftText.modAssign($rightText)"" else ""$leftText = $leftText.mod($rightText)"" -+ JetTokens.EQEQ -> (if (elemType?.isNullable() ?: true) ""$leftText?."" else ""$leftText."") + ""equals($rightText) ?: $rightText.identityEquals(null)""","It still produces unnecessary code. If `a` has a non-nullable type, `a == b` should be replaced by `a.equals(b)`, not `a.equals(b) ?: b.identityEquals(null)` -",please move intellij copyright year to header -164,"@@ -0,0 +1,22 @@ -+package demo -+ -+import com.google.common.primitives.Ints -+import com.google.common.base.Joiner -+import java.util.ArrayList -+ -+class KotlinGreetingJoiner(val greeter : Greeter) { -+ -+ val names = ArrayList() -+ -+ fun addName(name : String?): Unit{ -+ names.add(name) -+ } -+ -+ fun getJoinedGreeting() : String? { -+ val joiner = Joiner.on("" and "").skipNulls();","why do we need guava in such simple example? we can replace ugly `Joiner.on("" and "").skipNulls().join(names)` with `names.filterNotNull().joinToString("" and "")`. We also don't need `com.google.common.primitives.Ints` at all... -",You can remove this and use `new ArrayList()`. -165,"@@ -0,0 +1,227 @@ -+/* -+ * 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.javac -+ -+import com.intellij.ide.highlighter.JavaFileType -+import com.intellij.openapi.components.ServiceManager -+import com.intellij.openapi.fileTypes.FileType -+import com.intellij.openapi.project.Project -+import com.intellij.openapi.vfs.VirtualFile -+import com.intellij.psi.CommonClassNames -+import com.intellij.psi.search.EverythingGlobalScope -+import com.intellij.psi.search.GlobalSearchScope -+import com.sun.source.tree.CompilationUnitTree -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.api.JavacTrees -+import com.sun.tools.javac.code.Flags -+import com.sun.tools.javac.code.Symbol -+import com.sun.tools.javac.code.Symtab -+import com.sun.tools.javac.file.JavacFileManager -+import com.sun.tools.javac.jvm.ClassReader -+import com.sun.tools.javac.main.JavaCompiler -+import com.sun.tools.javac.model.JavacElements -+import com.sun.tools.javac.tree.JCTree -+import com.sun.tools.javac.util.Context -+import com.sun.tools.javac.util.Names -+import com.sun.tools.javac.util.Options -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity -+import org.jetbrains.kotlin.cli.common.messages.MessageCollector -+import com.sun.tools.javac.util.List as JavacList -+import org.jetbrains.kotlin.wrappers.symbols.JavacClass -+import org.jetbrains.kotlin.wrappers.symbols.JavacPackage -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.isSubpackageOf -+import org.jetbrains.kotlin.name.parentOrNull -+import org.jetbrains.kotlin.wrappers.trees.JCClass -+import org.jetbrains.kotlin.wrappers.trees.JCPackage -+import java.io.Closeable -+import java.io.File -+import javax.lang.model.element.TypeElement -+import javax.tools.JavaFileManager -+import javax.tools.JavaFileObject -+import javax.tools.StandardLocation -+ -+class Javac(javaFiles: Collection,",May be `JavaCompilerWrapper`?,"I don't really like this package name, but I don't have any better one." -166,"@@ -0,0 +1,227 @@ -+/* -+ * 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.javac -+ -+import com.intellij.ide.highlighter.JavaFileType -+import com.intellij.openapi.components.ServiceManager -+import com.intellij.openapi.fileTypes.FileType -+import com.intellij.openapi.project.Project -+import com.intellij.openapi.vfs.VirtualFile -+import com.intellij.psi.CommonClassNames -+import com.intellij.psi.search.EverythingGlobalScope -+import com.intellij.psi.search.GlobalSearchScope -+import com.sun.source.tree.CompilationUnitTree -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.api.JavacTrees -+import com.sun.tools.javac.code.Flags -+import com.sun.tools.javac.code.Symbol -+import com.sun.tools.javac.code.Symtab -+import com.sun.tools.javac.file.JavacFileManager -+import com.sun.tools.javac.jvm.ClassReader -+import com.sun.tools.javac.main.JavaCompiler -+import com.sun.tools.javac.model.JavacElements -+import com.sun.tools.javac.tree.JCTree -+import com.sun.tools.javac.util.Context -+import com.sun.tools.javac.util.Names -+import com.sun.tools.javac.util.Options -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity -+import org.jetbrains.kotlin.cli.common.messages.MessageCollector -+import com.sun.tools.javac.util.List as JavacList -+import org.jetbrains.kotlin.wrappers.symbols.JavacClass -+import org.jetbrains.kotlin.wrappers.symbols.JavacPackage -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.isSubpackageOf -+import org.jetbrains.kotlin.name.parentOrNull -+import org.jetbrains.kotlin.wrappers.trees.JCClass -+import org.jetbrains.kotlin.wrappers.trees.JCPackage -+import java.io.Closeable -+import java.io.File -+import javax.lang.model.element.TypeElement -+import javax.tools.JavaFileManager -+import javax.tools.JavaFileObject -+import javax.tools.StandardLocation -+ -+class Javac(javaFiles: Collection, -+ classPathRoots: List, -+ outDir: File?, -+ private val messageCollector: MessageCollector?, -+ arguments: Array?) : Closeable { -+ -+ companion object { -+ fun getInstance(project: Project): Javac = ServiceManager.getService(project, Javac::class.java) -+ } -+ -+ val JAVA_LANG_OBJECT by lazy { findClassInSymbols(CommonClassNames.JAVA_LANG_OBJECT) } -+ -+ private val context = Context() -+ -+ init { -+ messageCollector?.let { JavacLogger.preRegister(context, it) } -+ arguments?.toList()?.let { JavacOptionsMapper.map(Options.instance(context), it) } -+ } -+ -+ private val javac = object : JavaCompiler(context) { -+ override fun parseFiles(files: Iterable?) = compilationUnits -+ } -+ private val fileManager = context[JavaFileManager::class.java] as JavacFileManager -+ -+ init { -+ fileManager.setLocation(StandardLocation.CLASS_PATH, classPathRoots) -+ outDir?.let { -+ it.mkdirs() -+ fileManager.setLocation(StandardLocation.CLASS_OUTPUT, listOf(it)) -+ } -+ } -+ -+ private val symbols = Symtab.instance(context) -+ private val trees = JavacTrees.instance(context) -+ private val elements = JavacElements.instance(context) -+ private val fileObjects = fileManager.getJavaFileObjectsFromFiles(javaFiles).toJavacList() -+ private val compilationUnits: JavacList = fileObjects.map(javac::parse).toJavacList() -+ -+ private val javaClasses = compilationUnits -+ .flatMap { unit -> unit.typeDecls -+ .flatMap { JCClass(it as JCTree.JCClassDecl, trees.getPath(unit, it), this).withInnerClasses() } -+ } -+ .map { it.fqName to it } -+ .toMap()",There is `keysToMap` in Kotlin project itself & also `associateBy` in stdlib. I'm not sure it's quite important but they may be faster (one internal container instead of two) and definitely shorter.,"I don't really like this package name, but I don't have any better one." -167,"@@ -0,0 +1,227 @@ -+/* -+ * 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.javac -+ -+import com.intellij.ide.highlighter.JavaFileType -+import com.intellij.openapi.components.ServiceManager -+import com.intellij.openapi.fileTypes.FileType -+import com.intellij.openapi.project.Project -+import com.intellij.openapi.vfs.VirtualFile -+import com.intellij.psi.CommonClassNames -+import com.intellij.psi.search.EverythingGlobalScope -+import com.intellij.psi.search.GlobalSearchScope -+import com.sun.source.tree.CompilationUnitTree -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.api.JavacTrees -+import com.sun.tools.javac.code.Flags -+import com.sun.tools.javac.code.Symbol -+import com.sun.tools.javac.code.Symtab -+import com.sun.tools.javac.file.JavacFileManager -+import com.sun.tools.javac.jvm.ClassReader -+import com.sun.tools.javac.main.JavaCompiler -+import com.sun.tools.javac.model.JavacElements -+import com.sun.tools.javac.tree.JCTree -+import com.sun.tools.javac.util.Context -+import com.sun.tools.javac.util.Names -+import com.sun.tools.javac.util.Options -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity -+import org.jetbrains.kotlin.cli.common.messages.MessageCollector -+import com.sun.tools.javac.util.List as JavacList -+import org.jetbrains.kotlin.wrappers.symbols.JavacClass -+import org.jetbrains.kotlin.wrappers.symbols.JavacPackage -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.isSubpackageOf -+import org.jetbrains.kotlin.name.parentOrNull -+import org.jetbrains.kotlin.wrappers.trees.JCClass -+import org.jetbrains.kotlin.wrappers.trees.JCPackage -+import java.io.Closeable -+import java.io.File -+import javax.lang.model.element.TypeElement -+import javax.tools.JavaFileManager -+import javax.tools.JavaFileObject -+import javax.tools.StandardLocation -+ -+class Javac(javaFiles: Collection, -+ classPathRoots: List, -+ outDir: File?, -+ private val messageCollector: MessageCollector?, -+ arguments: Array?) : Closeable { -+ -+ companion object { -+ fun getInstance(project: Project): Javac = ServiceManager.getService(project, Javac::class.java) -+ } -+ -+ val JAVA_LANG_OBJECT by lazy { findClassInSymbols(CommonClassNames.JAVA_LANG_OBJECT) } -+ -+ private val context = Context() -+ -+ init { -+ messageCollector?.let { JavacLogger.preRegister(context, it) } -+ arguments?.toList()?.let { JavacOptionsMapper.map(Options.instance(context), it) } -+ } -+ -+ private val javac = object : JavaCompiler(context) { -+ override fun parseFiles(files: Iterable?) = compilationUnits -+ } -+ private val fileManager = context[JavaFileManager::class.java] as JavacFileManager -+ -+ init { -+ fileManager.setLocation(StandardLocation.CLASS_PATH, classPathRoots) -+ outDir?.let { -+ it.mkdirs() -+ fileManager.setLocation(StandardLocation.CLASS_OUTPUT, listOf(it)) -+ } -+ } -+ -+ private val symbols = Symtab.instance(context) -+ private val trees = JavacTrees.instance(context) -+ private val elements = JavacElements.instance(context) -+ private val fileObjects = fileManager.getJavaFileObjectsFromFiles(javaFiles).toJavacList() -+ private val compilationUnits: JavacList = fileObjects.map(javac::parse).toJavacList() -+ -+ private val javaClasses = compilationUnits -+ .flatMap { unit -> unit.typeDecls -+ .flatMap { JCClass(it as JCTree.JCClassDecl, trees.getPath(unit, it), this).withInnerClasses() } -+ } -+ .map { it.fqName to it } -+ .toMap() -+ -+ private val javaPackages = compilationUnits -+ .map { FqName(it.packageName.toString()) to JCPackage(it.packageName.toString(), this) } -+ .toMap()",See above,"I don't really like this package name, but I don't have any better one." -168,"@@ -0,0 +1,227 @@ -+/* -+ * 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.javac -+ -+import com.intellij.ide.highlighter.JavaFileType -+import com.intellij.openapi.components.ServiceManager -+import com.intellij.openapi.fileTypes.FileType -+import com.intellij.openapi.project.Project -+import com.intellij.openapi.vfs.VirtualFile -+import com.intellij.psi.CommonClassNames -+import com.intellij.psi.search.EverythingGlobalScope -+import com.intellij.psi.search.GlobalSearchScope -+import com.sun.source.tree.CompilationUnitTree -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.api.JavacTrees -+import com.sun.tools.javac.code.Flags -+import com.sun.tools.javac.code.Symbol -+import com.sun.tools.javac.code.Symtab -+import com.sun.tools.javac.file.JavacFileManager -+import com.sun.tools.javac.jvm.ClassReader -+import com.sun.tools.javac.main.JavaCompiler -+import com.sun.tools.javac.model.JavacElements -+import com.sun.tools.javac.tree.JCTree -+import com.sun.tools.javac.util.Context -+import com.sun.tools.javac.util.Names -+import com.sun.tools.javac.util.Options -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity -+import org.jetbrains.kotlin.cli.common.messages.MessageCollector -+import com.sun.tools.javac.util.List as JavacList -+import org.jetbrains.kotlin.wrappers.symbols.JavacClass -+import org.jetbrains.kotlin.wrappers.symbols.JavacPackage -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.isSubpackageOf -+import org.jetbrains.kotlin.name.parentOrNull -+import org.jetbrains.kotlin.wrappers.trees.JCClass -+import org.jetbrains.kotlin.wrappers.trees.JCPackage -+import java.io.Closeable -+import java.io.File -+import javax.lang.model.element.TypeElement -+import javax.tools.JavaFileManager -+import javax.tools.JavaFileObject -+import javax.tools.StandardLocation -+ -+class Javac(javaFiles: Collection, -+ classPathRoots: List, -+ outDir: File?, -+ private val messageCollector: MessageCollector?, -+ arguments: Array?) : Closeable { -+ -+ companion object { -+ fun getInstance(project: Project): Javac = ServiceManager.getService(project, Javac::class.java) -+ } -+ -+ val JAVA_LANG_OBJECT by lazy { findClassInSymbols(CommonClassNames.JAVA_LANG_OBJECT) } -+ -+ private val context = Context() -+ -+ init { -+ messageCollector?.let { JavacLogger.preRegister(context, it) } -+ arguments?.toList()?.let { JavacOptionsMapper.map(Options.instance(context), it) } -+ } -+ -+ private val javac = object : JavaCompiler(context) { -+ override fun parseFiles(files: Iterable?) = compilationUnits -+ } -+ private val fileManager = context[JavaFileManager::class.java] as JavacFileManager -+ -+ init { -+ fileManager.setLocation(StandardLocation.CLASS_PATH, classPathRoots) -+ outDir?.let { -+ it.mkdirs() -+ fileManager.setLocation(StandardLocation.CLASS_OUTPUT, listOf(it)) -+ } -+ } -+ -+ private val symbols = Symtab.instance(context) -+ private val trees = JavacTrees.instance(context) -+ private val elements = JavacElements.instance(context) -+ private val fileObjects = fileManager.getJavaFileObjectsFromFiles(javaFiles).toJavacList() -+ private val compilationUnits: JavacList = fileObjects.map(javac::parse).toJavacList() -+ -+ private val javaClasses = compilationUnits -+ .flatMap { unit -> unit.typeDecls -+ .flatMap { JCClass(it as JCTree.JCClassDecl, trees.getPath(unit, it), this).withInnerClasses() } -+ } -+ .map { it.fqName to it } -+ .toMap() -+ -+ private val javaPackages = compilationUnits -+ .map { FqName(it.packageName.toString()) to JCPackage(it.packageName.toString(), this) } -+ .toMap() -+ -+ fun compile() = with(javac) { -+ if (errorCount() > 0) return false -+ -+ fileManager.setClassPathForCompilation() -+ messageCollector?.report(CompilerMessageSeverity.INFO, -+ ""Compiling Java sources"", -+ CompilerMessageLocation.NO_LOCATION) -+ compile(fileObjects) -+ errorCount() == 0 -+ } -+ -+ override fun close() { -+ fileManager.close() -+ javac.close() -+ } -+ -+ fun findClass(fqName: FqName, scope: GlobalSearchScope = EverythingGlobalScope()) = when { -+ scope is EverythingGlobalScope -> javaClasses[fqName] ?: findClassInSymbols(fqName.asString()) -+ scope.contains(AnyJavaSourceVirtualFile) -> javaClasses[fqName]","I don't quite understand the idea with this object. As I can see, it's used in `contains` only. Who does put it into the scope?","I don't really like this package name, but I don't have any better one." -169,"@@ -0,0 +1,227 @@ -+/* -+ * 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.javac -+ -+import com.intellij.ide.highlighter.JavaFileType -+import com.intellij.openapi.components.ServiceManager -+import com.intellij.openapi.fileTypes.FileType -+import com.intellij.openapi.project.Project -+import com.intellij.openapi.vfs.VirtualFile -+import com.intellij.psi.CommonClassNames -+import com.intellij.psi.search.EverythingGlobalScope -+import com.intellij.psi.search.GlobalSearchScope -+import com.sun.source.tree.CompilationUnitTree -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.api.JavacTrees -+import com.sun.tools.javac.code.Flags -+import com.sun.tools.javac.code.Symbol -+import com.sun.tools.javac.code.Symtab -+import com.sun.tools.javac.file.JavacFileManager -+import com.sun.tools.javac.jvm.ClassReader -+import com.sun.tools.javac.main.JavaCompiler -+import com.sun.tools.javac.model.JavacElements -+import com.sun.tools.javac.tree.JCTree -+import com.sun.tools.javac.util.Context -+import com.sun.tools.javac.util.Names -+import com.sun.tools.javac.util.Options -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity -+import org.jetbrains.kotlin.cli.common.messages.MessageCollector -+import com.sun.tools.javac.util.List as JavacList -+import org.jetbrains.kotlin.wrappers.symbols.JavacClass -+import org.jetbrains.kotlin.wrappers.symbols.JavacPackage -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.isSubpackageOf -+import org.jetbrains.kotlin.name.parentOrNull -+import org.jetbrains.kotlin.wrappers.trees.JCClass -+import org.jetbrains.kotlin.wrappers.trees.JCPackage -+import java.io.Closeable -+import java.io.File -+import javax.lang.model.element.TypeElement -+import javax.tools.JavaFileManager -+import javax.tools.JavaFileObject -+import javax.tools.StandardLocation -+ -+class Javac(javaFiles: Collection, -+ classPathRoots: List, -+ outDir: File?, -+ private val messageCollector: MessageCollector?, -+ arguments: Array?) : Closeable { -+ -+ companion object { -+ fun getInstance(project: Project): Javac = ServiceManager.getService(project, Javac::class.java) -+ } -+ -+ val JAVA_LANG_OBJECT by lazy { findClassInSymbols(CommonClassNames.JAVA_LANG_OBJECT) } -+ -+ private val context = Context() -+ -+ init { -+ messageCollector?.let { JavacLogger.preRegister(context, it) } -+ arguments?.toList()?.let { JavacOptionsMapper.map(Options.instance(context), it) } -+ } -+ -+ private val javac = object : JavaCompiler(context) { -+ override fun parseFiles(files: Iterable?) = compilationUnits -+ } -+ private val fileManager = context[JavaFileManager::class.java] as JavacFileManager -+ -+ init { -+ fileManager.setLocation(StandardLocation.CLASS_PATH, classPathRoots) -+ outDir?.let { -+ it.mkdirs() -+ fileManager.setLocation(StandardLocation.CLASS_OUTPUT, listOf(it)) -+ } -+ } -+ -+ private val symbols = Symtab.instance(context) -+ private val trees = JavacTrees.instance(context) -+ private val elements = JavacElements.instance(context) -+ private val fileObjects = fileManager.getJavaFileObjectsFromFiles(javaFiles).toJavacList() -+ private val compilationUnits: JavacList = fileObjects.map(javac::parse).toJavacList() -+ -+ private val javaClasses = compilationUnits -+ .flatMap { unit -> unit.typeDecls -+ .flatMap { JCClass(it as JCTree.JCClassDecl, trees.getPath(unit, it), this).withInnerClasses() } -+ } -+ .map { it.fqName to it } -+ .toMap() -+ -+ private val javaPackages = compilationUnits -+ .map { FqName(it.packageName.toString()) to JCPackage(it.packageName.toString(), this) } -+ .toMap() -+ -+ fun compile() = with(javac) { -+ if (errorCount() > 0) return false -+ -+ fileManager.setClassPathForCompilation() -+ messageCollector?.report(CompilerMessageSeverity.INFO, -+ ""Compiling Java sources"", -+ CompilerMessageLocation.NO_LOCATION) -+ compile(fileObjects) -+ errorCount() == 0 -+ } -+ -+ override fun close() { -+ fileManager.close() -+ javac.close() -+ } -+ -+ fun findClass(fqName: FqName, scope: GlobalSearchScope = EverythingGlobalScope()) = when { -+ scope is EverythingGlobalScope -> javaClasses[fqName] ?: findClassInSymbols(fqName.asString()) -+ scope.contains(AnyJavaSourceVirtualFile) -> javaClasses[fqName] -+ else -> findClassInSymbols(fqName.asString()) ?: javaClasses[fqName] -+ } -+ -+ fun findPackage(fqName: FqName, scope: GlobalSearchScope) = when { -+ scope is EverythingGlobalScope -> javaPackages[fqName] ?: findPackageInSymbols(fqName.asString()) -+ scope.contains(AnyJavaSourceVirtualFile) -> javaPackages[fqName] -+ else -> findPackageInSymbols(fqName.asString()) ?: javaPackages[fqName] -+ } -+ -+ fun findSubPackages(fqName: FqName) = symbols.packages -+ .filter { (k, _) -> k.toString().startsWith(""$fqName."") } -+ .map { JavacPackage(it.value, this) } + -+ javaPackages -+ .filter { it.key.isSubpackageOf(fqName) && it.key != fqName } -+ .map { it.value }",There is `filterValues`.,"I don't really like this package name, but I don't have any better one." -170,"@@ -0,0 +1,227 @@ -+/* -+ * 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.javac -+ -+import com.intellij.ide.highlighter.JavaFileType -+import com.intellij.openapi.components.ServiceManager -+import com.intellij.openapi.fileTypes.FileType -+import com.intellij.openapi.project.Project -+import com.intellij.openapi.vfs.VirtualFile -+import com.intellij.psi.CommonClassNames -+import com.intellij.psi.search.EverythingGlobalScope -+import com.intellij.psi.search.GlobalSearchScope -+import com.sun.source.tree.CompilationUnitTree -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.api.JavacTrees -+import com.sun.tools.javac.code.Flags -+import com.sun.tools.javac.code.Symbol -+import com.sun.tools.javac.code.Symtab -+import com.sun.tools.javac.file.JavacFileManager -+import com.sun.tools.javac.jvm.ClassReader -+import com.sun.tools.javac.main.JavaCompiler -+import com.sun.tools.javac.model.JavacElements -+import com.sun.tools.javac.tree.JCTree -+import com.sun.tools.javac.util.Context -+import com.sun.tools.javac.util.Names -+import com.sun.tools.javac.util.Options -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity -+import org.jetbrains.kotlin.cli.common.messages.MessageCollector -+import com.sun.tools.javac.util.List as JavacList -+import org.jetbrains.kotlin.wrappers.symbols.JavacClass -+import org.jetbrains.kotlin.wrappers.symbols.JavacPackage -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.isSubpackageOf -+import org.jetbrains.kotlin.name.parentOrNull -+import org.jetbrains.kotlin.wrappers.trees.JCClass -+import org.jetbrains.kotlin.wrappers.trees.JCPackage -+import java.io.Closeable -+import java.io.File -+import javax.lang.model.element.TypeElement -+import javax.tools.JavaFileManager -+import javax.tools.JavaFileObject -+import javax.tools.StandardLocation -+ -+class Javac(javaFiles: Collection, -+ classPathRoots: List, -+ outDir: File?, -+ private val messageCollector: MessageCollector?, -+ arguments: Array?) : Closeable { -+ -+ companion object { -+ fun getInstance(project: Project): Javac = ServiceManager.getService(project, Javac::class.java) -+ } -+ -+ val JAVA_LANG_OBJECT by lazy { findClassInSymbols(CommonClassNames.JAVA_LANG_OBJECT) } -+ -+ private val context = Context() -+ -+ init { -+ messageCollector?.let { JavacLogger.preRegister(context, it) } -+ arguments?.toList()?.let { JavacOptionsMapper.map(Options.instance(context), it) } -+ } -+ -+ private val javac = object : JavaCompiler(context) { -+ override fun parseFiles(files: Iterable?) = compilationUnits -+ } -+ private val fileManager = context[JavaFileManager::class.java] as JavacFileManager -+ -+ init { -+ fileManager.setLocation(StandardLocation.CLASS_PATH, classPathRoots) -+ outDir?.let { -+ it.mkdirs() -+ fileManager.setLocation(StandardLocation.CLASS_OUTPUT, listOf(it)) -+ } -+ } -+ -+ private val symbols = Symtab.instance(context) -+ private val trees = JavacTrees.instance(context) -+ private val elements = JavacElements.instance(context) -+ private val fileObjects = fileManager.getJavaFileObjectsFromFiles(javaFiles).toJavacList() -+ private val compilationUnits: JavacList = fileObjects.map(javac::parse).toJavacList() -+ -+ private val javaClasses = compilationUnits -+ .flatMap { unit -> unit.typeDecls -+ .flatMap { JCClass(it as JCTree.JCClassDecl, trees.getPath(unit, it), this).withInnerClasses() } -+ } -+ .map { it.fqName to it } -+ .toMap() -+ -+ private val javaPackages = compilationUnits -+ .map { FqName(it.packageName.toString()) to JCPackage(it.packageName.toString(), this) } -+ .toMap() -+ -+ fun compile() = with(javac) { -+ if (errorCount() > 0) return false -+ -+ fileManager.setClassPathForCompilation() -+ messageCollector?.report(CompilerMessageSeverity.INFO, -+ ""Compiling Java sources"", -+ CompilerMessageLocation.NO_LOCATION) -+ compile(fileObjects) -+ errorCount() == 0 -+ } -+ -+ override fun close() { -+ fileManager.close() -+ javac.close() -+ } -+ -+ fun findClass(fqName: FqName, scope: GlobalSearchScope = EverythingGlobalScope()) = when { -+ scope is EverythingGlobalScope -> javaClasses[fqName] ?: findClassInSymbols(fqName.asString()) -+ scope.contains(AnyJavaSourceVirtualFile) -> javaClasses[fqName] -+ else -> findClassInSymbols(fqName.asString()) ?: javaClasses[fqName] -+ } -+ -+ fun findPackage(fqName: FqName, scope: GlobalSearchScope) = when { -+ scope is EverythingGlobalScope -> javaPackages[fqName] ?: findPackageInSymbols(fqName.asString()) -+ scope.contains(AnyJavaSourceVirtualFile) -> javaPackages[fqName] -+ else -> findPackageInSymbols(fqName.asString()) ?: javaPackages[fqName] -+ } -+ -+ fun findSubPackages(fqName: FqName) = symbols.packages -+ .filter { (k, _) -> k.toString().startsWith(""$fqName."") } -+ .map { JavacPackage(it.value, this) } + -+ javaPackages -+ .filter { it.key.isSubpackageOf(fqName) && it.key != fqName } -+ .map { it.value } -+ -+ fun findClassesFromPackage(fqName: FqName) = javaClasses.filter { it.key?.parentOrNull() == fqName } -+ .flatMap { it.value.withInnerClasses() } + -+ elements.getPackageElement(fqName.asString()) -+ ?.members() -+ ?.elements -+ ?.filterIsInstance(TypeElement::class.java) -+ ?.map { JavacClass(it, this) } -+ .orEmpty() -+ -+ fun getTreePath(tree: JCTree, compilationUnit: CompilationUnitTree): TreePath = trees.getPath(compilationUnit, tree) -+ -+ private inline fun Iterable.toJavacList() = JavacList.from(this) -+ -+ private fun findClassInSymbols(fqName: String) = elements.getTypeElement(fqName)?.let { JavacClass(it, this) } -+ -+ private fun findPackageInSymbols(fqName: String) = elements.getPackageElement(fqName)?.let { JavacPackage(it, this) } -+ -+ private fun JavacFileManager.setClassPathForCompilation() = apply { -+ setLocation(StandardLocation.CLASS_PATH, -+ getLocation(StandardLocation.CLASS_PATH) + getLocation(StandardLocation.CLASS_OUTPUT)) -+ -+ val reader = ClassReader.instance(context) -+ val names = Names.instance(context) -+ val outDirName = getLocation(StandardLocation.CLASS_OUTPUT).firstOrNull()?.path ?: """" -+ -+ list(StandardLocation.CLASS_OUTPUT, """", setOf(JavaFileObject.Kind.CLASS), true) -+ .forEach { -+ val fqName = it.name -+ .substringAfter(outDirName) -+ .substringBefore("".class"") -+ .replace(""/"", ""."") -+ .let { if (it.startsWith(""."")) it.substring(1) else it } -+ .let(names::fromString) -+ -+ symbols.classes[fqName]?.let { symbols.classes[fqName] = null } -+ val symbol = reader.enterClass(fqName, it) -+ -+ (elements.getPackageOf(symbol) as? Symbol.PackageSymbol)?.let { -+ it.members_field.enter(symbol) -+ it.flags_field = it.flags_field or Flags.EXISTS.toLong() -+ } -+ } -+ -+ } -+ -+ private fun JavaClass.withInnerClasses(): List = listOf(this) + innerClasses.flatMap { it.withInnerClasses() } -+ -+} -+ -+private object AnyJavaSourceVirtualFile : VirtualFile() { -+ override fun refresh(asynchronous: Boolean, recursive: Boolean, postRunnable: Runnable?) {} -+ -+ override fun getLength() = 0L -+ -+ override fun getFileSystem() = throw UnsupportedOperationException()","May be (if you need this object at all) it's better to provide some message like `""Should never be called""`. ","I don't really like this package name, but I don't have any better one." -171,"@@ -0,0 +1,24 @@ -+/* -+ * 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.effectsystem.factories -+ -+import org.jetbrains.kotlin.effectsystem.structure.ESBooleanExpression -+import org.jetbrains.kotlin.effectsystem.structure.ESClause -+import org.jetbrains.kotlin.effectsystem.structure.ESEffect -+ -+fun createClause(premise: ESBooleanExpression, conclusion: ESEffect) = ESClause(premise, conclusion) -+fun createUnconditionalClause(effect: ESEffect): ESClause = ESClause(true.lift(), effect)","Why do we need this `unconditionalClause`? As far as I understand it's interpreted as ""if effect takes place then true is true"", and this statement is always true.",missing new line at the end of file -172,"@@ -0,0 +1,240 @@ -+@file:kotlin.jvm.JvmMultifileClass -+@file:kotlin.jvm.JvmName(""StringsKt"") -+@file:Suppress(""PLATFORM_CLASS_MAPPED_TO_KOTLIN"") -+ -+package kotlin.text -+ -+ -+/** -+ * Returns `true` if the contents of this string is equal to the word ""true"", ignoring case, and `false` otherwise. -+ */ -+@kotlin.internal.InlineOnly -+public inline fun String.toBoolean(): Boolean = java.lang.Boolean.parseBoolean(this) -+ -+/** -+ * Parses the string as a signed [Byte] number and returns the result. -+ * @throws NumberFormatException if the string is not a valid representation of a number. -+ */ -+@kotlin.internal.InlineOnly -+public inline fun String.toByte(radix: Int = 10): Byte = java.lang.Byte.parseByte(this, radix) -+ -+/** -+ * Parses the string as a [Short] number and returns the result. -+ * @throws NumberFormatException if the string is not a valid representation of a number. -+ */ -+@kotlin.internal.InlineOnly -+public inline fun String.toShort(radix: Int = 10): Short = java.lang.Short.parseShort(this, radix) -+ -+/** -+ * Parses the string as an [Int] number and returns the result. -+ * @throws NumberFormatException if the string is not a valid representation of a number. -+ */ -+@kotlin.internal.InlineOnly -+public inline fun String.toInt(radix: Int = 10): Int = java.lang.Integer.parseInt(this, radix) -+ -+/** -+ * Parses the string as a [Long] number and returns the result. -+ * @throws NumberFormatException if the string is not a valid representation of a number. -+ */ -+@kotlin.internal.InlineOnly -+public inline fun String.toLong(radix: Int = 10): Long = java.lang.Long.parseLong(this, radix) -+ -+/** -+ * Parses the string as a [Float] number and returns the result. -+ * @throws NumberFormatException if the string is not a valid representation of a number. -+ */ -+@kotlin.internal.InlineOnly -+public inline fun String.toFloat(radix: Int = 10): Float = java.lang.Float.parseFloat(this)","Radix parameter seems to be unused -",I am wondering if this should be `Number` instead of `String`... -173,"@@ -0,0 +1,240 @@ -+@file:kotlin.jvm.JvmMultifileClass -+@file:kotlin.jvm.JvmName(""StringsKt"") -+@file:Suppress(""PLATFORM_CLASS_MAPPED_TO_KOTLIN"") -+ -+package kotlin.text -+ -+ -+/** -+ * Returns `true` if the contents of this string is equal to the word ""true"", ignoring case, and `false` otherwise. -+ */ -+@kotlin.internal.InlineOnly -+public inline fun String.toBoolean(): Boolean = java.lang.Boolean.parseBoolean(this) -+ -+/** -+ * Parses the string as a signed [Byte] number and returns the result. -+ * @throws NumberFormatException if the string is not a valid representation of a number. -+ */ -+@kotlin.internal.InlineOnly -+public inline fun String.toByte(radix: Int = 10): Byte = java.lang.Byte.parseByte(this, radix) -+ -+/** -+ * Parses the string as a [Short] number and returns the result. -+ * @throws NumberFormatException if the string is not a valid representation of a number. -+ */ -+@kotlin.internal.InlineOnly -+public inline fun String.toShort(radix: Int = 10): Short = java.lang.Short.parseShort(this, radix) -+ -+/** -+ * Parses the string as an [Int] number and returns the result. -+ * @throws NumberFormatException if the string is not a valid representation of a number. -+ */ -+@kotlin.internal.InlineOnly -+public inline fun String.toInt(radix: Int = 10): Int = java.lang.Integer.parseInt(this, radix) -+ -+/** -+ * Parses the string as a [Long] number and returns the result. -+ * @throws NumberFormatException if the string is not a valid representation of a number. -+ */ -+@kotlin.internal.InlineOnly -+public inline fun String.toLong(radix: Int = 10): Long = java.lang.Long.parseLong(this, radix) -+ -+/** -+ * Parses the string as a [Float] number and returns the result. -+ * @throws NumberFormatException if the string is not a valid representation of a number. -+ */ -+@kotlin.internal.InlineOnly -+public inline fun String.toFloat(radix: Int = 10): Float = java.lang.Float.parseFloat(this) -+ -+/** -+ * Parses the string as a [Double] number and returns the result. -+ * @throws NumberFormatException if the string is not a valid representation of a number. -+ */ -+@kotlin.internal.InlineOnly -+public inline fun String.toDouble(radix: Int = 10): Double = java.lang.Double.parseDouble(this)","Radix parameter seems to be unused -",I am wondering if this should be `Number` instead of `String`... -174,"@@ -0,0 +1,243 @@ -+/* -+ * 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.javac -+ -+import com.intellij.ide.highlighter.JavaFileType -+import com.intellij.openapi.components.ServiceManager -+import com.intellij.openapi.fileTypes.FileType -+import com.intellij.openapi.project.Project -+import com.intellij.openapi.vfs.VirtualFile -+import com.intellij.psi.CommonClassNames -+import com.intellij.psi.search.EverythingGlobalScope -+import com.intellij.psi.search.GlobalSearchScope","I think it would be nice to move parts of this class that use `com.intellij.openapi` to other compiler modules, to get rid of dependency of module `javac-wrapper` on `openapi`. This can be done in the future, I suppose.",Is this file supposed to be in this PR? -175,"@@ -0,0 +1,243 @@ -+/* -+ * 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.javac -+ -+import com.intellij.ide.highlighter.JavaFileType -+import com.intellij.openapi.components.ServiceManager -+import com.intellij.openapi.fileTypes.FileType -+import com.intellij.openapi.project.Project -+import com.intellij.openapi.vfs.VirtualFile -+import com.intellij.psi.CommonClassNames -+import com.intellij.psi.search.EverythingGlobalScope -+import com.intellij.psi.search.GlobalSearchScope -+import com.sun.source.tree.CompilationUnitTree -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.api.JavacTrees -+import com.sun.tools.javac.code.Flags -+import com.sun.tools.javac.code.Symbol -+import com.sun.tools.javac.code.Symtab -+import com.sun.tools.javac.file.JavacFileManager -+import com.sun.tools.javac.jvm.ClassReader -+import com.sun.tools.javac.main.JavaCompiler -+import com.sun.tools.javac.model.JavacElements -+import com.sun.tools.javac.model.JavacTypes -+import com.sun.tools.javac.tree.JCTree -+import com.sun.tools.javac.util.Context -+import com.sun.tools.javac.util.Names -+import com.sun.tools.javac.util.Options -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity -+import org.jetbrains.kotlin.cli.common.messages.MessageCollector -+import org.jetbrains.kotlin.config.CompilerConfiguration -+import org.jetbrains.kotlin.config.JVMConfigurationKeys -+import com.sun.tools.javac.util.List as JavacList -+import org.jetbrains.kotlin.wrappers.symbols.SymbolBasedClass -+import org.jetbrains.kotlin.wrappers.symbols.SymbolBasedPackage -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.isSubpackageOf -+import org.jetbrains.kotlin.name.parentOrNull -+import org.jetbrains.kotlin.psi.KtFile -+import org.jetbrains.kotlin.wrappers.trees.TreeBasedClass -+import org.jetbrains.kotlin.wrappers.trees.TreeBasedPackage -+import org.jetbrains.kotlin.wrappers.trees.TreePathResolverCache -+import java.io.Closeable -+import java.io.File -+import javax.lang.model.element.Element -+import javax.lang.model.element.TypeElement -+import javax.lang.model.type.TypeMirror -+import javax.tools.JavaFileManager -+import javax.tools.JavaFileObject -+import javax.tools.StandardLocation -+ -+class JavacWrapper(javaFiles: Collection,","Since you're passing `CompilerConfiguration` here, there's no need to pass `classPathRoots` and `messageCollector` separately because in production code, they can be trivially obtained from the configuration (and tests can be adapted to mimic that)","I don't really like this package name, but I don't have any better one." -176,"@@ -0,0 +1,243 @@ -+/* -+ * 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.javac -+ -+import com.intellij.ide.highlighter.JavaFileType -+import com.intellij.openapi.components.ServiceManager -+import com.intellij.openapi.fileTypes.FileType -+import com.intellij.openapi.project.Project -+import com.intellij.openapi.vfs.VirtualFile -+import com.intellij.psi.CommonClassNames -+import com.intellij.psi.search.EverythingGlobalScope -+import com.intellij.psi.search.GlobalSearchScope -+import com.sun.source.tree.CompilationUnitTree -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.api.JavacTrees -+import com.sun.tools.javac.code.Flags -+import com.sun.tools.javac.code.Symbol -+import com.sun.tools.javac.code.Symtab -+import com.sun.tools.javac.file.JavacFileManager -+import com.sun.tools.javac.jvm.ClassReader -+import com.sun.tools.javac.main.JavaCompiler -+import com.sun.tools.javac.model.JavacElements -+import com.sun.tools.javac.model.JavacTypes -+import com.sun.tools.javac.tree.JCTree -+import com.sun.tools.javac.util.Context -+import com.sun.tools.javac.util.Names -+import com.sun.tools.javac.util.Options -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity -+import org.jetbrains.kotlin.cli.common.messages.MessageCollector -+import org.jetbrains.kotlin.config.CompilerConfiguration -+import org.jetbrains.kotlin.config.JVMConfigurationKeys -+import com.sun.tools.javac.util.List as JavacList -+import org.jetbrains.kotlin.wrappers.symbols.SymbolBasedClass -+import org.jetbrains.kotlin.wrappers.symbols.SymbolBasedPackage -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.isSubpackageOf -+import org.jetbrains.kotlin.name.parentOrNull -+import org.jetbrains.kotlin.psi.KtFile -+import org.jetbrains.kotlin.wrappers.trees.TreeBasedClass -+import org.jetbrains.kotlin.wrappers.trees.TreeBasedPackage -+import org.jetbrains.kotlin.wrappers.trees.TreePathResolverCache -+import java.io.Closeable -+import java.io.File -+import javax.lang.model.element.Element -+import javax.lang.model.element.TypeElement -+import javax.lang.model.type.TypeMirror -+import javax.tools.JavaFileManager -+import javax.tools.JavaFileObject -+import javax.tools.StandardLocation -+ -+class JavacWrapper(javaFiles: Collection, -+ kotlinFiles: Collection, -+ classPathRoots: List, -+ private val configuration: CompilerConfiguration, -+ private val messageCollector: MessageCollector?, -+ arguments: Array?) : Closeable { -+ -+ companion object { -+ fun getInstance(project: Project): JavacWrapper = ServiceManager.getService(project, JavacWrapper::class.java) -+ } -+ -+ val JAVA_LANG_OBJECT by lazy { findClassInSymbols(CommonClassNames.JAVA_LANG_OBJECT) } -+ -+ private val context = Context() -+ -+ init { -+ messageCollector?.let { JavacLogger.preRegister(context, it) } -+ arguments?.toList()?.let { JavacOptionsMapper.map(Options.instance(context), it) } -+ } -+ -+ private val javac = object : JavaCompiler(context) { -+ override fun parseFiles(files: Iterable?) = compilationUnits -+ } -+ private val fileManager = context[JavaFileManager::class.java] as JavacFileManager -+ -+ init { -+ fileManager.setLocation(StandardLocation.CLASS_PATH, classPathRoots) -+ } -+ -+ private val symbols = Symtab.instance(context) -+ private val trees = JavacTrees.instance(context) -+ private val elements = JavacElements.instance(context) -+ private val types = JavacTypes.instance(context) -+ private val fileObjects = fileManager.getJavaFileObjectsFromFiles(javaFiles).toJavacList() -+ private val compilationUnits: JavacList = fileObjects.map(javac::parse).toJavacList() -+ -+ private val javaClasses = compilationUnits -+ .flatMap { unit -> unit.typeDecls -+ .flatMap { TreeBasedClass(it as JCTree.JCClassDecl, trees.getPath(unit, it), this).withInnerClasses() } -+ } -+ .associateBy(JavaClass::fqName) -+ -+ private val javaPackages = compilationUnits -+ .map { TreeBasedPackage(it.packageName.toString(), this) } -+ .associateBy(TreeBasedPackage::fqName) -+ -+ private val kotlinClassifiersCache = KotlinClassifiersCache(kotlinFiles, this) -+ private val treePathResolverCache = TreePathResolverCache(this) -+ -+ fun compile(outDir: File? = null) = with(javac) { -+ if (errorCount() > 0) return false -+ -+ fileManager.setClassPathForCompilation(outDir) -+ messageCollector?.report(CompilerMessageSeverity.INFO, -+ ""Compiling Java sources"") -+ compile(fileObjects) -+ errorCount() == 0 -+ } -+ -+ override fun close() { -+ fileManager.close() -+ javac.close() -+ } -+ -+ fun findClass(fqName: FqName, scope: GlobalSearchScope = EverythingGlobalScope()) = when { -+ scope is EverythingGlobalScope -> javaClasses[fqName] ?: findClassInSymbols(fqName.asString())","Using `instanceof` on `GlobalSearchScope` is very risky and should be avoided at all costs. For example, if I wrap the everything-scope twice into the not-scope: -``` -GlobalSearchScope.notScope(GlobalSearchScope.notScope( - GlobalSearchScope.allScope(project) -)) -``` -The resulting scope will be effectively the same, but your code won't work anymore because it would be another instance. - -Also, relying on specific scopes being passed here (like a scope with all .java files) is risky as well, because we might reconfigure the compiler in such a way that the compiled module is split into a different set of scopes in the near future.","I don't really like this package name, but I don't have any better one." -177,"@@ -0,0 +1,25 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+public enum class ExpressionKind(val output: String) { -+ IF : ExpressionKind(""if"") -+ ELSE : ExpressionKind(""else"") -+ WHILE : ExpressionKind(""while"") -+ DOWHILE : ExpressionKind(""do...while"") -+ FOR : ExpressionKind(""for"") -+}","Storing string representation in enum is a good idea. -I think this enum shouldn't be public and is better to put it near corresponding methods in Utils.kt -",What is the purpose of this enum? -178,"@@ -0,0 +1,25 @@ -+/* -+ * Copyright 2010-2015 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.kotlin.psi; -+ -+import com.intellij.psi.PsiElement; -+import org.jetbrains.annotations.Nullable; -+ -+public interface KtValVarKeywordProvider extends PsiElement {","""Provider"" is not a great name for it, I think -",Make all methods `extends PsiElement` -179,"@@ -0,0 +1,255 @@ -+/* -+ * 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.compilerRunner -+ -+import com.intellij.openapi.util.text.StringUtil -+import com.intellij.util.ArrayUtil -+import com.intellij.util.Function -+import com.intellij.util.containers.ContainerUtil -+import com.intellij.util.xmlb.XmlSerializerUtil -+import org.jetbrains.kotlin.cli.common.ExitCode -+import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments -+import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments -+import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.INFO -+import org.jetbrains.kotlin.cli.common.messages.MessageCollector -+import org.jetbrains.kotlin.cli.common.messages.MessageCollectorUtil -+import org.jetbrains.kotlin.config.CompilerSettings -+import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents -+import org.jetbrains.kotlin.progress.CompilationCanceledStatus -+import org.jetbrains.kotlin.rmi.CompilerId -+import org.jetbrains.kotlin.rmi.configureDaemonJVMOptions -+import org.jetbrains.kotlin.rmi.configureDaemonOptions -+import org.jetbrains.kotlin.rmi.isDaemonEnabled -+import org.jetbrains.kotlin.rmi.kotlinr.* -+import org.jetbrains.kotlin.utils.rethrow -+import java.io.* -+import java.lang.reflect.Field -+import java.lang.reflect.Modifier -+import java.util.* -+ -+public object KotlinCompilerRunner { -+ private val K2JVM_COMPILER = ""org.jetbrains.kotlin.cli.jvm.K2JVMCompiler"" -+ private val K2JS_COMPILER = ""org.jetbrains.kotlin.cli.js.K2JSCompiler"" -+ private val INTERNAL_ERROR = ExitCode.INTERNAL_ERROR.toString() -+ -+ public fun runK2JvmCompiler( -+ commonArguments: CommonCompilerArguments, -+ k2jvmArguments: K2JVMCompilerArguments, -+ compilerSettings: CompilerSettings, -+ messageCollector: MessageCollector, -+ environment: CompilerEnvironment, -+ moduleFile: File, -+ collector: OutputItemsCollector) { -+ val arguments = mergeBeans(commonArguments, k2jvmArguments) -+ setupK2JvmArguments(moduleFile, arguments) -+ -+ runCompiler(K2JVM_COMPILER, arguments, compilerSettings.additionalArguments, messageCollector, collector, environment) -+ } -+ -+ public fun runK2JsCompiler( -+ commonArguments: CommonCompilerArguments, -+ k2jsArguments: K2JSCompilerArguments, -+ compilerSettings: CompilerSettings, -+ messageCollector: MessageCollector, -+ environment: CompilerEnvironment, -+ collector: OutputItemsCollector, -+ sourceFiles: Collection, -+ libraryFiles: List, -+ outputFile: File) { -+ val arguments = mergeBeans(commonArguments, k2jsArguments) -+ setupK2JsArguments(outputFile, sourceFiles, libraryFiles, arguments) -+ -+ runCompiler(K2JS_COMPILER, arguments, compilerSettings.additionalArguments, messageCollector, collector, environment) -+ } -+ -+ private fun ProcessCompilerOutput(","Not related to changes, but why is it uppercase? -",Should be `K2JSCompilerArguments` -180,"@@ -0,0 +1,255 @@ -+/* -+ * 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.compilerRunner -+ -+import com.intellij.openapi.util.text.StringUtil -+import com.intellij.util.ArrayUtil -+import com.intellij.util.Function -+import com.intellij.util.containers.ContainerUtil -+import com.intellij.util.xmlb.XmlSerializerUtil -+import org.jetbrains.kotlin.cli.common.ExitCode -+import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments -+import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments -+import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.INFO -+import org.jetbrains.kotlin.cli.common.messages.MessageCollector -+import org.jetbrains.kotlin.cli.common.messages.MessageCollectorUtil -+import org.jetbrains.kotlin.config.CompilerSettings -+import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents -+import org.jetbrains.kotlin.progress.CompilationCanceledStatus -+import org.jetbrains.kotlin.rmi.CompilerId -+import org.jetbrains.kotlin.rmi.configureDaemonJVMOptions -+import org.jetbrains.kotlin.rmi.configureDaemonOptions -+import org.jetbrains.kotlin.rmi.isDaemonEnabled -+import org.jetbrains.kotlin.rmi.kotlinr.* -+import org.jetbrains.kotlin.utils.rethrow -+import java.io.* -+import java.lang.reflect.Field -+import java.lang.reflect.Modifier -+import java.util.* -+ -+public object KotlinCompilerRunner { -+ private val K2JVM_COMPILER = ""org.jetbrains.kotlin.cli.jvm.K2JVMCompiler"" -+ private val K2JS_COMPILER = ""org.jetbrains.kotlin.cli.js.K2JSCompiler"" -+ private val INTERNAL_ERROR = ExitCode.INTERNAL_ERROR.toString() -+ -+ public fun runK2JvmCompiler( -+ commonArguments: CommonCompilerArguments, -+ k2jvmArguments: K2JVMCompilerArguments, -+ compilerSettings: CompilerSettings, -+ messageCollector: MessageCollector, -+ environment: CompilerEnvironment, -+ moduleFile: File, -+ collector: OutputItemsCollector) { -+ val arguments = mergeBeans(commonArguments, k2jvmArguments) -+ setupK2JvmArguments(moduleFile, arguments) -+ -+ runCompiler(K2JVM_COMPILER, arguments, compilerSettings.additionalArguments, messageCollector, collector, environment) -+ } -+ -+ public fun runK2JsCompiler( -+ commonArguments: CommonCompilerArguments, -+ k2jsArguments: K2JSCompilerArguments, -+ compilerSettings: CompilerSettings, -+ messageCollector: MessageCollector, -+ environment: CompilerEnvironment, -+ collector: OutputItemsCollector, -+ sourceFiles: Collection, -+ libraryFiles: List, -+ outputFile: File) { -+ val arguments = mergeBeans(commonArguments, k2jsArguments) -+ setupK2JsArguments(outputFile, sourceFiles, libraryFiles, arguments) -+ -+ runCompiler(K2JS_COMPILER, arguments, compilerSettings.additionalArguments, messageCollector, collector, environment) -+ } -+ -+ private fun ProcessCompilerOutput( -+ messageCollector: MessageCollector, -+ collector: OutputItemsCollector, -+ stream: ByteArrayOutputStream, -+ exitCode: String) { -+ val reader = BufferedReader(StringReader(stream.toString())) -+ CompilerOutputParser.parseCompilerMessagesFromReader(messageCollector, reader, collector) -+ -+ if (INTERNAL_ERROR == exitCode) { -+ reportInternalCompilerError(messageCollector) -+ } -+ } -+ -+ private fun reportInternalCompilerError(messageCollector: MessageCollector) { -+ messageCollector.report(ERROR, ""Compiler terminated with internal error"", CompilerMessageLocation.NO_LOCATION) -+ } -+ -+ private fun runCompiler( -+ compilerClassName: String, -+ arguments: CommonCompilerArguments, -+ additionalArguments: String, -+ messageCollector: MessageCollector, -+ collector: OutputItemsCollector, -+ environment: CompilerEnvironment) { -+ try { -+ messageCollector.report(INFO, ""Using kotlin-home = "" + environment.kotlinPaths.homePath, CompilerMessageLocation.NO_LOCATION) -+ -+ val argumentsList = ArgumentUtils.convertArgumentsToStringList(arguments) -+ argumentsList.addAll(StringUtil.split(additionalArguments, "" ""))","Please use Kotlin's `split` -",Should be `K2JSCompilerArguments` -181,"@@ -0,0 +1,255 @@ -+/* -+ * 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.compilerRunner -+ -+import com.intellij.openapi.util.text.StringUtil -+import com.intellij.util.ArrayUtil -+import com.intellij.util.Function -+import com.intellij.util.containers.ContainerUtil -+import com.intellij.util.xmlb.XmlSerializerUtil -+import org.jetbrains.kotlin.cli.common.ExitCode -+import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments -+import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments -+import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.INFO -+import org.jetbrains.kotlin.cli.common.messages.MessageCollector -+import org.jetbrains.kotlin.cli.common.messages.MessageCollectorUtil -+import org.jetbrains.kotlin.config.CompilerSettings -+import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents -+import org.jetbrains.kotlin.progress.CompilationCanceledStatus -+import org.jetbrains.kotlin.rmi.CompilerId -+import org.jetbrains.kotlin.rmi.configureDaemonJVMOptions -+import org.jetbrains.kotlin.rmi.configureDaemonOptions -+import org.jetbrains.kotlin.rmi.isDaemonEnabled -+import org.jetbrains.kotlin.rmi.kotlinr.* -+import org.jetbrains.kotlin.utils.rethrow -+import java.io.* -+import java.lang.reflect.Field -+import java.lang.reflect.Modifier -+import java.util.* -+ -+public object KotlinCompilerRunner { -+ private val K2JVM_COMPILER = ""org.jetbrains.kotlin.cli.jvm.K2JVMCompiler"" -+ private val K2JS_COMPILER = ""org.jetbrains.kotlin.cli.js.K2JSCompiler"" -+ private val INTERNAL_ERROR = ExitCode.INTERNAL_ERROR.toString() -+ -+ public fun runK2JvmCompiler( -+ commonArguments: CommonCompilerArguments, -+ k2jvmArguments: K2JVMCompilerArguments, -+ compilerSettings: CompilerSettings, -+ messageCollector: MessageCollector, -+ environment: CompilerEnvironment, -+ moduleFile: File, -+ collector: OutputItemsCollector) { -+ val arguments = mergeBeans(commonArguments, k2jvmArguments) -+ setupK2JvmArguments(moduleFile, arguments) -+ -+ runCompiler(K2JVM_COMPILER, arguments, compilerSettings.additionalArguments, messageCollector, collector, environment) -+ } -+ -+ public fun runK2JsCompiler( -+ commonArguments: CommonCompilerArguments, -+ k2jsArguments: K2JSCompilerArguments, -+ compilerSettings: CompilerSettings, -+ messageCollector: MessageCollector, -+ environment: CompilerEnvironment, -+ collector: OutputItemsCollector, -+ sourceFiles: Collection, -+ libraryFiles: List, -+ outputFile: File) { -+ val arguments = mergeBeans(commonArguments, k2jsArguments) -+ setupK2JsArguments(outputFile, sourceFiles, libraryFiles, arguments) -+ -+ runCompiler(K2JS_COMPILER, arguments, compilerSettings.additionalArguments, messageCollector, collector, environment) -+ } -+ -+ private fun ProcessCompilerOutput( -+ messageCollector: MessageCollector, -+ collector: OutputItemsCollector, -+ stream: ByteArrayOutputStream, -+ exitCode: String) { -+ val reader = BufferedReader(StringReader(stream.toString())) -+ CompilerOutputParser.parseCompilerMessagesFromReader(messageCollector, reader, collector) -+ -+ if (INTERNAL_ERROR == exitCode) { -+ reportInternalCompilerError(messageCollector) -+ } -+ } -+ -+ private fun reportInternalCompilerError(messageCollector: MessageCollector) { -+ messageCollector.report(ERROR, ""Compiler terminated with internal error"", CompilerMessageLocation.NO_LOCATION) -+ } -+ -+ private fun runCompiler( -+ compilerClassName: String, -+ arguments: CommonCompilerArguments, -+ additionalArguments: String, -+ messageCollector: MessageCollector, -+ collector: OutputItemsCollector, -+ environment: CompilerEnvironment) { -+ try { -+ messageCollector.report(INFO, ""Using kotlin-home = "" + environment.kotlinPaths.homePath, CompilerMessageLocation.NO_LOCATION) -+ -+ val argumentsList = ArgumentUtils.convertArgumentsToStringList(arguments) -+ argumentsList.addAll(StringUtil.split(additionalArguments, "" "")) -+ -+ val argsArray = ArrayUtil.toStringArray(argumentsList)","`toTypedArray()` -",Should be `K2JSCompilerArguments` -182,"@@ -0,0 +1,255 @@ -+/* -+ * 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.compilerRunner -+ -+import com.intellij.openapi.util.text.StringUtil -+import com.intellij.util.ArrayUtil -+import com.intellij.util.Function -+import com.intellij.util.containers.ContainerUtil -+import com.intellij.util.xmlb.XmlSerializerUtil -+import org.jetbrains.kotlin.cli.common.ExitCode -+import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments -+import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments -+import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.INFO -+import org.jetbrains.kotlin.cli.common.messages.MessageCollector -+import org.jetbrains.kotlin.cli.common.messages.MessageCollectorUtil -+import org.jetbrains.kotlin.config.CompilerSettings -+import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents -+import org.jetbrains.kotlin.progress.CompilationCanceledStatus -+import org.jetbrains.kotlin.rmi.CompilerId -+import org.jetbrains.kotlin.rmi.configureDaemonJVMOptions -+import org.jetbrains.kotlin.rmi.configureDaemonOptions -+import org.jetbrains.kotlin.rmi.isDaemonEnabled -+import org.jetbrains.kotlin.rmi.kotlinr.* -+import org.jetbrains.kotlin.utils.rethrow -+import java.io.* -+import java.lang.reflect.Field -+import java.lang.reflect.Modifier -+import java.util.* -+ -+public object KotlinCompilerRunner { -+ private val K2JVM_COMPILER = ""org.jetbrains.kotlin.cli.jvm.K2JVMCompiler"" -+ private val K2JS_COMPILER = ""org.jetbrains.kotlin.cli.js.K2JSCompiler"" -+ private val INTERNAL_ERROR = ExitCode.INTERNAL_ERROR.toString() -+ -+ public fun runK2JvmCompiler( -+ commonArguments: CommonCompilerArguments, -+ k2jvmArguments: K2JVMCompilerArguments, -+ compilerSettings: CompilerSettings, -+ messageCollector: MessageCollector, -+ environment: CompilerEnvironment, -+ moduleFile: File, -+ collector: OutputItemsCollector) { -+ val arguments = mergeBeans(commonArguments, k2jvmArguments) -+ setupK2JvmArguments(moduleFile, arguments) -+ -+ runCompiler(K2JVM_COMPILER, arguments, compilerSettings.additionalArguments, messageCollector, collector, environment) -+ } -+ -+ public fun runK2JsCompiler( -+ commonArguments: CommonCompilerArguments, -+ k2jsArguments: K2JSCompilerArguments, -+ compilerSettings: CompilerSettings, -+ messageCollector: MessageCollector, -+ environment: CompilerEnvironment, -+ collector: OutputItemsCollector, -+ sourceFiles: Collection, -+ libraryFiles: List, -+ outputFile: File) { -+ val arguments = mergeBeans(commonArguments, k2jsArguments) -+ setupK2JsArguments(outputFile, sourceFiles, libraryFiles, arguments) -+ -+ runCompiler(K2JS_COMPILER, arguments, compilerSettings.additionalArguments, messageCollector, collector, environment) -+ } -+ -+ private fun ProcessCompilerOutput( -+ messageCollector: MessageCollector, -+ collector: OutputItemsCollector, -+ stream: ByteArrayOutputStream, -+ exitCode: String) { -+ val reader = BufferedReader(StringReader(stream.toString())) -+ CompilerOutputParser.parseCompilerMessagesFromReader(messageCollector, reader, collector) -+ -+ if (INTERNAL_ERROR == exitCode) { -+ reportInternalCompilerError(messageCollector) -+ } -+ } -+ -+ private fun reportInternalCompilerError(messageCollector: MessageCollector) { -+ messageCollector.report(ERROR, ""Compiler terminated with internal error"", CompilerMessageLocation.NO_LOCATION) -+ } -+ -+ private fun runCompiler( -+ compilerClassName: String, -+ arguments: CommonCompilerArguments, -+ additionalArguments: String, -+ messageCollector: MessageCollector, -+ collector: OutputItemsCollector, -+ environment: CompilerEnvironment) { -+ try { -+ messageCollector.report(INFO, ""Using kotlin-home = "" + environment.kotlinPaths.homePath, CompilerMessageLocation.NO_LOCATION) -+ -+ val argumentsList = ArgumentUtils.convertArgumentsToStringList(arguments) -+ argumentsList.addAll(StringUtil.split(additionalArguments, "" "")) -+ -+ val argsArray = ArrayUtil.toStringArray(argumentsList) -+ -+ if (!tryCompileWithDaemon(messageCollector, collector, environment, argsArray)) { -+ // otherwise fallback to in-process -+ -+ val stream = ByteArrayOutputStream() -+ val out = PrintStream(stream) -+ -+ val rc = CompilerRunnerUtil.invokeExecMethod(compilerClassName, argsArray, environment, messageCollector, out) -+ -+ // exec() returns an ExitCode object, class of which is loaded with a different class loader, -+ // so we take it's contents through reflection -+ ProcessCompilerOutput(messageCollector, collector, stream, getReturnCodeFromObject(rc)) -+ } -+ } -+ catch (e: Throwable) { -+ MessageCollectorUtil.reportException(messageCollector, e) -+ reportInternalCompilerError(messageCollector) -+ } -+ -+ } -+ -+ private fun tryCompileWithDaemon(messageCollector: MessageCollector, -+ collector: OutputItemsCollector, -+ environment: CompilerEnvironment, -+ argsArray: Array): Boolean { -+ if (isDaemonEnabled()) {","Early return would be helpful -",Should be `K2JSCompilerArguments` -183,"@@ -0,0 +1,255 @@ -+/* -+ * 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.compilerRunner -+ -+import com.intellij.openapi.util.text.StringUtil -+import com.intellij.util.ArrayUtil -+import com.intellij.util.Function -+import com.intellij.util.containers.ContainerUtil -+import com.intellij.util.xmlb.XmlSerializerUtil -+import org.jetbrains.kotlin.cli.common.ExitCode -+import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments -+import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments -+import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.INFO -+import org.jetbrains.kotlin.cli.common.messages.MessageCollector -+import org.jetbrains.kotlin.cli.common.messages.MessageCollectorUtil -+import org.jetbrains.kotlin.config.CompilerSettings -+import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents -+import org.jetbrains.kotlin.progress.CompilationCanceledStatus -+import org.jetbrains.kotlin.rmi.CompilerId -+import org.jetbrains.kotlin.rmi.configureDaemonJVMOptions -+import org.jetbrains.kotlin.rmi.configureDaemonOptions -+import org.jetbrains.kotlin.rmi.isDaemonEnabled -+import org.jetbrains.kotlin.rmi.kotlinr.* -+import org.jetbrains.kotlin.utils.rethrow -+import java.io.* -+import java.lang.reflect.Field -+import java.lang.reflect.Modifier -+import java.util.* -+ -+public object KotlinCompilerRunner { -+ private val K2JVM_COMPILER = ""org.jetbrains.kotlin.cli.jvm.K2JVMCompiler"" -+ private val K2JS_COMPILER = ""org.jetbrains.kotlin.cli.js.K2JSCompiler"" -+ private val INTERNAL_ERROR = ExitCode.INTERNAL_ERROR.toString() -+ -+ public fun runK2JvmCompiler( -+ commonArguments: CommonCompilerArguments, -+ k2jvmArguments: K2JVMCompilerArguments, -+ compilerSettings: CompilerSettings, -+ messageCollector: MessageCollector, -+ environment: CompilerEnvironment, -+ moduleFile: File, -+ collector: OutputItemsCollector) { -+ val arguments = mergeBeans(commonArguments, k2jvmArguments) -+ setupK2JvmArguments(moduleFile, arguments) -+ -+ runCompiler(K2JVM_COMPILER, arguments, compilerSettings.additionalArguments, messageCollector, collector, environment) -+ } -+ -+ public fun runK2JsCompiler( -+ commonArguments: CommonCompilerArguments, -+ k2jsArguments: K2JSCompilerArguments, -+ compilerSettings: CompilerSettings, -+ messageCollector: MessageCollector, -+ environment: CompilerEnvironment, -+ collector: OutputItemsCollector, -+ sourceFiles: Collection, -+ libraryFiles: List, -+ outputFile: File) { -+ val arguments = mergeBeans(commonArguments, k2jsArguments) -+ setupK2JsArguments(outputFile, sourceFiles, libraryFiles, arguments) -+ -+ runCompiler(K2JS_COMPILER, arguments, compilerSettings.additionalArguments, messageCollector, collector, environment) -+ } -+ -+ private fun ProcessCompilerOutput( -+ messageCollector: MessageCollector, -+ collector: OutputItemsCollector, -+ stream: ByteArrayOutputStream, -+ exitCode: String) { -+ val reader = BufferedReader(StringReader(stream.toString())) -+ CompilerOutputParser.parseCompilerMessagesFromReader(messageCollector, reader, collector) -+ -+ if (INTERNAL_ERROR == exitCode) { -+ reportInternalCompilerError(messageCollector) -+ } -+ } -+ -+ private fun reportInternalCompilerError(messageCollector: MessageCollector) { -+ messageCollector.report(ERROR, ""Compiler terminated with internal error"", CompilerMessageLocation.NO_LOCATION) -+ } -+ -+ private fun runCompiler( -+ compilerClassName: String, -+ arguments: CommonCompilerArguments, -+ additionalArguments: String, -+ messageCollector: MessageCollector, -+ collector: OutputItemsCollector, -+ environment: CompilerEnvironment) { -+ try { -+ messageCollector.report(INFO, ""Using kotlin-home = "" + environment.kotlinPaths.homePath, CompilerMessageLocation.NO_LOCATION) -+ -+ val argumentsList = ArgumentUtils.convertArgumentsToStringList(arguments) -+ argumentsList.addAll(StringUtil.split(additionalArguments, "" "")) -+ -+ val argsArray = ArrayUtil.toStringArray(argumentsList) -+ -+ if (!tryCompileWithDaemon(messageCollector, collector, environment, argsArray)) { -+ // otherwise fallback to in-process -+ -+ val stream = ByteArrayOutputStream() -+ val out = PrintStream(stream) -+ -+ val rc = CompilerRunnerUtil.invokeExecMethod(compilerClassName, argsArray, environment, messageCollector, out) -+ -+ // exec() returns an ExitCode object, class of which is loaded with a different class loader, -+ // so we take it's contents through reflection -+ ProcessCompilerOutput(messageCollector, collector, stream, getReturnCodeFromObject(rc)) -+ } -+ } -+ catch (e: Throwable) { -+ MessageCollectorUtil.reportException(messageCollector, e) -+ reportInternalCompilerError(messageCollector) -+ } -+ -+ } -+ -+ private fun tryCompileWithDaemon(messageCollector: MessageCollector, -+ collector: OutputItemsCollector, -+ environment: CompilerEnvironment, -+ argsArray: Array): Boolean { -+ if (isDaemonEnabled()) { -+ val libPath = CompilerRunnerUtil.getLibPath(environment.kotlinPaths, messageCollector) -+ // TODO: it may be a good idea to cache the compilerId, since making it means calculating digest over jar(s) and if \\ -+ // the lifetime of JPS process is small anyway, we can neglect the probability of changed compiler -+ val compilerId = CompilerId.makeCompilerId(File(libPath, ""kotlin-compiler.jar"")) -+ val daemonOptions = configureDaemonOptions() -+ val daemonJVMOptions = configureDaemonJVMOptions(true) -+ -+ val daemonReportMessages = ArrayList() -+ -+ val daemon = KotlinCompilerClient.connectToCompileService(compilerId, daemonJVMOptions, daemonOptions, DaemonReportingTargets(null, daemonReportMessages), true, true) -+ -+ for (msg in daemonReportMessages) { -+ if (msg.category === DaemonReportCategory.EXCEPTION && daemon == null) { -+ messageCollector.report(CompilerMessageSeverity.INFO, -+ ""Falling back to compilation without daemon due to error: "" + msg.message, -+ CompilerMessageLocation.NO_LOCATION) -+ } -+ else { -+ messageCollector.report(CompilerMessageSeverity.INFO, msg.message, CompilerMessageLocation.NO_LOCATION) -+ } -+ } -+ -+ if (daemon != null) { -+ val compilerOut = ByteArrayOutputStream() -+ val daemonOut = ByteArrayOutputStream() -+ -+ val services = CompilationServices( -+ incrementalCompilationComponents = environment.services.get(IncrementalCompilationComponents::class.java), -+ compilationCanceledStatus = environment.services.get(CompilationCanceledStatus::class.java)) -+ -+ val res = KotlinCompilerClient.incrementalCompile(daemon, argsArray, services, compilerOut, daemonOut) -+ -+ ProcessCompilerOutput(messageCollector, collector, compilerOut, res.toString()) -+ BufferedReader(StringReader(daemonOut.toString())).forEachLine { -+ messageCollector.report(CompilerMessageSeverity.INFO, it, CompilerMessageLocation.NO_LOCATION) -+ } -+ return true -+ } -+ } -+ return false -+ } -+ -+ private fun getReturnCodeFromObject(rc: Any?): String { -+ if (rc == null) {","`when` -",Should be `K2JSCompilerArguments` -184,"@@ -0,0 +1,255 @@ -+/* -+ * 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.compilerRunner -+ -+import com.intellij.openapi.util.text.StringUtil -+import com.intellij.util.ArrayUtil -+import com.intellij.util.Function -+import com.intellij.util.containers.ContainerUtil -+import com.intellij.util.xmlb.XmlSerializerUtil -+import org.jetbrains.kotlin.cli.common.ExitCode -+import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments -+import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments -+import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.INFO -+import org.jetbrains.kotlin.cli.common.messages.MessageCollector -+import org.jetbrains.kotlin.cli.common.messages.MessageCollectorUtil -+import org.jetbrains.kotlin.config.CompilerSettings -+import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents -+import org.jetbrains.kotlin.progress.CompilationCanceledStatus -+import org.jetbrains.kotlin.rmi.CompilerId -+import org.jetbrains.kotlin.rmi.configureDaemonJVMOptions -+import org.jetbrains.kotlin.rmi.configureDaemonOptions -+import org.jetbrains.kotlin.rmi.isDaemonEnabled -+import org.jetbrains.kotlin.rmi.kotlinr.* -+import org.jetbrains.kotlin.utils.rethrow -+import java.io.* -+import java.lang.reflect.Field -+import java.lang.reflect.Modifier -+import java.util.* -+ -+public object KotlinCompilerRunner { -+ private val K2JVM_COMPILER = ""org.jetbrains.kotlin.cli.jvm.K2JVMCompiler"" -+ private val K2JS_COMPILER = ""org.jetbrains.kotlin.cli.js.K2JSCompiler"" -+ private val INTERNAL_ERROR = ExitCode.INTERNAL_ERROR.toString() -+ -+ public fun runK2JvmCompiler( -+ commonArguments: CommonCompilerArguments, -+ k2jvmArguments: K2JVMCompilerArguments, -+ compilerSettings: CompilerSettings, -+ messageCollector: MessageCollector, -+ environment: CompilerEnvironment, -+ moduleFile: File, -+ collector: OutputItemsCollector) { -+ val arguments = mergeBeans(commonArguments, k2jvmArguments) -+ setupK2JvmArguments(moduleFile, arguments) -+ -+ runCompiler(K2JVM_COMPILER, arguments, compilerSettings.additionalArguments, messageCollector, collector, environment) -+ } -+ -+ public fun runK2JsCompiler( -+ commonArguments: CommonCompilerArguments, -+ k2jsArguments: K2JSCompilerArguments, -+ compilerSettings: CompilerSettings, -+ messageCollector: MessageCollector, -+ environment: CompilerEnvironment, -+ collector: OutputItemsCollector, -+ sourceFiles: Collection, -+ libraryFiles: List, -+ outputFile: File) { -+ val arguments = mergeBeans(commonArguments, k2jsArguments) -+ setupK2JsArguments(outputFile, sourceFiles, libraryFiles, arguments) -+ -+ runCompiler(K2JS_COMPILER, arguments, compilerSettings.additionalArguments, messageCollector, collector, environment) -+ } -+ -+ private fun ProcessCompilerOutput( -+ messageCollector: MessageCollector, -+ collector: OutputItemsCollector, -+ stream: ByteArrayOutputStream, -+ exitCode: String) { -+ val reader = BufferedReader(StringReader(stream.toString())) -+ CompilerOutputParser.parseCompilerMessagesFromReader(messageCollector, reader, collector) -+ -+ if (INTERNAL_ERROR == exitCode) { -+ reportInternalCompilerError(messageCollector) -+ } -+ } -+ -+ private fun reportInternalCompilerError(messageCollector: MessageCollector) { -+ messageCollector.report(ERROR, ""Compiler terminated with internal error"", CompilerMessageLocation.NO_LOCATION) -+ } -+ -+ private fun runCompiler( -+ compilerClassName: String, -+ arguments: CommonCompilerArguments, -+ additionalArguments: String, -+ messageCollector: MessageCollector, -+ collector: OutputItemsCollector, -+ environment: CompilerEnvironment) { -+ try { -+ messageCollector.report(INFO, ""Using kotlin-home = "" + environment.kotlinPaths.homePath, CompilerMessageLocation.NO_LOCATION) -+ -+ val argumentsList = ArgumentUtils.convertArgumentsToStringList(arguments) -+ argumentsList.addAll(StringUtil.split(additionalArguments, "" "")) -+ -+ val argsArray = ArrayUtil.toStringArray(argumentsList) -+ -+ if (!tryCompileWithDaemon(messageCollector, collector, environment, argsArray)) { -+ // otherwise fallback to in-process -+ -+ val stream = ByteArrayOutputStream() -+ val out = PrintStream(stream) -+ -+ val rc = CompilerRunnerUtil.invokeExecMethod(compilerClassName, argsArray, environment, messageCollector, out) -+ -+ // exec() returns an ExitCode object, class of which is loaded with a different class loader, -+ // so we take it's contents through reflection -+ ProcessCompilerOutput(messageCollector, collector, stream, getReturnCodeFromObject(rc)) -+ } -+ } -+ catch (e: Throwable) { -+ MessageCollectorUtil.reportException(messageCollector, e) -+ reportInternalCompilerError(messageCollector) -+ } -+ -+ } -+ -+ private fun tryCompileWithDaemon(messageCollector: MessageCollector, -+ collector: OutputItemsCollector, -+ environment: CompilerEnvironment, -+ argsArray: Array): Boolean { -+ if (isDaemonEnabled()) { -+ val libPath = CompilerRunnerUtil.getLibPath(environment.kotlinPaths, messageCollector) -+ // TODO: it may be a good idea to cache the compilerId, since making it means calculating digest over jar(s) and if \\ -+ // the lifetime of JPS process is small anyway, we can neglect the probability of changed compiler -+ val compilerId = CompilerId.makeCompilerId(File(libPath, ""kotlin-compiler.jar"")) -+ val daemonOptions = configureDaemonOptions() -+ val daemonJVMOptions = configureDaemonJVMOptions(true) -+ -+ val daemonReportMessages = ArrayList() -+ -+ val daemon = KotlinCompilerClient.connectToCompileService(compilerId, daemonJVMOptions, daemonOptions, DaemonReportingTargets(null, daemonReportMessages), true, true) -+ -+ for (msg in daemonReportMessages) { -+ if (msg.category === DaemonReportCategory.EXCEPTION && daemon == null) { -+ messageCollector.report(CompilerMessageSeverity.INFO, -+ ""Falling back to compilation without daemon due to error: "" + msg.message, -+ CompilerMessageLocation.NO_LOCATION) -+ } -+ else { -+ messageCollector.report(CompilerMessageSeverity.INFO, msg.message, CompilerMessageLocation.NO_LOCATION) -+ } -+ } -+ -+ if (daemon != null) { -+ val compilerOut = ByteArrayOutputStream() -+ val daemonOut = ByteArrayOutputStream() -+ -+ val services = CompilationServices( -+ incrementalCompilationComponents = environment.services.get(IncrementalCompilationComponents::class.java), -+ compilationCanceledStatus = environment.services.get(CompilationCanceledStatus::class.java)) -+ -+ val res = KotlinCompilerClient.incrementalCompile(daemon, argsArray, services, compilerOut, daemonOut) -+ -+ ProcessCompilerOutput(messageCollector, collector, compilerOut, res.toString()) -+ BufferedReader(StringReader(daemonOut.toString())).forEachLine { -+ messageCollector.report(CompilerMessageSeverity.INFO, it, CompilerMessageLocation.NO_LOCATION) -+ } -+ return true -+ } -+ } -+ return false -+ } -+ -+ private fun getReturnCodeFromObject(rc: Any?): String { -+ if (rc == null) { -+ return INTERNAL_ERROR -+ } -+ else if (ExitCode::class.java.name == rc.javaClass.name) { -+ return rc.toString() -+ } -+ else { -+ throw IllegalStateException(""Unexpected return: "" + rc) -+ } -+ } -+ -+ private fun mergeBeans(from: CommonCompilerArguments, to: T): T { -+ // TODO: rewrite when updated version of com.intellij.util.xmlb is available on TeamCity -+ try { -+ val copy = XmlSerializerUtil.createCopy(to) -+ -+ val fromFields = collectFieldsToCopy(from.javaClass) -+ for (fromField in fromFields) { -+ val toField = copy.javaClass.getField(fromField.name) -+ toField.set(copy, fromField.get(from)) -+ } -+ -+ return copy -+ } -+ catch (e: NoSuchFieldException) { -+ throw rethrow(e) -+ } -+ catch (e: IllegalAccessException) { -+ throw rethrow(e)","This `try`/`catch` and `rethrow`s are not needed in Kotlin -",Should be `K2JSCompilerArguments` -185,"@@ -0,0 +1,255 @@ -+/* -+ * 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.compilerRunner -+ -+import com.intellij.openapi.util.text.StringUtil -+import com.intellij.util.ArrayUtil -+import com.intellij.util.Function -+import com.intellij.util.containers.ContainerUtil -+import com.intellij.util.xmlb.XmlSerializerUtil -+import org.jetbrains.kotlin.cli.common.ExitCode -+import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments -+import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments -+import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.INFO -+import org.jetbrains.kotlin.cli.common.messages.MessageCollector -+import org.jetbrains.kotlin.cli.common.messages.MessageCollectorUtil -+import org.jetbrains.kotlin.config.CompilerSettings -+import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents -+import org.jetbrains.kotlin.progress.CompilationCanceledStatus -+import org.jetbrains.kotlin.rmi.CompilerId -+import org.jetbrains.kotlin.rmi.configureDaemonJVMOptions -+import org.jetbrains.kotlin.rmi.configureDaemonOptions -+import org.jetbrains.kotlin.rmi.isDaemonEnabled -+import org.jetbrains.kotlin.rmi.kotlinr.* -+import org.jetbrains.kotlin.utils.rethrow -+import java.io.* -+import java.lang.reflect.Field -+import java.lang.reflect.Modifier -+import java.util.* -+ -+public object KotlinCompilerRunner { -+ private val K2JVM_COMPILER = ""org.jetbrains.kotlin.cli.jvm.K2JVMCompiler"" -+ private val K2JS_COMPILER = ""org.jetbrains.kotlin.cli.js.K2JSCompiler"" -+ private val INTERNAL_ERROR = ExitCode.INTERNAL_ERROR.toString() -+ -+ public fun runK2JvmCompiler( -+ commonArguments: CommonCompilerArguments, -+ k2jvmArguments: K2JVMCompilerArguments, -+ compilerSettings: CompilerSettings, -+ messageCollector: MessageCollector, -+ environment: CompilerEnvironment, -+ moduleFile: File, -+ collector: OutputItemsCollector) { -+ val arguments = mergeBeans(commonArguments, k2jvmArguments) -+ setupK2JvmArguments(moduleFile, arguments) -+ -+ runCompiler(K2JVM_COMPILER, arguments, compilerSettings.additionalArguments, messageCollector, collector, environment) -+ } -+ -+ public fun runK2JsCompiler( -+ commonArguments: CommonCompilerArguments, -+ k2jsArguments: K2JSCompilerArguments, -+ compilerSettings: CompilerSettings, -+ messageCollector: MessageCollector, -+ environment: CompilerEnvironment, -+ collector: OutputItemsCollector, -+ sourceFiles: Collection, -+ libraryFiles: List, -+ outputFile: File) { -+ val arguments = mergeBeans(commonArguments, k2jsArguments) -+ setupK2JsArguments(outputFile, sourceFiles, libraryFiles, arguments) -+ -+ runCompiler(K2JS_COMPILER, arguments, compilerSettings.additionalArguments, messageCollector, collector, environment) -+ } -+ -+ private fun ProcessCompilerOutput( -+ messageCollector: MessageCollector, -+ collector: OutputItemsCollector, -+ stream: ByteArrayOutputStream, -+ exitCode: String) { -+ val reader = BufferedReader(StringReader(stream.toString())) -+ CompilerOutputParser.parseCompilerMessagesFromReader(messageCollector, reader, collector) -+ -+ if (INTERNAL_ERROR == exitCode) { -+ reportInternalCompilerError(messageCollector) -+ } -+ } -+ -+ private fun reportInternalCompilerError(messageCollector: MessageCollector) { -+ messageCollector.report(ERROR, ""Compiler terminated with internal error"", CompilerMessageLocation.NO_LOCATION) -+ } -+ -+ private fun runCompiler( -+ compilerClassName: String, -+ arguments: CommonCompilerArguments, -+ additionalArguments: String, -+ messageCollector: MessageCollector, -+ collector: OutputItemsCollector, -+ environment: CompilerEnvironment) { -+ try { -+ messageCollector.report(INFO, ""Using kotlin-home = "" + environment.kotlinPaths.homePath, CompilerMessageLocation.NO_LOCATION) -+ -+ val argumentsList = ArgumentUtils.convertArgumentsToStringList(arguments) -+ argumentsList.addAll(StringUtil.split(additionalArguments, "" "")) -+ -+ val argsArray = ArrayUtil.toStringArray(argumentsList) -+ -+ if (!tryCompileWithDaemon(messageCollector, collector, environment, argsArray)) { -+ // otherwise fallback to in-process -+ -+ val stream = ByteArrayOutputStream() -+ val out = PrintStream(stream) -+ -+ val rc = CompilerRunnerUtil.invokeExecMethod(compilerClassName, argsArray, environment, messageCollector, out) -+ -+ // exec() returns an ExitCode object, class of which is loaded with a different class loader, -+ // so we take it's contents through reflection -+ ProcessCompilerOutput(messageCollector, collector, stream, getReturnCodeFromObject(rc)) -+ } -+ } -+ catch (e: Throwable) { -+ MessageCollectorUtil.reportException(messageCollector, e) -+ reportInternalCompilerError(messageCollector) -+ } -+ -+ } -+ -+ private fun tryCompileWithDaemon(messageCollector: MessageCollector, -+ collector: OutputItemsCollector, -+ environment: CompilerEnvironment, -+ argsArray: Array): Boolean { -+ if (isDaemonEnabled()) { -+ val libPath = CompilerRunnerUtil.getLibPath(environment.kotlinPaths, messageCollector) -+ // TODO: it may be a good idea to cache the compilerId, since making it means calculating digest over jar(s) and if \\ -+ // the lifetime of JPS process is small anyway, we can neglect the probability of changed compiler -+ val compilerId = CompilerId.makeCompilerId(File(libPath, ""kotlin-compiler.jar"")) -+ val daemonOptions = configureDaemonOptions() -+ val daemonJVMOptions = configureDaemonJVMOptions(true) -+ -+ val daemonReportMessages = ArrayList() -+ -+ val daemon = KotlinCompilerClient.connectToCompileService(compilerId, daemonJVMOptions, daemonOptions, DaemonReportingTargets(null, daemonReportMessages), true, true) -+ -+ for (msg in daemonReportMessages) { -+ if (msg.category === DaemonReportCategory.EXCEPTION && daemon == null) { -+ messageCollector.report(CompilerMessageSeverity.INFO, -+ ""Falling back to compilation without daemon due to error: "" + msg.message, -+ CompilerMessageLocation.NO_LOCATION) -+ } -+ else { -+ messageCollector.report(CompilerMessageSeverity.INFO, msg.message, CompilerMessageLocation.NO_LOCATION) -+ } -+ } -+ -+ if (daemon != null) { -+ val compilerOut = ByteArrayOutputStream() -+ val daemonOut = ByteArrayOutputStream() -+ -+ val services = CompilationServices( -+ incrementalCompilationComponents = environment.services.get(IncrementalCompilationComponents::class.java), -+ compilationCanceledStatus = environment.services.get(CompilationCanceledStatus::class.java)) -+ -+ val res = KotlinCompilerClient.incrementalCompile(daemon, argsArray, services, compilerOut, daemonOut) -+ -+ ProcessCompilerOutput(messageCollector, collector, compilerOut, res.toString()) -+ BufferedReader(StringReader(daemonOut.toString())).forEachLine { -+ messageCollector.report(CompilerMessageSeverity.INFO, it, CompilerMessageLocation.NO_LOCATION) -+ } -+ return true -+ } -+ } -+ return false -+ } -+ -+ private fun getReturnCodeFromObject(rc: Any?): String { -+ if (rc == null) { -+ return INTERNAL_ERROR -+ } -+ else if (ExitCode::class.java.name == rc.javaClass.name) { -+ return rc.toString() -+ } -+ else { -+ throw IllegalStateException(""Unexpected return: "" + rc) -+ } -+ } -+ -+ private fun mergeBeans(from: CommonCompilerArguments, to: T): T { -+ // TODO: rewrite when updated version of com.intellij.util.xmlb is available on TeamCity -+ try { -+ val copy = XmlSerializerUtil.createCopy(to) -+ -+ val fromFields = collectFieldsToCopy(from.javaClass) -+ for (fromField in fromFields) { -+ val toField = copy.javaClass.getField(fromField.name) -+ toField.set(copy, fromField.get(from)) -+ } -+ -+ return copy -+ } -+ catch (e: NoSuchFieldException) { -+ throw rethrow(e) -+ } -+ catch (e: IllegalAccessException) { -+ throw rethrow(e) -+ } -+ -+ } -+ -+ private fun collectFieldsToCopy(clazz: Class<*>): List { -+ val fromFields = ArrayList() -+ -+ var currentClass: Class<*>? = clazz -+ while (currentClass != null) { -+ for (field in currentClass.declaredFields) { -+ val modifiers = field.modifiers -+ if (!Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers)) { -+ fromFields.add(field) -+ } -+ } -+ currentClass = currentClass.superclass -+ } -+ -+ return fromFields -+ } -+ -+ private fun setupK2JvmArguments(moduleFile: File, settings: K2JVMCompilerArguments) { -+ settings.module = moduleFile.absolutePath -+ settings.noStdlib = true -+ settings.noJdkAnnotations = true -+ settings.noJdk = true -+ } -+ -+ private fun setupK2JsArguments( -+ outputFile: File, -+ sourceFiles: Collection, -+ libraryFiles: List, -+ settings: K2JSCompilerArguments) { -+ settings.noStdlib = true -+ settings.freeArgs = ContainerUtil.map(sourceFiles, object : Function {","Please use Kotlin's `map { ... }` -",Should be `K2JSCompilerArguments` -186,"@@ -0,0 +1,255 @@ -+/* -+ * 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.compilerRunner -+ -+import com.intellij.openapi.util.text.StringUtil -+import com.intellij.util.ArrayUtil -+import com.intellij.util.Function -+import com.intellij.util.containers.ContainerUtil -+import com.intellij.util.xmlb.XmlSerializerUtil -+import org.jetbrains.kotlin.cli.common.ExitCode -+import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments -+import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments -+import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.INFO -+import org.jetbrains.kotlin.cli.common.messages.MessageCollector -+import org.jetbrains.kotlin.cli.common.messages.MessageCollectorUtil -+import org.jetbrains.kotlin.config.CompilerSettings -+import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents -+import org.jetbrains.kotlin.progress.CompilationCanceledStatus -+import org.jetbrains.kotlin.rmi.CompilerId -+import org.jetbrains.kotlin.rmi.configureDaemonJVMOptions -+import org.jetbrains.kotlin.rmi.configureDaemonOptions -+import org.jetbrains.kotlin.rmi.isDaemonEnabled -+import org.jetbrains.kotlin.rmi.kotlinr.* -+import org.jetbrains.kotlin.utils.rethrow -+import java.io.* -+import java.lang.reflect.Field -+import java.lang.reflect.Modifier -+import java.util.* -+ -+public object KotlinCompilerRunner { -+ private val K2JVM_COMPILER = ""org.jetbrains.kotlin.cli.jvm.K2JVMCompiler"" -+ private val K2JS_COMPILER = ""org.jetbrains.kotlin.cli.js.K2JSCompiler"" -+ private val INTERNAL_ERROR = ExitCode.INTERNAL_ERROR.toString() -+ -+ public fun runK2JvmCompiler( -+ commonArguments: CommonCompilerArguments, -+ k2jvmArguments: K2JVMCompilerArguments, -+ compilerSettings: CompilerSettings, -+ messageCollector: MessageCollector, -+ environment: CompilerEnvironment, -+ moduleFile: File, -+ collector: OutputItemsCollector) { -+ val arguments = mergeBeans(commonArguments, k2jvmArguments) -+ setupK2JvmArguments(moduleFile, arguments) -+ -+ runCompiler(K2JVM_COMPILER, arguments, compilerSettings.additionalArguments, messageCollector, collector, environment) -+ } -+ -+ public fun runK2JsCompiler( -+ commonArguments: CommonCompilerArguments, -+ k2jsArguments: K2JSCompilerArguments, -+ compilerSettings: CompilerSettings, -+ messageCollector: MessageCollector, -+ environment: CompilerEnvironment, -+ collector: OutputItemsCollector, -+ sourceFiles: Collection, -+ libraryFiles: List, -+ outputFile: File) { -+ val arguments = mergeBeans(commonArguments, k2jsArguments) -+ setupK2JsArguments(outputFile, sourceFiles, libraryFiles, arguments) -+ -+ runCompiler(K2JS_COMPILER, arguments, compilerSettings.additionalArguments, messageCollector, collector, environment) -+ } -+ -+ private fun ProcessCompilerOutput( -+ messageCollector: MessageCollector, -+ collector: OutputItemsCollector, -+ stream: ByteArrayOutputStream, -+ exitCode: String) { -+ val reader = BufferedReader(StringReader(stream.toString())) -+ CompilerOutputParser.parseCompilerMessagesFromReader(messageCollector, reader, collector) -+ -+ if (INTERNAL_ERROR == exitCode) { -+ reportInternalCompilerError(messageCollector) -+ } -+ } -+ -+ private fun reportInternalCompilerError(messageCollector: MessageCollector) { -+ messageCollector.report(ERROR, ""Compiler terminated with internal error"", CompilerMessageLocation.NO_LOCATION) -+ } -+ -+ private fun runCompiler( -+ compilerClassName: String, -+ arguments: CommonCompilerArguments, -+ additionalArguments: String, -+ messageCollector: MessageCollector, -+ collector: OutputItemsCollector, -+ environment: CompilerEnvironment) { -+ try { -+ messageCollector.report(INFO, ""Using kotlin-home = "" + environment.kotlinPaths.homePath, CompilerMessageLocation.NO_LOCATION) -+ -+ val argumentsList = ArgumentUtils.convertArgumentsToStringList(arguments) -+ argumentsList.addAll(StringUtil.split(additionalArguments, "" "")) -+ -+ val argsArray = ArrayUtil.toStringArray(argumentsList) -+ -+ if (!tryCompileWithDaemon(messageCollector, collector, environment, argsArray)) { -+ // otherwise fallback to in-process -+ -+ val stream = ByteArrayOutputStream() -+ val out = PrintStream(stream) -+ -+ val rc = CompilerRunnerUtil.invokeExecMethod(compilerClassName, argsArray, environment, messageCollector, out) -+ -+ // exec() returns an ExitCode object, class of which is loaded with a different class loader, -+ // so we take it's contents through reflection -+ ProcessCompilerOutput(messageCollector, collector, stream, getReturnCodeFromObject(rc)) -+ } -+ } -+ catch (e: Throwable) { -+ MessageCollectorUtil.reportException(messageCollector, e) -+ reportInternalCompilerError(messageCollector) -+ } -+ -+ } -+ -+ private fun tryCompileWithDaemon(messageCollector: MessageCollector, -+ collector: OutputItemsCollector, -+ environment: CompilerEnvironment, -+ argsArray: Array): Boolean { -+ if (isDaemonEnabled()) { -+ val libPath = CompilerRunnerUtil.getLibPath(environment.kotlinPaths, messageCollector) -+ // TODO: it may be a good idea to cache the compilerId, since making it means calculating digest over jar(s) and if \\ -+ // the lifetime of JPS process is small anyway, we can neglect the probability of changed compiler -+ val compilerId = CompilerId.makeCompilerId(File(libPath, ""kotlin-compiler.jar"")) -+ val daemonOptions = configureDaemonOptions() -+ val daemonJVMOptions = configureDaemonJVMOptions(true) -+ -+ val daemonReportMessages = ArrayList() -+ -+ val daemon = KotlinCompilerClient.connectToCompileService(compilerId, daemonJVMOptions, daemonOptions, DaemonReportingTargets(null, daemonReportMessages), true, true) -+ -+ for (msg in daemonReportMessages) { -+ if (msg.category === DaemonReportCategory.EXCEPTION && daemon == null) { -+ messageCollector.report(CompilerMessageSeverity.INFO, -+ ""Falling back to compilation without daemon due to error: "" + msg.message, -+ CompilerMessageLocation.NO_LOCATION) -+ } -+ else { -+ messageCollector.report(CompilerMessageSeverity.INFO, msg.message, CompilerMessageLocation.NO_LOCATION) -+ } -+ } -+ -+ if (daemon != null) { -+ val compilerOut = ByteArrayOutputStream() -+ val daemonOut = ByteArrayOutputStream() -+ -+ val services = CompilationServices( -+ incrementalCompilationComponents = environment.services.get(IncrementalCompilationComponents::class.java), -+ compilationCanceledStatus = environment.services.get(CompilationCanceledStatus::class.java)) -+ -+ val res = KotlinCompilerClient.incrementalCompile(daemon, argsArray, services, compilerOut, daemonOut) -+ -+ ProcessCompilerOutput(messageCollector, collector, compilerOut, res.toString()) -+ BufferedReader(StringReader(daemonOut.toString())).forEachLine { -+ messageCollector.report(CompilerMessageSeverity.INFO, it, CompilerMessageLocation.NO_LOCATION) -+ } -+ return true -+ } -+ } -+ return false -+ } -+ -+ private fun getReturnCodeFromObject(rc: Any?): String { -+ if (rc == null) { -+ return INTERNAL_ERROR -+ } -+ else if (ExitCode::class.java.name == rc.javaClass.name) { -+ return rc.toString() -+ } -+ else { -+ throw IllegalStateException(""Unexpected return: "" + rc) -+ } -+ } -+ -+ private fun mergeBeans(from: CommonCompilerArguments, to: T): T { -+ // TODO: rewrite when updated version of com.intellij.util.xmlb is available on TeamCity -+ try { -+ val copy = XmlSerializerUtil.createCopy(to) -+ -+ val fromFields = collectFieldsToCopy(from.javaClass) -+ for (fromField in fromFields) { -+ val toField = copy.javaClass.getField(fromField.name) -+ toField.set(copy, fromField.get(from)) -+ } -+ -+ return copy -+ } -+ catch (e: NoSuchFieldException) { -+ throw rethrow(e) -+ } -+ catch (e: IllegalAccessException) { -+ throw rethrow(e) -+ } -+ -+ } -+ -+ private fun collectFieldsToCopy(clazz: Class<*>): List { -+ val fromFields = ArrayList() -+ -+ var currentClass: Class<*>? = clazz -+ while (currentClass != null) { -+ for (field in currentClass.declaredFields) { -+ val modifiers = field.modifiers -+ if (!Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers)) { -+ fromFields.add(field) -+ } -+ } -+ currentClass = currentClass.superclass -+ } -+ -+ return fromFields -+ } -+ -+ private fun setupK2JvmArguments(moduleFile: File, settings: K2JVMCompilerArguments) { -+ settings.module = moduleFile.absolutePath -+ settings.noStdlib = true -+ settings.noJdkAnnotations = true -+ settings.noJdk = true -+ } -+ -+ private fun setupK2JsArguments( -+ outputFile: File, -+ sourceFiles: Collection, -+ libraryFiles: List, -+ settings: K2JSCompilerArguments) { -+ settings.noStdlib = true -+ settings.freeArgs = ContainerUtil.map(sourceFiles, object : Function { -+ override fun `fun`(file: File): String { -+ return file.path -+ } -+ }) -+ settings.outputFile = outputFile.path -+ settings.metaInfo = true -+ settings.libraryFiles = ArrayUtil.toStringArray(libraryFiles)","`toTypedArray()` -",Should be `K2JSCompilerArguments` -187,"@@ -0,0 +1,26 @@ -+/* -+ * 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 kotlin.jvm -+ -+import java.lang.annotation.Retention -+import java.lang.annotation.RetentionPolicy -+ -+/** -+ * Instructs the Kotlin compiler to generate overloads for this function that substitute default parameter values.","Maybe it will be useful to document exactly what overloads are generated here? One might think that `2^n` overloads will be generated, if `n` is the number of default parameters -",Missing Apache license header. -188,"@@ -0,0 +1,26 @@ -+/* -+ * 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.components -+ -+import org.jetbrains.kotlin.descriptors.SourceFile -+import org.jetbrains.kotlin.load.java.sources.JavaSourceElement -+import org.jetbrains.kotlin.load.java.structure.JavaElement -+ -+class JavacSourceElement(override val javaElement: JavaElement) : JavaSourceElement {",`JavacBasedSourceElement`?,Add a license to the top of the file -189,"@@ -0,0 +1,26 @@ -+/* -+ * 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.components -+ -+import org.jetbrains.kotlin.load.java.sources.JavaSourceElementFactory -+import org.jetbrains.kotlin.load.java.structure.JavaElement -+ -+class JavacSourceElementFactory : JavaSourceElementFactory {",`JavacBasedSourceElementFactory`?,Should be `import org.jetbrains.kotlin.load.JavaSourceElementFactory;` -190,"@@ -0,0 +1,26 @@ -+import kotlin.test.assertEquals -+ -+fun test1() { -+ val u = when (true) { -+ true -> 42 -+ else -> 1.0 -+ } -+ -+ assertEquals(42, u) -+} -+ -+fun test2() { -+ val u = 1L.let { -+ when (it) { -+ is Long -> if (it.toLong() == 2L) it.toLong() else it * 2 // CompilationException -+ else -> it.toDouble() -+ } -+ } -+ -+ assertEquals(1L, u) -+} -+ -+fun box(): String { -+ return ""OK""","what about test1, test2 call? -",This test doesn't seem to test anything related to kotlin. -191,"@@ -0,0 +1,262 @@ -+/* -+ * 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.rmi.kotlinr -+ -+import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache -+import org.jetbrains.kotlin.rmi.* -+import java.io.File -+import java.io.OutputStream -+import java.io.PrintStream -+import java.rmi.ConnectException -+import java.rmi.Remote -+import java.rmi.registry.LocateRegistry -+import java.util.concurrent.TimeUnit -+import java.util.concurrent.locks.ReentrantReadWriteLock -+import kotlin.concurrent.read -+import kotlin.concurrent.thread -+import kotlin.concurrent.write -+import kotlin.platform.platformStatic -+ -+fun Process.isAlive() =","~~Why do we need our own isAlive implementation?~~ -My bad. `Process.isAlive` was introduced in Java 8 -",Let's not use java.rmi.Remote; use RMI. -192,"@@ -0,0 +1,262 @@ -+/* -+ * 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.rmi.kotlinr -+ -+import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache -+import org.jetbrains.kotlin.rmi.* -+import java.io.File -+import java.io.OutputStream -+import java.io.PrintStream -+import java.rmi.ConnectException -+import java.rmi.Remote -+import java.rmi.registry.LocateRegistry -+import java.util.concurrent.TimeUnit -+import java.util.concurrent.locks.ReentrantReadWriteLock -+import kotlin.concurrent.read -+import kotlin.concurrent.thread -+import kotlin.concurrent.write -+import kotlin.platform.platformStatic -+ -+fun Process.isAlive() = -+ try { -+ this.exitValue() -+ false -+ } -+ catch (e: IllegalThreadStateException) { -+ true -+ } -+ -+public class KotlinCompilerClient { -+ -+ companion object { -+ -+ val DAEMON_STARTUP_TIMEOUT_MS = 10000L -+ val DAEMON_STARTUP_CHECK_INTERVAL_MS = 100L -+ -+ private fun connectToService(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): CompileService? { -+ -+ val compilerObj = connectToDaemon(compilerId, daemonOptions, errStream) ?: return null // no registry - no daemon running -+ return compilerObj as? CompileService ?: -+ throw ClassCastException(""Unable to cast compiler service, actual class received: ${compilerObj.javaClass}"") -+ } -+ -+ private fun connectToDaemon(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): Remote? { -+ try { -+ val daemon = LocateRegistry.getRegistry(""localhost"", daemonOptions.port) -+ ?.lookup(COMPILER_SERVICE_RMI_NAME) -+ if (daemon != null) -+ return daemon -+ errStream.println(""[daemon client] daemon not found"") -+ } -+ catch (e: ConnectException) { -+ errStream.println(""[daemon client] cannot connect to registry: "" + (e.getCause()?.getMessage() ?: e.getMessage() ?: ""unknown exception"")) -+ // ignoring it - processing below -+ } -+ return null -+ } -+ -+ -+ private fun startDaemon(compilerId: CompilerId, daemonLaunchingOptions: DaemonLaunchingOptions, daemonOptions: DaemonOptions, errStream: PrintStream) { -+ val javaExecutable = listOf(System.getProperty(""java.home""), ""bin"", ""java"").joinToString(File.separator)","Will we see black console window on Windows if we start `java.exe`? Shouldn't we run `javaw.exe` instead? -","This isn't related to this PR, but there is a typo here." -193,"@@ -0,0 +1,262 @@ -+/* -+ * 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.rmi.kotlinr -+ -+import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache -+import org.jetbrains.kotlin.rmi.* -+import java.io.File -+import java.io.OutputStream -+import java.io.PrintStream -+import java.rmi.ConnectException -+import java.rmi.Remote -+import java.rmi.registry.LocateRegistry -+import java.util.concurrent.TimeUnit -+import java.util.concurrent.locks.ReentrantReadWriteLock -+import kotlin.concurrent.read -+import kotlin.concurrent.thread -+import kotlin.concurrent.write -+import kotlin.platform.platformStatic -+ -+fun Process.isAlive() = -+ try { -+ this.exitValue() -+ false -+ } -+ catch (e: IllegalThreadStateException) { -+ true -+ } -+ -+public class KotlinCompilerClient { -+ -+ companion object { -+ -+ val DAEMON_STARTUP_TIMEOUT_MS = 10000L -+ val DAEMON_STARTUP_CHECK_INTERVAL_MS = 100L -+ -+ private fun connectToService(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): CompileService? { -+ -+ val compilerObj = connectToDaemon(compilerId, daemonOptions, errStream) ?: return null // no registry - no daemon running -+ return compilerObj as? CompileService ?: -+ throw ClassCastException(""Unable to cast compiler service, actual class received: ${compilerObj.javaClass}"") -+ } -+ -+ private fun connectToDaemon(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): Remote? { -+ try { -+ val daemon = LocateRegistry.getRegistry(""localhost"", daemonOptions.port) -+ ?.lookup(COMPILER_SERVICE_RMI_NAME) -+ if (daemon != null) -+ return daemon -+ errStream.println(""[daemon client] daemon not found"") -+ } -+ catch (e: ConnectException) { -+ errStream.println(""[daemon client] cannot connect to registry: "" + (e.getCause()?.getMessage() ?: e.getMessage() ?: ""unknown exception"")) -+ // ignoring it - processing below -+ } -+ return null -+ } -+ -+ -+ private fun startDaemon(compilerId: CompilerId, daemonLaunchingOptions: DaemonLaunchingOptions, daemonOptions: DaemonOptions, errStream: PrintStream) { -+ val javaExecutable = listOf(System.getProperty(""java.home""), ""bin"", ""java"").joinToString(File.separator) -+ // TODO: add some specific environment variables to the cp and may be command line, to allow some specific startup configs -+ val args = listOf(javaExecutable, -+ ""-cp"", compilerId.compilerClasspath.joinToString(File.pathSeparator)) + -+ daemonLaunchingOptions.jvmParams + -+ COMPILER_DAEMON_CLASS_FQN + -+ daemonOptions.asParams + -+ compilerId.asParams -+ errStream.println(""[daemon client] starting the daemon as: "" + args.joinToString("" "")) -+ val processBuilder = ProcessBuilder(args).redirectErrorStream(true) -+ // assuming daemon process is deaf and (mostly) silent, so do not handle streams -+ val daemon = processBuilder.start() -+ -+ val lock = ReentrantReadWriteLock() -+ var isEchoRead = false -+ -+ val stdouThread = -+ thread { -+ daemon.getInputStream() -+ .reader() -+ .forEachLine { -+ if (daemonOptions.startEcho.isNotEmpty() && it.contains(daemonOptions.startEcho)) -+ lock.write { isEchoRead = true; return@forEachLine } -+ errStream.println(""[daemon] "" + it) -+ } -+ } -+ try { -+ // trying to wait for process -+ if (daemonOptions.startEcho.isNotEmpty()) { -+ errStream.println(""[daemon client] waiting for daemon to respond"") -+ var waitMillis: Long = DAEMON_STARTUP_TIMEOUT_MS / DAEMON_STARTUP_CHECK_INTERVAL_MS -+ while (waitMillis-- > 0) { -+ Thread.sleep(DAEMON_STARTUP_CHECK_INTERVAL_MS) -+ if (!daemon.isAlive() || lock.read { isEchoRead } == true) break; -+ } -+ if (!daemon.isAlive()) -+ throw Exception(""Daemon terminated unexpectedly"") -+ if (lock.read { isEchoRead } == false) -+ throw Exception(""Unable to get response from daemon in $DAEMON_STARTUP_TIMEOUT_MS ms"") -+ } -+ else -+ // without startEcho defined waiting for max timeout -+ Thread.sleep(DAEMON_STARTUP_TIMEOUT_MS) -+ } -+ finally { -+ // assuming that all important output is already done, the rest should be routed to the log by the daemon itself -+ if (stdouThread.isAlive)","But if it is not then the child process could hang if there are bytes were not consumed: generally it may happen if the child process is trying to write to the pipe but nobody reads it anymore and the pipe internal buffer is full -","This isn't related to this PR, but there is a typo here." -194,"@@ -0,0 +1,262 @@ -+/* -+ * 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.rmi.kotlinr -+ -+import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache -+import org.jetbrains.kotlin.rmi.* -+import java.io.File -+import java.io.OutputStream -+import java.io.PrintStream -+import java.rmi.ConnectException -+import java.rmi.Remote -+import java.rmi.registry.LocateRegistry -+import java.util.concurrent.TimeUnit -+import java.util.concurrent.locks.ReentrantReadWriteLock -+import kotlin.concurrent.read -+import kotlin.concurrent.thread -+import kotlin.concurrent.write -+import kotlin.platform.platformStatic -+ -+fun Process.isAlive() = -+ try { -+ this.exitValue() -+ false -+ } -+ catch (e: IllegalThreadStateException) { -+ true -+ } -+ -+public class KotlinCompilerClient { -+ -+ companion object { -+ -+ val DAEMON_STARTUP_TIMEOUT_MS = 10000L -+ val DAEMON_STARTUP_CHECK_INTERVAL_MS = 100L -+ -+ private fun connectToService(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): CompileService? { -+ -+ val compilerObj = connectToDaemon(compilerId, daemonOptions, errStream) ?: return null // no registry - no daemon running -+ return compilerObj as? CompileService ?: -+ throw ClassCastException(""Unable to cast compiler service, actual class received: ${compilerObj.javaClass}"") -+ } -+ -+ private fun connectToDaemon(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): Remote? { -+ try { -+ val daemon = LocateRegistry.getRegistry(""localhost"", daemonOptions.port) -+ ?.lookup(COMPILER_SERVICE_RMI_NAME) -+ if (daemon != null) -+ return daemon -+ errStream.println(""[daemon client] daemon not found"") -+ } -+ catch (e: ConnectException) { -+ errStream.println(""[daemon client] cannot connect to registry: "" + (e.getCause()?.getMessage() ?: e.getMessage() ?: ""unknown exception"")) -+ // ignoring it - processing below -+ } -+ return null -+ } -+ -+ -+ private fun startDaemon(compilerId: CompilerId, daemonLaunchingOptions: DaemonLaunchingOptions, daemonOptions: DaemonOptions, errStream: PrintStream) { -+ val javaExecutable = listOf(System.getProperty(""java.home""), ""bin"", ""java"").joinToString(File.separator) -+ // TODO: add some specific environment variables to the cp and may be command line, to allow some specific startup configs -+ val args = listOf(javaExecutable, -+ ""-cp"", compilerId.compilerClasspath.joinToString(File.pathSeparator)) + -+ daemonLaunchingOptions.jvmParams + -+ COMPILER_DAEMON_CLASS_FQN + -+ daemonOptions.asParams + -+ compilerId.asParams -+ errStream.println(""[daemon client] starting the daemon as: "" + args.joinToString("" "")) -+ val processBuilder = ProcessBuilder(args).redirectErrorStream(true) -+ // assuming daemon process is deaf and (mostly) silent, so do not handle streams -+ val daemon = processBuilder.start() -+ -+ val lock = ReentrantReadWriteLock() -+ var isEchoRead = false -+ -+ val stdouThread = -+ thread { -+ daemon.getInputStream() -+ .reader() -+ .forEachLine { -+ if (daemonOptions.startEcho.isNotEmpty() && it.contains(daemonOptions.startEcho)) -+ lock.write { isEchoRead = true; return@forEachLine } -+ errStream.println(""[daemon] "" + it) -+ } -+ } -+ try { -+ // trying to wait for process -+ if (daemonOptions.startEcho.isNotEmpty()) { -+ errStream.println(""[daemon client] waiting for daemon to respond"") -+ var waitMillis: Long = DAEMON_STARTUP_TIMEOUT_MS / DAEMON_STARTUP_CHECK_INTERVAL_MS -+ while (waitMillis-- > 0) { -+ Thread.sleep(DAEMON_STARTUP_CHECK_INTERVAL_MS) -+ if (!daemon.isAlive() || lock.read { isEchoRead } == true) break; -+ } -+ if (!daemon.isAlive()) -+ throw Exception(""Daemon terminated unexpectedly"") -+ if (lock.read { isEchoRead } == false) -+ throw Exception(""Unable to get response from daemon in $DAEMON_STARTUP_TIMEOUT_MS ms"") -+ } -+ else -+ // without startEcho defined waiting for max timeout -+ Thread.sleep(DAEMON_STARTUP_TIMEOUT_MS) -+ } -+ finally { -+ // assuming that all important output is already done, the rest should be routed to the log by the daemon itself -+ if (stdouThread.isAlive) -+ // TODO: find better method to stop the thread, but seems it will require asynchronous consuming of the stream -+ lock.write { stdouThread.stop() } -+ } -+ } -+ -+ public fun checkCompilerId(compiler: CompileService, localId: CompilerId, errStream: PrintStream): Boolean { -+ val remoteId = compiler.getCompilerId() -+ errStream.println(""[daemon client] remoteId = "" + remoteId.toString()) -+ errStream.println(""[daemon client] localId = "" + localId.toString()) -+ return (localId.compilerVersion.isEmpty() || localId.compilerVersion == remoteId.compilerVersion) && -+ (localId.compilerClasspath.all { remoteId.compilerClasspath.contains(it) }) && -+ (localId.compilerDigest.isEmpty() || remoteId.compilerDigest.isEmpty() || localId.compilerDigest == remoteId.compilerDigest) -+ } -+ -+ public fun connectToCompileService(compilerId: CompilerId, daemonLaunchingOptions: DaemonLaunchingOptions, daemonOptions: DaemonOptions, errStream: PrintStream, autostart: Boolean = true, checkId: Boolean = true): CompileService? { -+ val service = connectToService(compilerId, daemonOptions, errStream) -+ if (service != null) { -+ if (!checkId || checkCompilerId(service, compilerId, errStream)) { -+ errStream.println(""[daemon client] found the suitable daemon"") -+ return service -+ } -+ errStream.println(""[daemon client] compiler identity don't match: "" + compilerId.asParams.joinToString("" "")) -+ if (!autostart) return null; -+ errStream.println(""[daemon client] shutdown the daemon"") -+ service.shutdown() -+ // TODO: find more reliable way","pidfile, some kind of ping, shutdown port? -","This isn't related to this PR, but there is a typo here." -195,"@@ -0,0 +1,262 @@ -+/* -+ * 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.rmi.kotlinr -+ -+import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache -+import org.jetbrains.kotlin.rmi.* -+import java.io.File -+import java.io.OutputStream -+import java.io.PrintStream -+import java.rmi.ConnectException -+import java.rmi.Remote -+import java.rmi.registry.LocateRegistry -+import java.util.concurrent.TimeUnit -+import java.util.concurrent.locks.ReentrantReadWriteLock -+import kotlin.concurrent.read -+import kotlin.concurrent.thread -+import kotlin.concurrent.write -+import kotlin.platform.platformStatic -+ -+fun Process.isAlive() = -+ try { -+ this.exitValue() -+ false -+ } -+ catch (e: IllegalThreadStateException) { -+ true -+ } -+ -+public class KotlinCompilerClient { -+ -+ companion object { -+ -+ val DAEMON_STARTUP_TIMEOUT_MS = 10000L -+ val DAEMON_STARTUP_CHECK_INTERVAL_MS = 100L -+ -+ private fun connectToService(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): CompileService? { -+ -+ val compilerObj = connectToDaemon(compilerId, daemonOptions, errStream) ?: return null // no registry - no daemon running -+ return compilerObj as? CompileService ?: -+ throw ClassCastException(""Unable to cast compiler service, actual class received: ${compilerObj.javaClass}"") -+ } -+ -+ private fun connectToDaemon(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): Remote? { -+ try { -+ val daemon = LocateRegistry.getRegistry(""localhost"", daemonOptions.port) -+ ?.lookup(COMPILER_SERVICE_RMI_NAME) -+ if (daemon != null) -+ return daemon -+ errStream.println(""[daemon client] daemon not found"") -+ } -+ catch (e: ConnectException) { -+ errStream.println(""[daemon client] cannot connect to registry: "" + (e.getCause()?.getMessage() ?: e.getMessage() ?: ""unknown exception"")) -+ // ignoring it - processing below -+ } -+ return null -+ } -+ -+ -+ private fun startDaemon(compilerId: CompilerId, daemonLaunchingOptions: DaemonLaunchingOptions, daemonOptions: DaemonOptions, errStream: PrintStream) { -+ val javaExecutable = listOf(System.getProperty(""java.home""), ""bin"", ""java"").joinToString(File.separator) -+ // TODO: add some specific environment variables to the cp and may be command line, to allow some specific startup configs -+ val args = listOf(javaExecutable, -+ ""-cp"", compilerId.compilerClasspath.joinToString(File.pathSeparator)) + -+ daemonLaunchingOptions.jvmParams + -+ COMPILER_DAEMON_CLASS_FQN + -+ daemonOptions.asParams + -+ compilerId.asParams -+ errStream.println(""[daemon client] starting the daemon as: "" + args.joinToString("" "")) -+ val processBuilder = ProcessBuilder(args).redirectErrorStream(true) -+ // assuming daemon process is deaf and (mostly) silent, so do not handle streams -+ val daemon = processBuilder.start() -+ -+ val lock = ReentrantReadWriteLock() -+ var isEchoRead = false -+ -+ val stdouThread = -+ thread { -+ daemon.getInputStream() -+ .reader() -+ .forEachLine { -+ if (daemonOptions.startEcho.isNotEmpty() && it.contains(daemonOptions.startEcho)) -+ lock.write { isEchoRead = true; return@forEachLine } -+ errStream.println(""[daemon] "" + it) -+ } -+ } -+ try { -+ // trying to wait for process -+ if (daemonOptions.startEcho.isNotEmpty()) { -+ errStream.println(""[daemon client] waiting for daemon to respond"") -+ var waitMillis: Long = DAEMON_STARTUP_TIMEOUT_MS / DAEMON_STARTUP_CHECK_INTERVAL_MS -+ while (waitMillis-- > 0) { -+ Thread.sleep(DAEMON_STARTUP_CHECK_INTERVAL_MS) -+ if (!daemon.isAlive() || lock.read { isEchoRead } == true) break; -+ } -+ if (!daemon.isAlive()) -+ throw Exception(""Daemon terminated unexpectedly"") -+ if (lock.read { isEchoRead } == false) -+ throw Exception(""Unable to get response from daemon in $DAEMON_STARTUP_TIMEOUT_MS ms"") -+ } -+ else -+ // without startEcho defined waiting for max timeout -+ Thread.sleep(DAEMON_STARTUP_TIMEOUT_MS) -+ } -+ finally { -+ // assuming that all important output is already done, the rest should be routed to the log by the daemon itself -+ if (stdouThread.isAlive) -+ // TODO: find better method to stop the thread, but seems it will require asynchronous consuming of the stream -+ lock.write { stdouThread.stop() } -+ } -+ } -+ -+ public fun checkCompilerId(compiler: CompileService, localId: CompilerId, errStream: PrintStream): Boolean { -+ val remoteId = compiler.getCompilerId() -+ errStream.println(""[daemon client] remoteId = "" + remoteId.toString()) -+ errStream.println(""[daemon client] localId = "" + localId.toString()) -+ return (localId.compilerVersion.isEmpty() || localId.compilerVersion == remoteId.compilerVersion) && -+ (localId.compilerClasspath.all { remoteId.compilerClasspath.contains(it) }) && -+ (localId.compilerDigest.isEmpty() || remoteId.compilerDigest.isEmpty() || localId.compilerDigest == remoteId.compilerDigest) -+ } -+ -+ public fun connectToCompileService(compilerId: CompilerId, daemonLaunchingOptions: DaemonLaunchingOptions, daemonOptions: DaemonOptions, errStream: PrintStream, autostart: Boolean = true, checkId: Boolean = true): CompileService? { -+ val service = connectToService(compilerId, daemonOptions, errStream) -+ if (service != null) { -+ if (!checkId || checkCompilerId(service, compilerId, errStream)) { -+ errStream.println(""[daemon client] found the suitable daemon"") -+ return service -+ } -+ errStream.println(""[daemon client] compiler identity don't match: "" + compilerId.asParams.joinToString("" "")) -+ if (!autostart) return null; -+ errStream.println(""[daemon client] shutdown the daemon"") -+ service.shutdown() -+ // TODO: find more reliable way -+ Thread.sleep(1000) -+ errStream.println(""[daemon client] daemon shut down correctly, restarting"") -+ } -+ else { -+ if (!autostart) return null; -+ else errStream.println(""[daemon client] cannot connect to Compile Daemon, trying to start"") -+ } -+ -+ startDaemon(compilerId, daemonLaunchingOptions, daemonOptions, errStream) -+ errStream.println(""[daemon client] daemon started, trying to connect"") -+ return connectToService(compilerId, daemonOptions, errStream) -+ } -+ -+ public fun shutdownCompileService(): Unit { -+ KotlinCompilerClient.connectToCompileService(CompilerId(), DaemonLaunchingOptions(), DaemonOptions(), System.out, autostart = false, checkId = false) -+ ?.shutdown() -+ } -+ -+ public fun incrementalCompile(compiler: CompileService, args: Array, caches: Map, out: OutputStream): Int { -+ -+ val outStrm = RemoteOutputStreamServer(out) -+ val cacheServers = hashMapOf() -+ try { -+ caches.forEach { cacheServers.put( it.getKey(), RemoteIncrementalCacheServer( it.getValue())) } -+ val res = compiler.remoteIncrementalCompile(args, cacheServers, outStrm, CompileService.OutputFormat.XML) -+ return res -+ } -+ finally { -+ cacheServers.forEach { it.getValue().disconnect() } -+ outStrm.disconnect() -+ } -+ } -+ -+ public fun isDaemonEnabled(): Boolean = System.getProperty(COMPILE_DAEMON_ENABLED_PROPERTY) != null -+ -+ public fun configureDaemonLaunchingOptions(opts: DaemonLaunchingOptions) { -+ System.getProperty(COMPILE_DAEMON_JVM_OPTIONS_PROPERTY)?.let { -+ // TODO: find better way to pass and parse jvm options for daemon -+ opts.jvmParams = it.split(""##"") -+ } -+ } -+ -+ data class ClientOptions( -+ public var stop: Boolean = false -+ ) :CmdlineParams { -+ override val asParams: Iterable -+ get() = -+ if (stop) listOf(""stop"") else listOf()","listOf() -> emptyList() -","This isn't related to this PR, but there is a typo here." -196,"@@ -0,0 +1,262 @@ -+/* -+ * 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.rmi.kotlinr -+ -+import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache -+import org.jetbrains.kotlin.rmi.* -+import java.io.File -+import java.io.OutputStream -+import java.io.PrintStream -+import java.rmi.ConnectException -+import java.rmi.Remote -+import java.rmi.registry.LocateRegistry -+import java.util.concurrent.TimeUnit -+import java.util.concurrent.locks.ReentrantReadWriteLock -+import kotlin.concurrent.read -+import kotlin.concurrent.thread -+import kotlin.concurrent.write -+import kotlin.platform.platformStatic -+ -+fun Process.isAlive() = -+ try { -+ this.exitValue() -+ false -+ } -+ catch (e: IllegalThreadStateException) { -+ true -+ } -+ -+public class KotlinCompilerClient { -+ -+ companion object { -+ -+ val DAEMON_STARTUP_TIMEOUT_MS = 10000L -+ val DAEMON_STARTUP_CHECK_INTERVAL_MS = 100L -+ -+ private fun connectToService(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): CompileService? { -+ -+ val compilerObj = connectToDaemon(compilerId, daemonOptions, errStream) ?: return null // no registry - no daemon running -+ return compilerObj as? CompileService ?: -+ throw ClassCastException(""Unable to cast compiler service, actual class received: ${compilerObj.javaClass}"") -+ } -+ -+ private fun connectToDaemon(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): Remote? { -+ try { -+ val daemon = LocateRegistry.getRegistry(""localhost"", daemonOptions.port) -+ ?.lookup(COMPILER_SERVICE_RMI_NAME) -+ if (daemon != null) -+ return daemon -+ errStream.println(""[daemon client] daemon not found"") -+ } -+ catch (e: ConnectException) { -+ errStream.println(""[daemon client] cannot connect to registry: "" + (e.getCause()?.getMessage() ?: e.getMessage() ?: ""unknown exception"")) -+ // ignoring it - processing below -+ } -+ return null -+ } -+ -+ -+ private fun startDaemon(compilerId: CompilerId, daemonLaunchingOptions: DaemonLaunchingOptions, daemonOptions: DaemonOptions, errStream: PrintStream) { -+ val javaExecutable = listOf(System.getProperty(""java.home""), ""bin"", ""java"").joinToString(File.separator) -+ // TODO: add some specific environment variables to the cp and may be command line, to allow some specific startup configs -+ val args = listOf(javaExecutable, -+ ""-cp"", compilerId.compilerClasspath.joinToString(File.pathSeparator)) + -+ daemonLaunchingOptions.jvmParams + -+ COMPILER_DAEMON_CLASS_FQN + -+ daemonOptions.asParams + -+ compilerId.asParams -+ errStream.println(""[daemon client] starting the daemon as: "" + args.joinToString("" "")) -+ val processBuilder = ProcessBuilder(args).redirectErrorStream(true) -+ // assuming daemon process is deaf and (mostly) silent, so do not handle streams -+ val daemon = processBuilder.start() -+ -+ val lock = ReentrantReadWriteLock() -+ var isEchoRead = false -+ -+ val stdouThread = -+ thread { -+ daemon.getInputStream() -+ .reader() -+ .forEachLine { -+ if (daemonOptions.startEcho.isNotEmpty() && it.contains(daemonOptions.startEcho)) -+ lock.write { isEchoRead = true; return@forEachLine } -+ errStream.println(""[daemon] "" + it) -+ } -+ } -+ try { -+ // trying to wait for process -+ if (daemonOptions.startEcho.isNotEmpty()) { -+ errStream.println(""[daemon client] waiting for daemon to respond"") -+ var waitMillis: Long = DAEMON_STARTUP_TIMEOUT_MS / DAEMON_STARTUP_CHECK_INTERVAL_MS -+ while (waitMillis-- > 0) { -+ Thread.sleep(DAEMON_STARTUP_CHECK_INTERVAL_MS) -+ if (!daemon.isAlive() || lock.read { isEchoRead } == true) break; -+ } -+ if (!daemon.isAlive()) -+ throw Exception(""Daemon terminated unexpectedly"") -+ if (lock.read { isEchoRead } == false) -+ throw Exception(""Unable to get response from daemon in $DAEMON_STARTUP_TIMEOUT_MS ms"") -+ } -+ else -+ // without startEcho defined waiting for max timeout -+ Thread.sleep(DAEMON_STARTUP_TIMEOUT_MS) -+ } -+ finally { -+ // assuming that all important output is already done, the rest should be routed to the log by the daemon itself -+ if (stdouThread.isAlive) -+ // TODO: find better method to stop the thread, but seems it will require asynchronous consuming of the stream -+ lock.write { stdouThread.stop() } -+ } -+ } -+ -+ public fun checkCompilerId(compiler: CompileService, localId: CompilerId, errStream: PrintStream): Boolean { -+ val remoteId = compiler.getCompilerId() -+ errStream.println(""[daemon client] remoteId = "" + remoteId.toString()) -+ errStream.println(""[daemon client] localId = "" + localId.toString()) -+ return (localId.compilerVersion.isEmpty() || localId.compilerVersion == remoteId.compilerVersion) && -+ (localId.compilerClasspath.all { remoteId.compilerClasspath.contains(it) }) && -+ (localId.compilerDigest.isEmpty() || remoteId.compilerDigest.isEmpty() || localId.compilerDigest == remoteId.compilerDigest) -+ } -+ -+ public fun connectToCompileService(compilerId: CompilerId, daemonLaunchingOptions: DaemonLaunchingOptions, daemonOptions: DaemonOptions, errStream: PrintStream, autostart: Boolean = true, checkId: Boolean = true): CompileService? { -+ val service = connectToService(compilerId, daemonOptions, errStream) -+ if (service != null) { -+ if (!checkId || checkCompilerId(service, compilerId, errStream)) { -+ errStream.println(""[daemon client] found the suitable daemon"") -+ return service -+ } -+ errStream.println(""[daemon client] compiler identity don't match: "" + compilerId.asParams.joinToString("" "")) -+ if (!autostart) return null; -+ errStream.println(""[daemon client] shutdown the daemon"") -+ service.shutdown() -+ // TODO: find more reliable way -+ Thread.sleep(1000) -+ errStream.println(""[daemon client] daemon shut down correctly, restarting"") -+ } -+ else { -+ if (!autostart) return null; -+ else errStream.println(""[daemon client] cannot connect to Compile Daemon, trying to start"") -+ } -+ -+ startDaemon(compilerId, daemonLaunchingOptions, daemonOptions, errStream) -+ errStream.println(""[daemon client] daemon started, trying to connect"") -+ return connectToService(compilerId, daemonOptions, errStream) -+ } -+ -+ public fun shutdownCompileService(): Unit { -+ KotlinCompilerClient.connectToCompileService(CompilerId(), DaemonLaunchingOptions(), DaemonOptions(), System.out, autostart = false, checkId = false) -+ ?.shutdown() -+ } -+ -+ public fun incrementalCompile(compiler: CompileService, args: Array, caches: Map, out: OutputStream): Int { -+ -+ val outStrm = RemoteOutputStreamServer(out) -+ val cacheServers = hashMapOf() -+ try { -+ caches.forEach { cacheServers.put( it.getKey(), RemoteIncrementalCacheServer( it.getValue())) } -+ val res = compiler.remoteIncrementalCompile(args, cacheServers, outStrm, CompileService.OutputFormat.XML) -+ return res -+ } -+ finally { -+ cacheServers.forEach { it.getValue().disconnect() } -+ outStrm.disconnect() -+ } -+ } -+ -+ public fun isDaemonEnabled(): Boolean = System.getProperty(COMPILE_DAEMON_ENABLED_PROPERTY) != null -+ -+ public fun configureDaemonLaunchingOptions(opts: DaemonLaunchingOptions) { -+ System.getProperty(COMPILE_DAEMON_JVM_OPTIONS_PROPERTY)?.let { -+ // TODO: find better way to pass and parse jvm options for daemon -+ opts.jvmParams = it.split(""##"") -+ } -+ } -+ -+ data class ClientOptions( -+ public var stop: Boolean = false -+ ) :CmdlineParams { -+ override val asParams: Iterable -+ get() = -+ if (stop) listOf(""stop"") else listOf() -+ -+ override val parsers: List> -+ get() = listOf( BoolPropParser(this, ::stop)) -+ } -+ -+ platformStatic public fun main(vararg args: String) { -+ val compilerId = CompilerId() -+ val daemonOptions = DaemonOptions() -+ val daemonLaunchingOptions = DaemonLaunchingOptions() -+ val clientOptions = ClientOptions() -+ val filteredArgs = args.asIterable().propParseFilter(compilerId, daemonOptions, daemonLaunchingOptions, clientOptions) -+ -+ if (!clientOptions.stop) { -+ if (compilerId.compilerClasspath.none()) { -+ // attempt to find compiler to use -+ println(""compiler wasn't explicitly specified, attempt to find appropriate jar"") -+ System.getProperty(""java.class.path"") -+ ?.split(File.pathSeparator) -+ ?.map { File(it).parent } -+ ?.distinct() -+ ?.map { -+ it?.walk() -+ ?.firstOrNull { it.getName().equals(COMPILER_JAR_NAME, ignoreCase = true) } -+ } -+ ?.filterNotNull() -+ ?.firstOrNull() -+ ?.let { compilerId.compilerClasspath = listOf(it.absolutePath) } -+ } -+ if (compilerId.compilerClasspath.none()) -+ throw IllegalArgumentException(""Cannot find compiler jar"") -+ else -+ println(""desired compiler classpath: "" + compilerId.compilerClasspath.joinToString(File.pathSeparator)) -+ -+ compilerId.updateDigest() -+ } -+ -+ connectToCompileService(compilerId, daemonLaunchingOptions, daemonOptions, System.out, autostart = !clientOptions.stop, checkId = !clientOptions.stop)?.let { -+ when { -+ clientOptions.stop -> { -+ println(""Shutdown the daemon"") -+ it.shutdown() -+ println(""Daemon shut down successfully"") -+ } -+ else -> { -+ println(""Executing daemon compilation with args: "" + filteredArgs.joinToString("" "")) -+ val outStrm = RemoteOutputStreamServer(System.out) -+ try { -+ val memBefore = it.getUsedMemory() / 1024 -+ val startTime = System.nanoTime() -+ val res = it.remoteCompile(filteredArgs.toArrayList().toTypedArray(), outStrm, CompileService.OutputFormat.PLAIN) -+ val endTime = System.nanoTime()","We can use kotlin's `measureTimeMillis` or `measureTimeNano`: http://kotlinlang.org/api/latest/jvm/stdlib/kotlin.util/index.html -","This isn't related to this PR, but there is a typo here." -197,"@@ -0,0 +1,263 @@ -+/* -+ * 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.rmi.kotlinr -+ -+import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache -+import org.jetbrains.kotlin.rmi.* -+import java.io.File -+import java.io.OutputStream -+import java.io.PrintStream -+import java.rmi.ConnectException -+import java.rmi.Remote -+import java.rmi.registry.LocateRegistry -+import java.util.concurrent.Semaphore -+import java.util.concurrent.TimeUnit -+import kotlin.concurrent.thread -+ -+fun Process.isAlive() = -+ try { -+ this.exitValue() -+ false -+ } -+ catch (e: IllegalThreadStateException) { -+ true -+ } -+ -+public class KotlinCompilerClient { -+ -+ companion object { -+ -+ val DAEMON_STARTUP_TIMEOUT_MS = 10000L -+ -+ private fun connectToService(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): CompileService? { -+ -+ val compilerObj = connectToDaemon(compilerId, daemonOptions, errStream) ?: return null // no registry - no daemon running -+ return compilerObj as? CompileService ?: -+ throw ClassCastException(""Unable to cast compiler service, actual class received: ${compilerObj.javaClass}"") -+ } -+ -+ private fun connectToDaemon(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): Remote? { -+ try { -+ val daemon = LocateRegistry.getRegistry(""localhost"", daemonOptions.port) -+ ?.lookup(COMPILER_SERVICE_RMI_NAME) -+ if (daemon != null) -+ return daemon -+ errStream.println(""[daemon client] daemon not found"") -+ } -+ catch (e: ConnectException) { -+ errStream.println(""[daemon client] cannot connect to registry: "" + (e.getCause()?.getMessage() ?: e.getMessage() ?: ""unknown exception"")) -+ // ignoring it - processing below -+ } -+ return null -+ } -+ -+ -+ private fun startDaemon(compilerId: CompilerId, daemonJVMOptions: DaemonJVMOptions, daemonOptions: DaemonOptions, errStream: PrintStream) { -+ val javaExecutable = File(System.getProperty(""java.home""), ""bin"").let { -+ val javaw = File(it, ""javaw.exe"") -+ if (javaw.exists()) javaw -+ else File(it, ""java"") -+ } -+ // TODO: add some specific environment variables to the cp and may be command line, to allow some specific startup configs -+ val args = listOf(javaExecutable.absolutePath, -+ ""-cp"", compilerId.compilerClasspath.joinToString(File.pathSeparator)) + -+ daemonJVMOptions.mappers.flatMap { it.toArgs(""-"") } + -+ COMPILER_DAEMON_CLASS_FQN + -+ daemonOptions.mappers.flatMap { it.toArgs(COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX) } + -+ compilerId.mappers.flatMap { it.toArgs(COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX) } -+ errStream.println(""[daemon client] starting the daemon as: "" + args.joinToString("" "")) -+ val processBuilder = ProcessBuilder(args).redirectErrorStream(true) -+ // assuming daemon process is deaf and (mostly) silent, so do not handle streams -+ val daemon = processBuilder.start() -+ -+ var isEchoRead = Semaphore(1) -+ isEchoRead.acquire() -+ -+ val stdoutThread = -+ thread { -+ daemon.getInputStream() -+ .reader() -+ .forEachLine { -+ if (daemonOptions.startEcho.isNotEmpty() && it.contains(daemonOptions.startEcho)) { -+ isEchoRead.release() -+ return@forEachLine -+ } -+ errStream.println(""[daemon] "" + it) -+ } -+ } -+ try { -+ // trying to wait for process -+ if (daemonOptions.startEcho.isNotEmpty()) { -+ errStream.println(""[daemon client] waiting for daemon to respond"") -+ val succeeded = isEchoRead.tryAcquire(DAEMON_STARTUP_TIMEOUT_MS, TimeUnit.MILLISECONDS) -+ if (!daemon.isAlive()) -+ throw Exception(""Daemon terminated unexpectedly"") -+ if (!succeeded) -+ throw Exception(""Unable to get response from daemon in $DAEMON_STARTUP_TIMEOUT_MS ms"") -+ } -+ else -+ // without startEcho defined waiting for max timeout -+ Thread.sleep(DAEMON_STARTUP_TIMEOUT_MS) -+ } -+ finally { -+ // assuming that all important output is already done, the rest should be routed to the log by the daemon itself -+ if (stdoutThread.isAlive) -+ // TODO: find better method to stop the thread, but seems it will require asynchronous consuming of the stream -+ stdoutThread.stop() -+ } -+ } -+ -+ public fun checkCompilerId(compiler: CompileService, localId: CompilerId, errStream: PrintStream): Boolean { -+ val remoteId = compiler.getCompilerId() -+ errStream.println(""[daemon client] remoteId = "" + remoteId.toString()) -+ errStream.println(""[daemon client] localId = "" + localId.toString()) -+ return (localId.compilerVersion.isEmpty() || localId.compilerVersion == remoteId.compilerVersion) && -+ (localId.compilerClasspath.all { remoteId.compilerClasspath.contains(it) }) && -+ (localId.compilerDigest.isEmpty() || remoteId.compilerDigest.isEmpty() || localId.compilerDigest == remoteId.compilerDigest) -+ } -+ -+ public fun connectToCompileService(compilerId: CompilerId, daemonJVMOptions: DaemonJVMOptions, daemonOptions: DaemonOptions, errStream: PrintStream, autostart: Boolean = true, checkId: Boolean = true): CompileService? { -+ val service = connectToService(compilerId, daemonOptions, errStream) -+ if (service != null) { -+ if (!checkId || checkCompilerId(service, compilerId, errStream)) { -+ errStream.println(""[daemon client] found the suitable daemon"") -+ return service -+ } -+ errStream.println(""[daemon client] compiler identity don't match: "" + compilerId.mappers.flatMap { it.toArgs("""") }.joinToString("" "")) -+ if (!autostart) return null; -+ errStream.println(""[daemon client] shutdown the daemon"") -+ service.shutdown() -+ // TODO: find more reliable way -+ Thread.sleep(1000) -+ errStream.println(""[daemon client] daemon shut down correctly, restarting"") -+ } -+ else { -+ if (!autostart) return null; -+ else errStream.println(""[daemon client] cannot connect to Compile Daemon, trying to start"") -+ } -+ -+ startDaemon(compilerId, daemonJVMOptions, daemonOptions, errStream) -+ errStream.println(""[daemon client] daemon started, trying to connect"") -+ return connectToService(compilerId, daemonOptions, errStream) -+ } -+ -+ public fun shutdownCompileService(daemonOptions: DaemonOptions): Unit { -+ KotlinCompilerClient.connectToCompileService(CompilerId(), DaemonJVMOptions(), daemonOptions, System.out, autostart = false, checkId = false) -+ ?.shutdown() -+ } -+ -+ public fun shutdownCompileService(): Unit { -+ shutdownCompileService(DaemonOptions()) -+ } -+ -+ public fun compile(compiler: CompileService, args: Array, out: OutputStream): Int { -+ -+ val outStrm = RemoteOutputStreamServer(out) -+ try { -+ return compiler.remoteCompile(args, outStrm, CompileService.OutputFormat.PLAIN) -+ } -+ finally { -+ outStrm.disconnect() -+ } -+ } -+ -+ public fun incrementalCompile(compiler: CompileService, args: Array, caches: Map, out: OutputStream): Int { -+ -+ val outStrm = RemoteOutputStreamServer(out) -+ val cacheServers = hashMapOf() -+ try { -+ caches.mapValuesTo(cacheServers, { RemoteIncrementalCacheServer( it.getValue()) }) -+ return compiler.remoteIncrementalCompile(args, cacheServers, outStrm, CompileService.OutputFormat.XML) -+ } -+ finally { -+ cacheServers.forEach { it.getValue().disconnect() } -+ outStrm.disconnect() -+ } -+ } -+ -+ data class ClientOptions( -+ public var stop: Boolean = false -+ ) : OptionsGroup { -+ override val mappers: List> -+ get() = listOf( BoolPropMapper(this, ::stop)) -+ } -+ -+ jvmStatic public fun main(vararg args: String) { -+ val compilerId = CompilerId() -+ val daemonOptions = DaemonOptions() -+ val daemonLaunchingOptions = DaemonJVMOptions() -+ val clientOptions = ClientOptions() -+ val filteredArgs = args.asIterable().filterExtractProps(compilerId, daemonOptions, daemonLaunchingOptions, clientOptions, prefix = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX) -+ -+ if (!clientOptions.stop) { -+ if (compilerId.compilerClasspath.none()) { -+ // attempt to find compiler to use -+ println(""compiler wasn't explicitly specified, attempt to find appropriate jar"")","Why are you printing this & other information to stdout, not stderr? -",Don't need the `final` here. -198,"@@ -0,0 +1,27 @@ -+/* -+ * 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.effectsystem.structure -+ -+interface ESEffect { -+ /** -+ * Returns: -+ * - true, when presence of `this`-effect necessary implies presence of `other`-effect -+ * - false, when presence of `this`-effect necessary implies absence of `other`-effect -+ * - null, when presence of `this`-effect doesn't implies neither presence nor absence of `other`-effect -+ */ -+ fun isImplies(other: ESEffect): Boolean?",It's matter of taste but I'd use here some enum with three elements,"This isn't a typo, it's a function." -199,"@@ -0,0 +1,271 @@ -+/* -+ * 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.rmi.kotlinr -+ -+import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache -+import org.jetbrains.kotlin.rmi.* -+import java.io.File -+import java.io.OutputStream -+import java.io.PrintStream -+import java.rmi.ConnectException -+import java.rmi.Remote -+import java.rmi.registry.LocateRegistry -+import java.util.concurrent.Semaphore -+import java.util.concurrent.TimeUnit -+import java.util.concurrent.locks.ReentrantReadWriteLock -+import kotlin.concurrent.read -+import kotlin.concurrent.thread -+import kotlin.concurrent.write -+import kotlin.platform.platformStatic -+import kotlin.reflect.KProperty1","Try to run optimize imports and reformat -",Did you mean to commit this file? -200,"@@ -0,0 +1,271 @@ -+/* -+ * 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.rmi.kotlinr -+ -+import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache -+import org.jetbrains.kotlin.rmi.* -+import java.io.File -+import java.io.OutputStream -+import java.io.PrintStream -+import java.rmi.ConnectException -+import java.rmi.Remote -+import java.rmi.registry.LocateRegistry -+import java.util.concurrent.Semaphore -+import java.util.concurrent.TimeUnit -+import java.util.concurrent.locks.ReentrantReadWriteLock -+import kotlin.concurrent.read -+import kotlin.concurrent.thread -+import kotlin.concurrent.write -+import kotlin.platform.platformStatic -+import kotlin.reflect.KProperty1 -+ -+fun Process.isAlive() = -+ try { -+ this.exitValue() -+ false -+ } -+ catch (e: IllegalThreadStateException) { -+ true -+ } -+ -+public class KotlinCompilerClient {","Looks like it should be object -","This package name is wrong, it should be `kotlin.rmi`" -201,"@@ -0,0 +1,271 @@ -+/* -+ * 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.rmi.kotlinr -+ -+import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache -+import org.jetbrains.kotlin.rmi.* -+import java.io.File -+import java.io.OutputStream -+import java.io.PrintStream -+import java.rmi.ConnectException -+import java.rmi.Remote -+import java.rmi.registry.LocateRegistry -+import java.util.concurrent.Semaphore -+import java.util.concurrent.TimeUnit -+import java.util.concurrent.locks.ReentrantReadWriteLock -+import kotlin.concurrent.read -+import kotlin.concurrent.thread -+import kotlin.concurrent.write -+import kotlin.platform.platformStatic -+import kotlin.reflect.KProperty1 -+ -+fun Process.isAlive() = -+ try { -+ this.exitValue() -+ false -+ } -+ catch (e: IllegalThreadStateException) { -+ true -+ } -+ -+public class KotlinCompilerClient { -+ -+ companion object { -+ -+ val DAEMON_STARTUP_TIMEOUT_MS = 10000L","private? -","This isn't a good package name, it took me a long time t" -202,"@@ -0,0 +1,271 @@ -+/* -+ * 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.rmi.kotlinr -+ -+import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache -+import org.jetbrains.kotlin.rmi.* -+import java.io.File -+import java.io.OutputStream -+import java.io.PrintStream -+import java.rmi.ConnectException -+import java.rmi.Remote -+import java.rmi.registry.LocateRegistry -+import java.util.concurrent.Semaphore -+import java.util.concurrent.TimeUnit -+import java.util.concurrent.locks.ReentrantReadWriteLock -+import kotlin.concurrent.read -+import kotlin.concurrent.thread -+import kotlin.concurrent.write -+import kotlin.platform.platformStatic -+import kotlin.reflect.KProperty1 -+ -+fun Process.isAlive() = -+ try { -+ this.exitValue() -+ false -+ } -+ catch (e: IllegalThreadStateException) { -+ true -+ } -+ -+public class KotlinCompilerClient { -+ -+ companion object { -+ -+ val DAEMON_STARTUP_TIMEOUT_MS = 10000L -+ -+ private fun connectToService(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): CompileService? {","we prefer to first declare a public API -","This isn't a good package name, it took me a long time t" -203,"@@ -0,0 +1,271 @@ -+/* -+ * 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.rmi.kotlinr -+ -+import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache -+import org.jetbrains.kotlin.rmi.* -+import java.io.File -+import java.io.OutputStream -+import java.io.PrintStream -+import java.rmi.ConnectException -+import java.rmi.Remote -+import java.rmi.registry.LocateRegistry -+import java.util.concurrent.Semaphore -+import java.util.concurrent.TimeUnit -+import java.util.concurrent.locks.ReentrantReadWriteLock -+import kotlin.concurrent.read -+import kotlin.concurrent.thread -+import kotlin.concurrent.write -+import kotlin.platform.platformStatic -+import kotlin.reflect.KProperty1 -+ -+fun Process.isAlive() = -+ try { -+ this.exitValue() -+ false -+ } -+ catch (e: IllegalThreadStateException) { -+ true -+ } -+ -+public class KotlinCompilerClient { -+ -+ companion object { -+ -+ val DAEMON_STARTUP_TIMEOUT_MS = 10000L -+ -+ private fun connectToService(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): CompileService? { -+ -+ val compilerObj = connectToDaemon(compilerId, daemonOptions, errStream) ?: return null // no registry - no daemon running","minor: I'd inline `connectToDaemon` -","Don't use a private constant here. Also, why not a const" -204,"@@ -0,0 +1,271 @@ -+/* -+ * 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.rmi.kotlinr -+ -+import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache -+import org.jetbrains.kotlin.rmi.* -+import java.io.File -+import java.io.OutputStream -+import java.io.PrintStream -+import java.rmi.ConnectException -+import java.rmi.Remote -+import java.rmi.registry.LocateRegistry -+import java.util.concurrent.Semaphore -+import java.util.concurrent.TimeUnit -+import java.util.concurrent.locks.ReentrantReadWriteLock -+import kotlin.concurrent.read -+import kotlin.concurrent.thread -+import kotlin.concurrent.write -+import kotlin.platform.platformStatic -+import kotlin.reflect.KProperty1 -+ -+fun Process.isAlive() = -+ try { -+ this.exitValue() -+ false -+ } -+ catch (e: IllegalThreadStateException) { -+ true -+ } -+ -+public class KotlinCompilerClient { -+ -+ companion object { -+ -+ val DAEMON_STARTUP_TIMEOUT_MS = 10000L -+ -+ private fun connectToService(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): CompileService? { -+ -+ val compilerObj = connectToDaemon(compilerId, daemonOptions, errStream) ?: return null // no registry - no daemon running -+ return compilerObj as? CompileService ?:","Why ClassCastException is not enough here? -",missing a blank line here -205,"@@ -0,0 +1,271 @@ -+/* -+ * 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.rmi.kotlinr -+ -+import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache -+import org.jetbrains.kotlin.rmi.* -+import java.io.File -+import java.io.OutputStream -+import java.io.PrintStream -+import java.rmi.ConnectException -+import java.rmi.Remote -+import java.rmi.registry.LocateRegistry -+import java.util.concurrent.Semaphore -+import java.util.concurrent.TimeUnit -+import java.util.concurrent.locks.ReentrantReadWriteLock -+import kotlin.concurrent.read -+import kotlin.concurrent.thread -+import kotlin.concurrent.write -+import kotlin.platform.platformStatic -+import kotlin.reflect.KProperty1 -+ -+fun Process.isAlive() = -+ try { -+ this.exitValue() -+ false -+ } -+ catch (e: IllegalThreadStateException) { -+ true -+ } -+ -+public class KotlinCompilerClient { -+ -+ companion object { -+ -+ val DAEMON_STARTUP_TIMEOUT_MS = 10000L -+ -+ private fun connectToService(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): CompileService? { -+ -+ val compilerObj = connectToDaemon(compilerId, daemonOptions, errStream) ?: return null // no registry - no daemon running -+ return compilerObj as? CompileService ?: -+ throw ClassCastException(""Unable to cast compiler service, actual class received: ${compilerObj.javaClass}"") -+ } -+ -+ private fun connectToDaemon(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): Remote? { -+ try { -+ val daemon = LocateRegistry.getRegistry(""localhost"", daemonOptions.port) -+ ?.lookup(COMPILER_SERVICE_RMI_NAME) -+ if (daemon != null)","We prefer to use braces in `if` except one-line ifs: `if (cond) return/break/continue` -",missing a blank line here -206,"@@ -0,0 +1,271 @@ -+/* -+ * 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.rmi.kotlinr -+ -+import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache -+import org.jetbrains.kotlin.rmi.* -+import java.io.File -+import java.io.OutputStream -+import java.io.PrintStream -+import java.rmi.ConnectException -+import java.rmi.Remote -+import java.rmi.registry.LocateRegistry -+import java.util.concurrent.Semaphore -+import java.util.concurrent.TimeUnit -+import java.util.concurrent.locks.ReentrantReadWriteLock -+import kotlin.concurrent.read -+import kotlin.concurrent.thread -+import kotlin.concurrent.write -+import kotlin.platform.platformStatic -+import kotlin.reflect.KProperty1 -+ -+fun Process.isAlive() = -+ try { -+ this.exitValue() -+ false -+ } -+ catch (e: IllegalThreadStateException) { -+ true -+ } -+ -+public class KotlinCompilerClient { -+ -+ companion object { -+ -+ val DAEMON_STARTUP_TIMEOUT_MS = 10000L -+ -+ private fun connectToService(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): CompileService? { -+ -+ val compilerObj = connectToDaemon(compilerId, daemonOptions, errStream) ?: return null // no registry - no daemon running -+ return compilerObj as? CompileService ?: -+ throw ClassCastException(""Unable to cast compiler service, actual class received: ${compilerObj.javaClass}"") -+ } -+ -+ private fun connectToDaemon(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): Remote? { -+ try { -+ val daemon = LocateRegistry.getRegistry(""localhost"", daemonOptions.port) -+ ?.lookup(COMPILER_SERVICE_RMI_NAME) -+ if (daemon != null) -+ return daemon -+ errStream.println(""[daemon client] daemon not found"") -+ } -+ catch (e: ConnectException) { -+ errStream.println(""[daemon client] cannot connect to registry: "" + (e.getCause()?.getMessage() ?: e.getMessage() ?: ""unknown exception"")) -+ // ignoring it - processing below -+ } -+ return null -+ } -+ -+ -+ private fun startDaemon(compilerId: CompilerId, daemonLaunchingOptions: DaemonLaunchingOptions, daemonOptions: DaemonOptions, errStream: PrintStream) { -+ val javaExecutable = File(System.getProperty(""java.home""), ""bin"").let { -+ val javaw = File(it, ""javaw.exe"") -+ if (javaw.exists()) javaw -+ else File(it, ""java"") -+ } -+ // TODO: add some specific environment variables to the cp and may be command line, to allow some specific startup configs -+ val args = listOf(javaExecutable.absolutePath, -+ ""-cp"", compilerId.compilerClasspath.joinToString(File.pathSeparator)) + -+ daemonLaunchingOptions.extractors.flatMap { it.extract(""-"") } + -+ COMPILER_DAEMON_CLASS_FQN + -+ daemonOptions.extractors.flatMap { it.extract(COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX) } + -+ compilerId.extractors.flatMap { it.extract(COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX) } -+ errStream.println(""[daemon client] starting the daemon as: "" + args.joinToString("" "")) -+ val processBuilder = ProcessBuilder(args).redirectErrorStream(true) -+ // assuming daemon process is deaf and (mostly) silent, so do not handle streams -+ val daemon = processBuilder.start() -+ -+ var isEchoRead = Semaphore(1) -+ isEchoRead.acquire() -+ -+ val stdoutThread = -+ thread { -+ daemon.getInputStream() -+ .reader() -+ .forEachLine { -+ if (daemonOptions.startEcho.isNotEmpty() && it.contains(daemonOptions.startEcho)) { -+ isEchoRead.release() -+ return@forEachLine -+ } -+ errStream.println(""[daemon] "" + it) -+ } -+ } -+ try { -+ // trying to wait for process -+ if (daemonOptions.startEcho.isNotEmpty()) { -+ errStream.println(""[daemon client] waiting for daemon to respond"") -+ val succeeded = isEchoRead.tryAcquire(DAEMON_STARTUP_TIMEOUT_MS, TimeUnit.MILLISECONDS) -+ if (!daemon.isAlive()) -+ throw Exception(""Daemon terminated unexpectedly"") -+ if (!succeeded) -+ throw Exception(""Unable to get response from daemon in $DAEMON_STARTUP_TIMEOUT_MS ms"") -+ } -+ else","braces -",missing a blank line here -207,"@@ -0,0 +1,271 @@ -+/* -+ * 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.rmi.kotlinr -+ -+import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache -+import org.jetbrains.kotlin.rmi.* -+import java.io.File -+import java.io.OutputStream -+import java.io.PrintStream -+import java.rmi.ConnectException -+import java.rmi.Remote -+import java.rmi.registry.LocateRegistry -+import java.util.concurrent.Semaphore -+import java.util.concurrent.TimeUnit -+import java.util.concurrent.locks.ReentrantReadWriteLock -+import kotlin.concurrent.read -+import kotlin.concurrent.thread -+import kotlin.concurrent.write -+import kotlin.platform.platformStatic -+import kotlin.reflect.KProperty1 -+ -+fun Process.isAlive() = -+ try { -+ this.exitValue() -+ false -+ } -+ catch (e: IllegalThreadStateException) { -+ true -+ } -+ -+public class KotlinCompilerClient { -+ -+ companion object { -+ -+ val DAEMON_STARTUP_TIMEOUT_MS = 10000L -+ -+ private fun connectToService(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): CompileService? { -+ -+ val compilerObj = connectToDaemon(compilerId, daemonOptions, errStream) ?: return null // no registry - no daemon running -+ return compilerObj as? CompileService ?: -+ throw ClassCastException(""Unable to cast compiler service, actual class received: ${compilerObj.javaClass}"") -+ } -+ -+ private fun connectToDaemon(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): Remote? { -+ try { -+ val daemon = LocateRegistry.getRegistry(""localhost"", daemonOptions.port) -+ ?.lookup(COMPILER_SERVICE_RMI_NAME) -+ if (daemon != null) -+ return daemon -+ errStream.println(""[daemon client] daemon not found"") -+ } -+ catch (e: ConnectException) { -+ errStream.println(""[daemon client] cannot connect to registry: "" + (e.getCause()?.getMessage() ?: e.getMessage() ?: ""unknown exception"")) -+ // ignoring it - processing below -+ } -+ return null -+ } -+ -+ -+ private fun startDaemon(compilerId: CompilerId, daemonLaunchingOptions: DaemonLaunchingOptions, daemonOptions: DaemonOptions, errStream: PrintStream) { -+ val javaExecutable = File(System.getProperty(""java.home""), ""bin"").let { -+ val javaw = File(it, ""javaw.exe"") -+ if (javaw.exists()) javaw -+ else File(it, ""java"") -+ } -+ // TODO: add some specific environment variables to the cp and may be command line, to allow some specific startup configs -+ val args = listOf(javaExecutable.absolutePath, -+ ""-cp"", compilerId.compilerClasspath.joinToString(File.pathSeparator)) + -+ daemonLaunchingOptions.extractors.flatMap { it.extract(""-"") } + -+ COMPILER_DAEMON_CLASS_FQN + -+ daemonOptions.extractors.flatMap { it.extract(COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX) } + -+ compilerId.extractors.flatMap { it.extract(COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX) } -+ errStream.println(""[daemon client] starting the daemon as: "" + args.joinToString("" "")) -+ val processBuilder = ProcessBuilder(args).redirectErrorStream(true) -+ // assuming daemon process is deaf and (mostly) silent, so do not handle streams -+ val daemon = processBuilder.start() -+ -+ var isEchoRead = Semaphore(1) -+ isEchoRead.acquire() -+ -+ val stdoutThread = -+ thread { -+ daemon.getInputStream() -+ .reader() -+ .forEachLine { -+ if (daemonOptions.startEcho.isNotEmpty() && it.contains(daemonOptions.startEcho)) { -+ isEchoRead.release() -+ return@forEachLine -+ } -+ errStream.println(""[daemon] "" + it) -+ } -+ } -+ try { -+ // trying to wait for process -+ if (daemonOptions.startEcho.isNotEmpty()) { -+ errStream.println(""[daemon client] waiting for daemon to respond"") -+ val succeeded = isEchoRead.tryAcquire(DAEMON_STARTUP_TIMEOUT_MS, TimeUnit.MILLISECONDS) -+ if (!daemon.isAlive()) -+ throw Exception(""Daemon terminated unexpectedly"") -+ if (!succeeded) -+ throw Exception(""Unable to get response from daemon in $DAEMON_STARTUP_TIMEOUT_MS ms"") -+ } -+ else -+ // without startEcho defined waiting for max timeout -+ Thread.sleep(DAEMON_STARTUP_TIMEOUT_MS) -+ } -+ finally { -+ // assuming that all important output is already done, the rest should be routed to the log by the daemon itself -+ if (stdoutThread.isAlive) -+ // TODO: find better method to stop the thread, but seems it will require asynchronous consuming of the stream -+ stdoutThread.stop() -+ } -+ } -+ -+ public fun checkCompilerId(compiler: CompileService, localId: CompilerId, errStream: PrintStream): Boolean { -+ val remoteId = compiler.getCompilerId() -+ errStream.println(""[daemon client] remoteId = "" + remoteId.toString()) -+ errStream.println(""[daemon client] localId = "" + localId.toString()) -+ return (localId.compilerVersion.isEmpty() || localId.compilerVersion == remoteId.compilerVersion) &&","why we skip empty parameters? -",missing a blank line here -208,"@@ -0,0 +1,271 @@ -+/* -+ * 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.rmi.kotlinr -+ -+import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache -+import org.jetbrains.kotlin.rmi.* -+import java.io.File -+import java.io.OutputStream -+import java.io.PrintStream -+import java.rmi.ConnectException -+import java.rmi.Remote -+import java.rmi.registry.LocateRegistry -+import java.util.concurrent.Semaphore -+import java.util.concurrent.TimeUnit -+import java.util.concurrent.locks.ReentrantReadWriteLock -+import kotlin.concurrent.read -+import kotlin.concurrent.thread -+import kotlin.concurrent.write -+import kotlin.platform.platformStatic -+import kotlin.reflect.KProperty1 -+ -+fun Process.isAlive() = -+ try { -+ this.exitValue() -+ false -+ } -+ catch (e: IllegalThreadStateException) { -+ true -+ } -+ -+public class KotlinCompilerClient { -+ -+ companion object { -+ -+ val DAEMON_STARTUP_TIMEOUT_MS = 10000L -+ -+ private fun connectToService(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): CompileService? { -+ -+ val compilerObj = connectToDaemon(compilerId, daemonOptions, errStream) ?: return null // no registry - no daemon running -+ return compilerObj as? CompileService ?: -+ throw ClassCastException(""Unable to cast compiler service, actual class received: ${compilerObj.javaClass}"") -+ } -+ -+ private fun connectToDaemon(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): Remote? { -+ try { -+ val daemon = LocateRegistry.getRegistry(""localhost"", daemonOptions.port) -+ ?.lookup(COMPILER_SERVICE_RMI_NAME) -+ if (daemon != null) -+ return daemon -+ errStream.println(""[daemon client] daemon not found"") -+ } -+ catch (e: ConnectException) { -+ errStream.println(""[daemon client] cannot connect to registry: "" + (e.getCause()?.getMessage() ?: e.getMessage() ?: ""unknown exception"")) -+ // ignoring it - processing below -+ } -+ return null -+ } -+ -+ -+ private fun startDaemon(compilerId: CompilerId, daemonLaunchingOptions: DaemonLaunchingOptions, daemonOptions: DaemonOptions, errStream: PrintStream) { -+ val javaExecutable = File(System.getProperty(""java.home""), ""bin"").let { -+ val javaw = File(it, ""javaw.exe"") -+ if (javaw.exists()) javaw -+ else File(it, ""java"") -+ } -+ // TODO: add some specific environment variables to the cp and may be command line, to allow some specific startup configs -+ val args = listOf(javaExecutable.absolutePath, -+ ""-cp"", compilerId.compilerClasspath.joinToString(File.pathSeparator)) + -+ daemonLaunchingOptions.extractors.flatMap { it.extract(""-"") } + -+ COMPILER_DAEMON_CLASS_FQN + -+ daemonOptions.extractors.flatMap { it.extract(COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX) } + -+ compilerId.extractors.flatMap { it.extract(COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX) } -+ errStream.println(""[daemon client] starting the daemon as: "" + args.joinToString("" "")) -+ val processBuilder = ProcessBuilder(args).redirectErrorStream(true) -+ // assuming daemon process is deaf and (mostly) silent, so do not handle streams -+ val daemon = processBuilder.start() -+ -+ var isEchoRead = Semaphore(1) -+ isEchoRead.acquire() -+ -+ val stdoutThread = -+ thread { -+ daemon.getInputStream() -+ .reader() -+ .forEachLine { -+ if (daemonOptions.startEcho.isNotEmpty() && it.contains(daemonOptions.startEcho)) { -+ isEchoRead.release() -+ return@forEachLine -+ } -+ errStream.println(""[daemon] "" + it) -+ } -+ } -+ try { -+ // trying to wait for process -+ if (daemonOptions.startEcho.isNotEmpty()) { -+ errStream.println(""[daemon client] waiting for daemon to respond"") -+ val succeeded = isEchoRead.tryAcquire(DAEMON_STARTUP_TIMEOUT_MS, TimeUnit.MILLISECONDS) -+ if (!daemon.isAlive()) -+ throw Exception(""Daemon terminated unexpectedly"") -+ if (!succeeded) -+ throw Exception(""Unable to get response from daemon in $DAEMON_STARTUP_TIMEOUT_MS ms"") -+ } -+ else -+ // without startEcho defined waiting for max timeout -+ Thread.sleep(DAEMON_STARTUP_TIMEOUT_MS) -+ } -+ finally { -+ // assuming that all important output is already done, the rest should be routed to the log by the daemon itself -+ if (stdoutThread.isAlive) -+ // TODO: find better method to stop the thread, but seems it will require asynchronous consuming of the stream -+ stdoutThread.stop() -+ } -+ } -+ -+ public fun checkCompilerId(compiler: CompileService, localId: CompilerId, errStream: PrintStream): Boolean { -+ val remoteId = compiler.getCompilerId() -+ errStream.println(""[daemon client] remoteId = "" + remoteId.toString()) -+ errStream.println(""[daemon client] localId = "" + localId.toString()) -+ return (localId.compilerVersion.isEmpty() || localId.compilerVersion == remoteId.compilerVersion) && -+ (localId.compilerClasspath.all { remoteId.compilerClasspath.contains(it) }) &&","`containsAll` -",missing a blank line here -209,"@@ -0,0 +1,272 @@ -+/* -+ * 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.rmi -+ -+import java.io.File -+import java.io.Serializable -+import java.lang.management.ManagementFactory -+import java.security.DigestInputStream -+import java.security.MessageDigest -+import kotlin.platform.platformStatic -+import kotlin.reflect.KMutableProperty1 -+import kotlin.reflect.KProperty1 -+ -+ -+public val COMPILER_JAR_NAME: String = ""kotlin-compiler.jar"" -+public val COMPILER_SERVICE_RMI_NAME: String = ""KotlinJvmCompilerService"" -+public val COMPILER_DAEMON_CLASS_FQN: String = ""org.jetbrains.kotlin.rmi.service.CompileDaemon"" -+public val COMPILE_DAEMON_DEFAULT_PORT: Int = 17031 -+public val COMPILE_DAEMON_ENABLED_PROPERTY: String =""kotlin.daemon.enabled"" -+public val COMPILE_DAEMON_JVM_OPTIONS_PROPERTY: String =""kotlin.daemon.jvm.options"" -+public val COMPILE_DAEMON_OPTIONS_PROPERTY: String =""kotlin.daemon.options"" -+public val COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX: String =""--daemon-"" -+ -+ -+open class PropExtractor>(val dest: C, -+ val prop: P, -+ val name: String, -+ val convert: ((v: V) -> String?) = { it.toString() }, -+ val skipIf: ((v: V) -> Boolean) = { false }, -+ val mergeWithDelimiter: String? = null) -+{ -+ constructor(dest: C, prop: P, convert: ((v: V) -> String?) = { it.toString() }, skipIf: ((v: V) -> Boolean) = { false }) : this(dest, prop, prop.name, convert, skipIf)","i'd just add default value for `name` to primary constructor -",Maybe use a different nam -210,"@@ -0,0 +1,272 @@ -+/* -+ * 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.rmi -+ -+import java.io.File -+import java.io.Serializable -+import java.lang.management.ManagementFactory -+import java.security.DigestInputStream -+import java.security.MessageDigest -+import kotlin.platform.platformStatic -+import kotlin.reflect.KMutableProperty1 -+import kotlin.reflect.KProperty1 -+ -+ -+public val COMPILER_JAR_NAME: String = ""kotlin-compiler.jar"" -+public val COMPILER_SERVICE_RMI_NAME: String = ""KotlinJvmCompilerService"" -+public val COMPILER_DAEMON_CLASS_FQN: String = ""org.jetbrains.kotlin.rmi.service.CompileDaemon"" -+public val COMPILE_DAEMON_DEFAULT_PORT: Int = 17031 -+public val COMPILE_DAEMON_ENABLED_PROPERTY: String =""kotlin.daemon.enabled"" -+public val COMPILE_DAEMON_JVM_OPTIONS_PROPERTY: String =""kotlin.daemon.jvm.options"" -+public val COMPILE_DAEMON_OPTIONS_PROPERTY: String =""kotlin.daemon.options"" -+public val COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX: String =""--daemon-"" -+ -+ -+open class PropExtractor>(val dest: C, -+ val prop: P, -+ val name: String, -+ val convert: ((v: V) -> String?) = { it.toString() }, -+ val skipIf: ((v: V) -> Boolean) = { false }, -+ val mergeWithDelimiter: String? = null) -+{ -+ constructor(dest: C, prop: P, convert: ((v: V) -> String?) = { it.toString() }, skipIf: ((v: V) -> Boolean) = { false }) : this(dest, prop, prop.name, convert, skipIf) -+ open fun extract(prefix: String = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX): List = -+ when { -+ skipIf(prop.get(dest)) -> listOf() -+ mergeWithDelimiter != null -> listOf(prefix + name + mergeWithDelimiter + convert(prop.get(dest))).filterNotNull()","we can get list with string which ends with ""null"" and `filterNotNull` is unnecessary here -",Maybe use a different nam -211,"@@ -0,0 +1,272 @@ -+/* -+ * 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.rmi -+ -+import java.io.File -+import java.io.Serializable -+import java.lang.management.ManagementFactory -+import java.security.DigestInputStream -+import java.security.MessageDigest -+import kotlin.platform.platformStatic -+import kotlin.reflect.KMutableProperty1 -+import kotlin.reflect.KProperty1 -+ -+ -+public val COMPILER_JAR_NAME: String = ""kotlin-compiler.jar"" -+public val COMPILER_SERVICE_RMI_NAME: String = ""KotlinJvmCompilerService"" -+public val COMPILER_DAEMON_CLASS_FQN: String = ""org.jetbrains.kotlin.rmi.service.CompileDaemon"" -+public val COMPILE_DAEMON_DEFAULT_PORT: Int = 17031 -+public val COMPILE_DAEMON_ENABLED_PROPERTY: String =""kotlin.daemon.enabled"" -+public val COMPILE_DAEMON_JVM_OPTIONS_PROPERTY: String =""kotlin.daemon.jvm.options"" -+public val COMPILE_DAEMON_OPTIONS_PROPERTY: String =""kotlin.daemon.options"" -+public val COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX: String =""--daemon-"" -+ -+ -+open class PropExtractor>(val dest: C, -+ val prop: P, -+ val name: String, -+ val convert: ((v: V) -> String?) = { it.toString() }, -+ val skipIf: ((v: V) -> Boolean) = { false }, -+ val mergeWithDelimiter: String? = null) -+{ -+ constructor(dest: C, prop: P, convert: ((v: V) -> String?) = { it.toString() }, skipIf: ((v: V) -> Boolean) = { false }) : this(dest, prop, prop.name, convert, skipIf) -+ open fun extract(prefix: String = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX): List = -+ when { -+ skipIf(prop.get(dest)) -> listOf() -+ mergeWithDelimiter != null -> listOf(prefix + name + mergeWithDelimiter + convert(prop.get(dest))).filterNotNull() -+ else -> listOf(prefix + name, convert(prop.get(dest))).filterNotNull() -+ } -+} -+ -+class BoolPropExtractor>(dest: C, prop: P, name: String? = null) -+ : PropExtractor(dest, prop, name ?: prop.name, convert = { null }, skipIf = { !prop.get(dest) }) -+ -+class RestPropExtractor>>(dest: C, prop: P) : PropExtractor, P>(dest, prop, convert = { null }) { -+ override fun extract(prefix: String): List = prop.get(dest).map { prefix + it } -+} -+ -+ -+open class PropParser>(val dest: C, -+ val prop: P, alternativeNames: List, -+ val parse: (s: String) -> V, -+ val allowMergedArg: Boolean = false) { -+ val names = listOf(prop.name) + alternativeNames -+ constructor(dest: C, prop: P, parse: (s: String) -> V, allowMergedArg: Boolean = false) : this(dest, prop, listOf(), parse, allowMergedArg) -+ fun apply(s: String) = prop.set(dest, parse(s)) -+} -+ -+class BoolPropParser>(dest: C, prop: P): PropParser(dest, prop, { true }) -+ -+class RestPropParser>>(dest: C, prop: P): PropParser, P>(dest, prop, { arrayListOf() }) { -+ fun add(s: String) { prop.get(dest).add(s) } -+} -+ -+ -+fun Iterable.filterSetProps(parsers: List>, prefix: String, restParser: RestPropParser<*,*>? = null) : Iterable {","I think we need better name for this function -",Maybe use a different nam -212,"@@ -0,0 +1,272 @@ -+/* -+ * 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.rmi -+ -+import java.io.File -+import java.io.Serializable -+import java.lang.management.ManagementFactory -+import java.security.DigestInputStream -+import java.security.MessageDigest -+import kotlin.platform.platformStatic -+import kotlin.reflect.KMutableProperty1 -+import kotlin.reflect.KProperty1 -+ -+ -+public val COMPILER_JAR_NAME: String = ""kotlin-compiler.jar"" -+public val COMPILER_SERVICE_RMI_NAME: String = ""KotlinJvmCompilerService"" -+public val COMPILER_DAEMON_CLASS_FQN: String = ""org.jetbrains.kotlin.rmi.service.CompileDaemon"" -+public val COMPILE_DAEMON_DEFAULT_PORT: Int = 17031 -+public val COMPILE_DAEMON_ENABLED_PROPERTY: String =""kotlin.daemon.enabled"" -+public val COMPILE_DAEMON_JVM_OPTIONS_PROPERTY: String =""kotlin.daemon.jvm.options"" -+public val COMPILE_DAEMON_OPTIONS_PROPERTY: String =""kotlin.daemon.options"" -+public val COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX: String =""--daemon-"" -+ -+ -+open class PropExtractor>(val dest: C, -+ val prop: P, -+ val name: String, -+ val convert: ((v: V) -> String?) = { it.toString() }, -+ val skipIf: ((v: V) -> Boolean) = { false }, -+ val mergeWithDelimiter: String? = null) -+{ -+ constructor(dest: C, prop: P, convert: ((v: V) -> String?) = { it.toString() }, skipIf: ((v: V) -> Boolean) = { false }) : this(dest, prop, prop.name, convert, skipIf) -+ open fun extract(prefix: String = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX): List = -+ when { -+ skipIf(prop.get(dest)) -> listOf() -+ mergeWithDelimiter != null -> listOf(prefix + name + mergeWithDelimiter + convert(prop.get(dest))).filterNotNull() -+ else -> listOf(prefix + name, convert(prop.get(dest))).filterNotNull() -+ } -+} -+ -+class BoolPropExtractor>(dest: C, prop: P, name: String? = null) -+ : PropExtractor(dest, prop, name ?: prop.name, convert = { null }, skipIf = { !prop.get(dest) }) -+ -+class RestPropExtractor>>(dest: C, prop: P) : PropExtractor, P>(dest, prop, convert = { null }) { -+ override fun extract(prefix: String): List = prop.get(dest).map { prefix + it } -+} -+ -+ -+open class PropParser>(val dest: C, -+ val prop: P, alternativeNames: List, -+ val parse: (s: String) -> V, -+ val allowMergedArg: Boolean = false) { -+ val names = listOf(prop.name) + alternativeNames -+ constructor(dest: C, prop: P, parse: (s: String) -> V, allowMergedArg: Boolean = false) : this(dest, prop, listOf(), parse, allowMergedArg) -+ fun apply(s: String) = prop.set(dest, parse(s)) -+} -+ -+class BoolPropParser>(dest: C, prop: P): PropParser(dest, prop, { true }) -+ -+class RestPropParser>>(dest: C, prop: P): PropParser, P>(dest, prop, { arrayListOf() }) { -+ fun add(s: String) { prop.get(dest).add(s) } -+} -+ -+ -+fun Iterable.filterSetProps(parsers: List>, prefix: String, restParser: RestPropParser<*,*>? = null) : Iterable { -+ var currentParser: PropParser<*,*,*>? = null -+ var matchingOption = """" -+ val res = filter { param ->","I think it'll be simpler if rewrite with `while` -",Maybe use a different nam -213,"@@ -0,0 +1,272 @@ -+/* -+ * 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.rmi -+ -+import java.io.File -+import java.io.Serializable -+import java.lang.management.ManagementFactory -+import java.security.DigestInputStream -+import java.security.MessageDigest -+import kotlin.platform.platformStatic -+import kotlin.reflect.KMutableProperty1 -+import kotlin.reflect.KProperty1 -+ -+ -+public val COMPILER_JAR_NAME: String = ""kotlin-compiler.jar"" -+public val COMPILER_SERVICE_RMI_NAME: String = ""KotlinJvmCompilerService"" -+public val COMPILER_DAEMON_CLASS_FQN: String = ""org.jetbrains.kotlin.rmi.service.CompileDaemon"" -+public val COMPILE_DAEMON_DEFAULT_PORT: Int = 17031 -+public val COMPILE_DAEMON_ENABLED_PROPERTY: String =""kotlin.daemon.enabled"" -+public val COMPILE_DAEMON_JVM_OPTIONS_PROPERTY: String =""kotlin.daemon.jvm.options"" -+public val COMPILE_DAEMON_OPTIONS_PROPERTY: String =""kotlin.daemon.options"" -+public val COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX: String =""--daemon-"" -+ -+ -+open class PropExtractor>(val dest: C, -+ val prop: P, -+ val name: String, -+ val convert: ((v: V) -> String?) = { it.toString() }, -+ val skipIf: ((v: V) -> Boolean) = { false }, -+ val mergeWithDelimiter: String? = null) -+{ -+ constructor(dest: C, prop: P, convert: ((v: V) -> String?) = { it.toString() }, skipIf: ((v: V) -> Boolean) = { false }) : this(dest, prop, prop.name, convert, skipIf) -+ open fun extract(prefix: String = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX): List = -+ when { -+ skipIf(prop.get(dest)) -> listOf() -+ mergeWithDelimiter != null -> listOf(prefix + name + mergeWithDelimiter + convert(prop.get(dest))).filterNotNull() -+ else -> listOf(prefix + name, convert(prop.get(dest))).filterNotNull() -+ } -+} -+ -+class BoolPropExtractor>(dest: C, prop: P, name: String? = null) -+ : PropExtractor(dest, prop, name ?: prop.name, convert = { null }, skipIf = { !prop.get(dest) }) -+ -+class RestPropExtractor>>(dest: C, prop: P) : PropExtractor, P>(dest, prop, convert = { null }) { -+ override fun extract(prefix: String): List = prop.get(dest).map { prefix + it } -+} -+ -+ -+open class PropParser>(val dest: C, -+ val prop: P, alternativeNames: List, -+ val parse: (s: String) -> V, -+ val allowMergedArg: Boolean = false) { -+ val names = listOf(prop.name) + alternativeNames -+ constructor(dest: C, prop: P, parse: (s: String) -> V, allowMergedArg: Boolean = false) : this(dest, prop, listOf(), parse, allowMergedArg) -+ fun apply(s: String) = prop.set(dest, parse(s)) -+} -+ -+class BoolPropParser>(dest: C, prop: P): PropParser(dest, prop, { true }) -+ -+class RestPropParser>>(dest: C, prop: P): PropParser, P>(dest, prop, { arrayListOf() }) { -+ fun add(s: String) { prop.get(dest).add(s) } -+} -+ -+ -+fun Iterable.filterSetProps(parsers: List>, prefix: String, restParser: RestPropParser<*,*>? = null) : Iterable { -+ var currentParser: PropParser<*,*,*>? = null -+ var matchingOption = """" -+ val res = filter { param -> -+ if (currentParser == null) { -+ val parser = parsers.find { it.names.any { name -> -+ if (param.startsWith(prefix + name)) { matchingOption = prefix + name; true }","replace `;` with `\n` -",Maybe use a different nam -214,"@@ -0,0 +1,272 @@ -+/* -+ * 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.rmi -+ -+import java.io.File -+import java.io.Serializable -+import java.lang.management.ManagementFactory -+import java.security.DigestInputStream -+import java.security.MessageDigest -+import kotlin.platform.platformStatic -+import kotlin.reflect.KMutableProperty1 -+import kotlin.reflect.KProperty1 -+ -+ -+public val COMPILER_JAR_NAME: String = ""kotlin-compiler.jar"" -+public val COMPILER_SERVICE_RMI_NAME: String = ""KotlinJvmCompilerService"" -+public val COMPILER_DAEMON_CLASS_FQN: String = ""org.jetbrains.kotlin.rmi.service.CompileDaemon"" -+public val COMPILE_DAEMON_DEFAULT_PORT: Int = 17031 -+public val COMPILE_DAEMON_ENABLED_PROPERTY: String =""kotlin.daemon.enabled"" -+public val COMPILE_DAEMON_JVM_OPTIONS_PROPERTY: String =""kotlin.daemon.jvm.options"" -+public val COMPILE_DAEMON_OPTIONS_PROPERTY: String =""kotlin.daemon.options"" -+public val COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX: String =""--daemon-"" -+ -+ -+open class PropExtractor>(val dest: C, -+ val prop: P, -+ val name: String, -+ val convert: ((v: V) -> String?) = { it.toString() }, -+ val skipIf: ((v: V) -> Boolean) = { false }, -+ val mergeWithDelimiter: String? = null) -+{ -+ constructor(dest: C, prop: P, convert: ((v: V) -> String?) = { it.toString() }, skipIf: ((v: V) -> Boolean) = { false }) : this(dest, prop, prop.name, convert, skipIf) -+ open fun extract(prefix: String = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX): List = -+ when { -+ skipIf(prop.get(dest)) -> listOf() -+ mergeWithDelimiter != null -> listOf(prefix + name + mergeWithDelimiter + convert(prop.get(dest))).filterNotNull() -+ else -> listOf(prefix + name, convert(prop.get(dest))).filterNotNull() -+ } -+} -+ -+class BoolPropExtractor>(dest: C, prop: P, name: String? = null) -+ : PropExtractor(dest, prop, name ?: prop.name, convert = { null }, skipIf = { !prop.get(dest) }) -+ -+class RestPropExtractor>>(dest: C, prop: P) : PropExtractor, P>(dest, prop, convert = { null }) { -+ override fun extract(prefix: String): List = prop.get(dest).map { prefix + it } -+} -+ -+ -+open class PropParser>(val dest: C, -+ val prop: P, alternativeNames: List, -+ val parse: (s: String) -> V, -+ val allowMergedArg: Boolean = false) { -+ val names = listOf(prop.name) + alternativeNames -+ constructor(dest: C, prop: P, parse: (s: String) -> V, allowMergedArg: Boolean = false) : this(dest, prop, listOf(), parse, allowMergedArg) -+ fun apply(s: String) = prop.set(dest, parse(s)) -+} -+ -+class BoolPropParser>(dest: C, prop: P): PropParser(dest, prop, { true }) -+ -+class RestPropParser>>(dest: C, prop: P): PropParser, P>(dest, prop, { arrayListOf() }) { -+ fun add(s: String) { prop.get(dest).add(s) } -+} -+ -+ -+fun Iterable.filterSetProps(parsers: List>, prefix: String, restParser: RestPropParser<*,*>? = null) : Iterable { -+ var currentParser: PropParser<*,*,*>? = null -+ var matchingOption = """" -+ val res = filter { param -> -+ if (currentParser == null) { -+ val parser = parsers.find { it.names.any { name -> -+ if (param.startsWith(prefix + name)) { matchingOption = prefix + name; true } -+ else false } } -+ if (parser != null) { -+ val optionLength = matchingOption.length() -+ when { -+ parser is BoolPropParser<*,*> -> -+ if (param.length() > optionLength) throw IllegalArgumentException(""Invalid switch option '$param', expecting $matchingOption without arguments"") -+ else parser.apply("""") -+ param.length() > optionLength -> -+ if (param[optionLength] != '=') { -+ if (parser.allowMergedArg) parser.apply(param.substring(optionLength)) -+ else throw IllegalArgumentException(""Invalid option syntax '$param', expecting $matchingOption[= ]"") -+ } -+ else parser.apply(param.substring(optionLength + 1)) -+ else -> currentParser = parser -+ } -+ false -+ } -+ else if (restParser != null && param.startsWith(prefix)) { -+ restParser.add(param.removePrefix(prefix)) -+ false -+ } -+ else true","please don't mix blocks with and without braces -",Maybe use a different nam -215,"@@ -0,0 +1,272 @@ -+/* -+ * 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.rmi -+ -+import java.io.File -+import java.io.Serializable -+import java.lang.management.ManagementFactory -+import java.security.DigestInputStream -+import java.security.MessageDigest -+import kotlin.platform.platformStatic -+import kotlin.reflect.KMutableProperty1 -+import kotlin.reflect.KProperty1 -+ -+ -+public val COMPILER_JAR_NAME: String = ""kotlin-compiler.jar"" -+public val COMPILER_SERVICE_RMI_NAME: String = ""KotlinJvmCompilerService"" -+public val COMPILER_DAEMON_CLASS_FQN: String = ""org.jetbrains.kotlin.rmi.service.CompileDaemon"" -+public val COMPILE_DAEMON_DEFAULT_PORT: Int = 17031 -+public val COMPILE_DAEMON_ENABLED_PROPERTY: String =""kotlin.daemon.enabled"" -+public val COMPILE_DAEMON_JVM_OPTIONS_PROPERTY: String =""kotlin.daemon.jvm.options"" -+public val COMPILE_DAEMON_OPTIONS_PROPERTY: String =""kotlin.daemon.options"" -+public val COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX: String =""--daemon-"" -+ -+ -+open class PropExtractor>(val dest: C, -+ val prop: P, -+ val name: String, -+ val convert: ((v: V) -> String?) = { it.toString() }, -+ val skipIf: ((v: V) -> Boolean) = { false }, -+ val mergeWithDelimiter: String? = null) -+{ -+ constructor(dest: C, prop: P, convert: ((v: V) -> String?) = { it.toString() }, skipIf: ((v: V) -> Boolean) = { false }) : this(dest, prop, prop.name, convert, skipIf) -+ open fun extract(prefix: String = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX): List = -+ when { -+ skipIf(prop.get(dest)) -> listOf() -+ mergeWithDelimiter != null -> listOf(prefix + name + mergeWithDelimiter + convert(prop.get(dest))).filterNotNull() -+ else -> listOf(prefix + name, convert(prop.get(dest))).filterNotNull() -+ } -+} -+ -+class BoolPropExtractor>(dest: C, prop: P, name: String? = null) -+ : PropExtractor(dest, prop, name ?: prop.name, convert = { null }, skipIf = { !prop.get(dest) }) -+ -+class RestPropExtractor>>(dest: C, prop: P) : PropExtractor, P>(dest, prop, convert = { null }) { -+ override fun extract(prefix: String): List = prop.get(dest).map { prefix + it } -+} -+ -+ -+open class PropParser>(val dest: C, -+ val prop: P, alternativeNames: List, -+ val parse: (s: String) -> V, -+ val allowMergedArg: Boolean = false) { -+ val names = listOf(prop.name) + alternativeNames -+ constructor(dest: C, prop: P, parse: (s: String) -> V, allowMergedArg: Boolean = false) : this(dest, prop, listOf(), parse, allowMergedArg) -+ fun apply(s: String) = prop.set(dest, parse(s)) -+} -+ -+class BoolPropParser>(dest: C, prop: P): PropParser(dest, prop, { true }) -+ -+class RestPropParser>>(dest: C, prop: P): PropParser, P>(dest, prop, { arrayListOf() }) { -+ fun add(s: String) { prop.get(dest).add(s) } -+} -+ -+ -+fun Iterable.filterSetProps(parsers: List>, prefix: String, restParser: RestPropParser<*,*>? = null) : Iterable { -+ var currentParser: PropParser<*,*,*>? = null -+ var matchingOption = """" -+ val res = filter { param -> -+ if (currentParser == null) { -+ val parser = parsers.find { it.names.any { name -> -+ if (param.startsWith(prefix + name)) { matchingOption = prefix + name; true } -+ else false } } -+ if (parser != null) { -+ val optionLength = matchingOption.length() -+ when { -+ parser is BoolPropParser<*,*> -> -+ if (param.length() > optionLength) throw IllegalArgumentException(""Invalid switch option '$param', expecting $matchingOption without arguments"") -+ else parser.apply("""") -+ param.length() > optionLength -> -+ if (param[optionLength] != '=') { -+ if (parser.allowMergedArg) parser.apply(param.substring(optionLength)) -+ else throw IllegalArgumentException(""Invalid option syntax '$param', expecting $matchingOption[= ]"") -+ } -+ else parser.apply(param.substring(optionLength + 1)) -+ else -> currentParser = parser -+ } -+ false -+ } -+ else if (restParser != null && param.startsWith(prefix)) { -+ restParser.add(param.removePrefix(prefix)) -+ false -+ } -+ else true -+ } -+ else { -+ currentParser!!.apply(param) -+ currentParser = null -+ false -+ } -+ } -+ if (currentParser != null) throw IllegalArgumentException(""Expecting argument for the option $matchingOption"") -+ return res -+} -+ -+// TODO: find out how to create more generic variant using first constructor -+//fun C.propsToParams() { -+// val kc = C::class -+// kc.constructors.first(). -+//} -+ -+ -+ -+public interface CmdlineParams : Serializable {","minor: I don't like `Cmdline` -",Maybe use a different nam -216,"@@ -0,0 +1,272 @@ -+/* -+ * 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.rmi -+ -+import java.io.File -+import java.io.Serializable -+import java.lang.management.ManagementFactory -+import java.security.DigestInputStream -+import java.security.MessageDigest -+import kotlin.platform.platformStatic -+import kotlin.reflect.KMutableProperty1 -+import kotlin.reflect.KProperty1 -+ -+ -+public val COMPILER_JAR_NAME: String = ""kotlin-compiler.jar"" -+public val COMPILER_SERVICE_RMI_NAME: String = ""KotlinJvmCompilerService"" -+public val COMPILER_DAEMON_CLASS_FQN: String = ""org.jetbrains.kotlin.rmi.service.CompileDaemon"" -+public val COMPILE_DAEMON_DEFAULT_PORT: Int = 17031 -+public val COMPILE_DAEMON_ENABLED_PROPERTY: String =""kotlin.daemon.enabled"" -+public val COMPILE_DAEMON_JVM_OPTIONS_PROPERTY: String =""kotlin.daemon.jvm.options"" -+public val COMPILE_DAEMON_OPTIONS_PROPERTY: String =""kotlin.daemon.options"" -+public val COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX: String =""--daemon-"" -+ -+ -+open class PropExtractor>(val dest: C, -+ val prop: P, -+ val name: String, -+ val convert: ((v: V) -> String?) = { it.toString() }, -+ val skipIf: ((v: V) -> Boolean) = { false }, -+ val mergeWithDelimiter: String? = null) -+{ -+ constructor(dest: C, prop: P, convert: ((v: V) -> String?) = { it.toString() }, skipIf: ((v: V) -> Boolean) = { false }) : this(dest, prop, prop.name, convert, skipIf) -+ open fun extract(prefix: String = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX): List = -+ when { -+ skipIf(prop.get(dest)) -> listOf() -+ mergeWithDelimiter != null -> listOf(prefix + name + mergeWithDelimiter + convert(prop.get(dest))).filterNotNull() -+ else -> listOf(prefix + name, convert(prop.get(dest))).filterNotNull() -+ } -+} -+ -+class BoolPropExtractor>(dest: C, prop: P, name: String? = null) -+ : PropExtractor(dest, prop, name ?: prop.name, convert = { null }, skipIf = { !prop.get(dest) }) -+ -+class RestPropExtractor>>(dest: C, prop: P) : PropExtractor, P>(dest, prop, convert = { null }) { -+ override fun extract(prefix: String): List = prop.get(dest).map { prefix + it } -+} -+ -+ -+open class PropParser>(val dest: C, -+ val prop: P, alternativeNames: List, -+ val parse: (s: String) -> V, -+ val allowMergedArg: Boolean = false) { -+ val names = listOf(prop.name) + alternativeNames -+ constructor(dest: C, prop: P, parse: (s: String) -> V, allowMergedArg: Boolean = false) : this(dest, prop, listOf(), parse, allowMergedArg) -+ fun apply(s: String) = prop.set(dest, parse(s)) -+} -+ -+class BoolPropParser>(dest: C, prop: P): PropParser(dest, prop, { true }) -+ -+class RestPropParser>>(dest: C, prop: P): PropParser, P>(dest, prop, { arrayListOf() }) { -+ fun add(s: String) { prop.get(dest).add(s) } -+} -+ -+ -+fun Iterable.filterSetProps(parsers: List>, prefix: String, restParser: RestPropParser<*,*>? = null) : Iterable { -+ var currentParser: PropParser<*,*,*>? = null -+ var matchingOption = """" -+ val res = filter { param -> -+ if (currentParser == null) { -+ val parser = parsers.find { it.names.any { name -> -+ if (param.startsWith(prefix + name)) { matchingOption = prefix + name; true } -+ else false } } -+ if (parser != null) { -+ val optionLength = matchingOption.length() -+ when { -+ parser is BoolPropParser<*,*> -> -+ if (param.length() > optionLength) throw IllegalArgumentException(""Invalid switch option '$param', expecting $matchingOption without arguments"") -+ else parser.apply("""") -+ param.length() > optionLength -> -+ if (param[optionLength] != '=') { -+ if (parser.allowMergedArg) parser.apply(param.substring(optionLength)) -+ else throw IllegalArgumentException(""Invalid option syntax '$param', expecting $matchingOption[= ]"") -+ } -+ else parser.apply(param.substring(optionLength + 1)) -+ else -> currentParser = parser -+ } -+ false -+ } -+ else if (restParser != null && param.startsWith(prefix)) { -+ restParser.add(param.removePrefix(prefix)) -+ false -+ } -+ else true -+ } -+ else { -+ currentParser!!.apply(param) -+ currentParser = null -+ false -+ } -+ } -+ if (currentParser != null) throw IllegalArgumentException(""Expecting argument for the option $matchingOption"") -+ return res -+} -+ -+// TODO: find out how to create more generic variant using first constructor -+//fun C.propsToParams() { -+// val kc = C::class -+// kc.constructors.first(). -+//} -+ -+ -+ -+public interface CmdlineParams : Serializable { -+ public val extractors: List>","I think these properties should not be part of public api -",Maybe use a different nam -217,"@@ -0,0 +1,272 @@ -+/* -+ * 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.rmi -+ -+import java.io.File -+import java.io.Serializable -+import java.lang.management.ManagementFactory -+import java.security.DigestInputStream -+import java.security.MessageDigest -+import kotlin.platform.platformStatic -+import kotlin.reflect.KMutableProperty1 -+import kotlin.reflect.KProperty1 -+ -+ -+public val COMPILER_JAR_NAME: String = ""kotlin-compiler.jar"" -+public val COMPILER_SERVICE_RMI_NAME: String = ""KotlinJvmCompilerService"" -+public val COMPILER_DAEMON_CLASS_FQN: String = ""org.jetbrains.kotlin.rmi.service.CompileDaemon"" -+public val COMPILE_DAEMON_DEFAULT_PORT: Int = 17031 -+public val COMPILE_DAEMON_ENABLED_PROPERTY: String =""kotlin.daemon.enabled"" -+public val COMPILE_DAEMON_JVM_OPTIONS_PROPERTY: String =""kotlin.daemon.jvm.options"" -+public val COMPILE_DAEMON_OPTIONS_PROPERTY: String =""kotlin.daemon.options"" -+public val COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX: String =""--daemon-"" -+ -+ -+open class PropExtractor>(val dest: C, -+ val prop: P, -+ val name: String, -+ val convert: ((v: V) -> String?) = { it.toString() }, -+ val skipIf: ((v: V) -> Boolean) = { false }, -+ val mergeWithDelimiter: String? = null) -+{ -+ constructor(dest: C, prop: P, convert: ((v: V) -> String?) = { it.toString() }, skipIf: ((v: V) -> Boolean) = { false }) : this(dest, prop, prop.name, convert, skipIf) -+ open fun extract(prefix: String = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX): List = -+ when { -+ skipIf(prop.get(dest)) -> listOf() -+ mergeWithDelimiter != null -> listOf(prefix + name + mergeWithDelimiter + convert(prop.get(dest))).filterNotNull() -+ else -> listOf(prefix + name, convert(prop.get(dest))).filterNotNull() -+ } -+} -+ -+class BoolPropExtractor>(dest: C, prop: P, name: String? = null) -+ : PropExtractor(dest, prop, name ?: prop.name, convert = { null }, skipIf = { !prop.get(dest) }) -+ -+class RestPropExtractor>>(dest: C, prop: P) : PropExtractor, P>(dest, prop, convert = { null }) { -+ override fun extract(prefix: String): List = prop.get(dest).map { prefix + it } -+} -+ -+ -+open class PropParser>(val dest: C, -+ val prop: P, alternativeNames: List, -+ val parse: (s: String) -> V, -+ val allowMergedArg: Boolean = false) { -+ val names = listOf(prop.name) + alternativeNames -+ constructor(dest: C, prop: P, parse: (s: String) -> V, allowMergedArg: Boolean = false) : this(dest, prop, listOf(), parse, allowMergedArg) -+ fun apply(s: String) = prop.set(dest, parse(s)) -+} -+ -+class BoolPropParser>(dest: C, prop: P): PropParser(dest, prop, { true }) -+ -+class RestPropParser>>(dest: C, prop: P): PropParser, P>(dest, prop, { arrayListOf() }) { -+ fun add(s: String) { prop.get(dest).add(s) } -+} -+ -+ -+fun Iterable.filterSetProps(parsers: List>, prefix: String, restParser: RestPropParser<*,*>? = null) : Iterable { -+ var currentParser: PropParser<*,*,*>? = null -+ var matchingOption = """" -+ val res = filter { param -> -+ if (currentParser == null) { -+ val parser = parsers.find { it.names.any { name -> -+ if (param.startsWith(prefix + name)) { matchingOption = prefix + name; true } -+ else false } } -+ if (parser != null) { -+ val optionLength = matchingOption.length() -+ when { -+ parser is BoolPropParser<*,*> -> -+ if (param.length() > optionLength) throw IllegalArgumentException(""Invalid switch option '$param', expecting $matchingOption without arguments"") -+ else parser.apply("""") -+ param.length() > optionLength -> -+ if (param[optionLength] != '=') { -+ if (parser.allowMergedArg) parser.apply(param.substring(optionLength)) -+ else throw IllegalArgumentException(""Invalid option syntax '$param', expecting $matchingOption[= ]"") -+ } -+ else parser.apply(param.substring(optionLength + 1)) -+ else -> currentParser = parser -+ } -+ false -+ } -+ else if (restParser != null && param.startsWith(prefix)) { -+ restParser.add(param.removePrefix(prefix)) -+ false -+ } -+ else true -+ } -+ else { -+ currentParser!!.apply(param) -+ currentParser = null -+ false -+ } -+ } -+ if (currentParser != null) throw IllegalArgumentException(""Expecting argument for the option $matchingOption"") -+ return res -+} -+ -+// TODO: find out how to create more generic variant using first constructor -+//fun C.propsToParams() { -+// val kc = C::class -+// kc.constructors.first(). -+//} -+ -+ -+ -+public interface CmdlineParams : Serializable { -+ public val extractors: List> -+ public val parsers: List> -+} -+ -+public fun Iterable.filterSetProps(vararg cs: CmdlineParams, prefix: String) : Iterable =","what is cs? -",Maybe use a different nam -218,"@@ -0,0 +1,272 @@ -+/* -+ * 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.rmi -+ -+import java.io.File -+import java.io.Serializable -+import java.lang.management.ManagementFactory -+import java.security.DigestInputStream -+import java.security.MessageDigest -+import kotlin.platform.platformStatic -+import kotlin.reflect.KMutableProperty1 -+import kotlin.reflect.KProperty1 -+ -+ -+public val COMPILER_JAR_NAME: String = ""kotlin-compiler.jar"" -+public val COMPILER_SERVICE_RMI_NAME: String = ""KotlinJvmCompilerService"" -+public val COMPILER_DAEMON_CLASS_FQN: String = ""org.jetbrains.kotlin.rmi.service.CompileDaemon"" -+public val COMPILE_DAEMON_DEFAULT_PORT: Int = 17031 -+public val COMPILE_DAEMON_ENABLED_PROPERTY: String =""kotlin.daemon.enabled"" -+public val COMPILE_DAEMON_JVM_OPTIONS_PROPERTY: String =""kotlin.daemon.jvm.options"" -+public val COMPILE_DAEMON_OPTIONS_PROPERTY: String =""kotlin.daemon.options"" -+public val COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX: String =""--daemon-"" -+ -+ -+open class PropExtractor>(val dest: C, -+ val prop: P, -+ val name: String, -+ val convert: ((v: V) -> String?) = { it.toString() }, -+ val skipIf: ((v: V) -> Boolean) = { false }, -+ val mergeWithDelimiter: String? = null) -+{ -+ constructor(dest: C, prop: P, convert: ((v: V) -> String?) = { it.toString() }, skipIf: ((v: V) -> Boolean) = { false }) : this(dest, prop, prop.name, convert, skipIf) -+ open fun extract(prefix: String = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX): List = -+ when { -+ skipIf(prop.get(dest)) -> listOf() -+ mergeWithDelimiter != null -> listOf(prefix + name + mergeWithDelimiter + convert(prop.get(dest))).filterNotNull() -+ else -> listOf(prefix + name, convert(prop.get(dest))).filterNotNull() -+ } -+} -+ -+class BoolPropExtractor>(dest: C, prop: P, name: String? = null) -+ : PropExtractor(dest, prop, name ?: prop.name, convert = { null }, skipIf = { !prop.get(dest) }) -+ -+class RestPropExtractor>>(dest: C, prop: P) : PropExtractor, P>(dest, prop, convert = { null }) { -+ override fun extract(prefix: String): List = prop.get(dest).map { prefix + it } -+} -+ -+ -+open class PropParser>(val dest: C, -+ val prop: P, alternativeNames: List, -+ val parse: (s: String) -> V, -+ val allowMergedArg: Boolean = false) { -+ val names = listOf(prop.name) + alternativeNames -+ constructor(dest: C, prop: P, parse: (s: String) -> V, allowMergedArg: Boolean = false) : this(dest, prop, listOf(), parse, allowMergedArg) -+ fun apply(s: String) = prop.set(dest, parse(s)) -+} -+ -+class BoolPropParser>(dest: C, prop: P): PropParser(dest, prop, { true }) -+ -+class RestPropParser>>(dest: C, prop: P): PropParser, P>(dest, prop, { arrayListOf() }) { -+ fun add(s: String) { prop.get(dest).add(s) } -+} -+ -+ -+fun Iterable.filterSetProps(parsers: List>, prefix: String, restParser: RestPropParser<*,*>? = null) : Iterable { -+ var currentParser: PropParser<*,*,*>? = null -+ var matchingOption = """" -+ val res = filter { param -> -+ if (currentParser == null) { -+ val parser = parsers.find { it.names.any { name -> -+ if (param.startsWith(prefix + name)) { matchingOption = prefix + name; true } -+ else false } } -+ if (parser != null) { -+ val optionLength = matchingOption.length() -+ when { -+ parser is BoolPropParser<*,*> -> -+ if (param.length() > optionLength) throw IllegalArgumentException(""Invalid switch option '$param', expecting $matchingOption without arguments"") -+ else parser.apply("""") -+ param.length() > optionLength -> -+ if (param[optionLength] != '=') { -+ if (parser.allowMergedArg) parser.apply(param.substring(optionLength)) -+ else throw IllegalArgumentException(""Invalid option syntax '$param', expecting $matchingOption[= ]"") -+ } -+ else parser.apply(param.substring(optionLength + 1)) -+ else -> currentParser = parser -+ } -+ false -+ } -+ else if (restParser != null && param.startsWith(prefix)) { -+ restParser.add(param.removePrefix(prefix)) -+ false -+ } -+ else true -+ } -+ else { -+ currentParser!!.apply(param) -+ currentParser = null -+ false -+ } -+ } -+ if (currentParser != null) throw IllegalArgumentException(""Expecting argument for the option $matchingOption"") -+ return res -+} -+ -+// TODO: find out how to create more generic variant using first constructor -+//fun C.propsToParams() { -+// val kc = C::class -+// kc.constructors.first(). -+//} -+ -+ -+ -+public interface CmdlineParams : Serializable { -+ public val extractors: List> -+ public val parsers: List> -+} -+ -+public fun Iterable.filterSetProps(vararg cs: CmdlineParams, prefix: String) : Iterable = -+ filterSetProps(cs.flatMap { it.parsers }, prefix) -+ -+ -+public data class DaemonLaunchingOptions( -+ public var maxMemory: String = """",","I don't like public vars and public constructor in inheritors of CmdlineParams -",Maybe use a different nam -219,"@@ -0,0 +1,272 @@ -+/* -+ * 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.rmi -+ -+import java.io.File -+import java.io.Serializable -+import java.lang.management.ManagementFactory -+import java.security.DigestInputStream -+import java.security.MessageDigest -+import kotlin.platform.platformStatic -+import kotlin.reflect.KMutableProperty1 -+import kotlin.reflect.KProperty1 -+ -+ -+public val COMPILER_JAR_NAME: String = ""kotlin-compiler.jar"" -+public val COMPILER_SERVICE_RMI_NAME: String = ""KotlinJvmCompilerService"" -+public val COMPILER_DAEMON_CLASS_FQN: String = ""org.jetbrains.kotlin.rmi.service.CompileDaemon"" -+public val COMPILE_DAEMON_DEFAULT_PORT: Int = 17031 -+public val COMPILE_DAEMON_ENABLED_PROPERTY: String =""kotlin.daemon.enabled"" -+public val COMPILE_DAEMON_JVM_OPTIONS_PROPERTY: String =""kotlin.daemon.jvm.options"" -+public val COMPILE_DAEMON_OPTIONS_PROPERTY: String =""kotlin.daemon.options"" -+public val COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX: String =""--daemon-"" -+ -+ -+open class PropExtractor>(val dest: C, -+ val prop: P, -+ val name: String, -+ val convert: ((v: V) -> String?) = { it.toString() }, -+ val skipIf: ((v: V) -> Boolean) = { false }, -+ val mergeWithDelimiter: String? = null) -+{ -+ constructor(dest: C, prop: P, convert: ((v: V) -> String?) = { it.toString() }, skipIf: ((v: V) -> Boolean) = { false }) : this(dest, prop, prop.name, convert, skipIf) -+ open fun extract(prefix: String = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX): List = -+ when { -+ skipIf(prop.get(dest)) -> listOf() -+ mergeWithDelimiter != null -> listOf(prefix + name + mergeWithDelimiter + convert(prop.get(dest))).filterNotNull() -+ else -> listOf(prefix + name, convert(prop.get(dest))).filterNotNull() -+ } -+} -+ -+class BoolPropExtractor>(dest: C, prop: P, name: String? = null) -+ : PropExtractor(dest, prop, name ?: prop.name, convert = { null }, skipIf = { !prop.get(dest) }) -+ -+class RestPropExtractor>>(dest: C, prop: P) : PropExtractor, P>(dest, prop, convert = { null }) { -+ override fun extract(prefix: String): List = prop.get(dest).map { prefix + it } -+} -+ -+ -+open class PropParser>(val dest: C, -+ val prop: P, alternativeNames: List, -+ val parse: (s: String) -> V, -+ val allowMergedArg: Boolean = false) { -+ val names = listOf(prop.name) + alternativeNames -+ constructor(dest: C, prop: P, parse: (s: String) -> V, allowMergedArg: Boolean = false) : this(dest, prop, listOf(), parse, allowMergedArg) -+ fun apply(s: String) = prop.set(dest, parse(s)) -+} -+ -+class BoolPropParser>(dest: C, prop: P): PropParser(dest, prop, { true }) -+ -+class RestPropParser>>(dest: C, prop: P): PropParser, P>(dest, prop, { arrayListOf() }) { -+ fun add(s: String) { prop.get(dest).add(s) } -+} -+ -+ -+fun Iterable.filterSetProps(parsers: List>, prefix: String, restParser: RestPropParser<*,*>? = null) : Iterable { -+ var currentParser: PropParser<*,*,*>? = null -+ var matchingOption = """" -+ val res = filter { param -> -+ if (currentParser == null) { -+ val parser = parsers.find { it.names.any { name -> -+ if (param.startsWith(prefix + name)) { matchingOption = prefix + name; true } -+ else false } } -+ if (parser != null) { -+ val optionLength = matchingOption.length() -+ when { -+ parser is BoolPropParser<*,*> -> -+ if (param.length() > optionLength) throw IllegalArgumentException(""Invalid switch option '$param', expecting $matchingOption without arguments"") -+ else parser.apply("""") -+ param.length() > optionLength -> -+ if (param[optionLength] != '=') { -+ if (parser.allowMergedArg) parser.apply(param.substring(optionLength)) -+ else throw IllegalArgumentException(""Invalid option syntax '$param', expecting $matchingOption[= ]"") -+ } -+ else parser.apply(param.substring(optionLength + 1)) -+ else -> currentParser = parser -+ } -+ false -+ } -+ else if (restParser != null && param.startsWith(prefix)) { -+ restParser.add(param.removePrefix(prefix)) -+ false -+ } -+ else true -+ } -+ else { -+ currentParser!!.apply(param) -+ currentParser = null -+ false -+ } -+ } -+ if (currentParser != null) throw IllegalArgumentException(""Expecting argument for the option $matchingOption"") -+ return res -+} -+ -+// TODO: find out how to create more generic variant using first constructor -+//fun C.propsToParams() { -+// val kc = C::class -+// kc.constructors.first(). -+//} -+ -+ -+ -+public interface CmdlineParams : Serializable { -+ public val extractors: List> -+ public val parsers: List> -+} -+ -+public fun Iterable.filterSetProps(vararg cs: CmdlineParams, prefix: String) : Iterable = -+ filterSetProps(cs.flatMap { it.parsers }, prefix) -+ -+ -+public data class DaemonLaunchingOptions( -+ public var maxMemory: String = """", -+ public var maxPermSize: String = """", -+ public var reservedCodeCacheSize: String = """", -+ public var otherJvmParams: MutableCollection = arrayListOf() -+) : CmdlineParams { -+ -+ override val extractors: List> -+ get() = listOf( PropExtractor(this, ::maxMemory, ""Xmx"", skipIf = { it.isEmpty() }, mergeWithDelimiter = """"),","I'd extract `{ it.isEmpty() }` to constant -",Maybe use a different nam -220,"@@ -0,0 +1,272 @@ -+/* -+ * 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.rmi -+ -+import java.io.File -+import java.io.Serializable -+import java.lang.management.ManagementFactory -+import java.security.DigestInputStream -+import java.security.MessageDigest -+import kotlin.platform.platformStatic -+import kotlin.reflect.KMutableProperty1 -+import kotlin.reflect.KProperty1 -+ -+ -+public val COMPILER_JAR_NAME: String = ""kotlin-compiler.jar"" -+public val COMPILER_SERVICE_RMI_NAME: String = ""KotlinJvmCompilerService"" -+public val COMPILER_DAEMON_CLASS_FQN: String = ""org.jetbrains.kotlin.rmi.service.CompileDaemon"" -+public val COMPILE_DAEMON_DEFAULT_PORT: Int = 17031 -+public val COMPILE_DAEMON_ENABLED_PROPERTY: String =""kotlin.daemon.enabled"" -+public val COMPILE_DAEMON_JVM_OPTIONS_PROPERTY: String =""kotlin.daemon.jvm.options"" -+public val COMPILE_DAEMON_OPTIONS_PROPERTY: String =""kotlin.daemon.options"" -+public val COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX: String =""--daemon-"" -+ -+ -+open class PropExtractor>(val dest: C, -+ val prop: P, -+ val name: String, -+ val convert: ((v: V) -> String?) = { it.toString() }, -+ val skipIf: ((v: V) -> Boolean) = { false }, -+ val mergeWithDelimiter: String? = null) -+{ -+ constructor(dest: C, prop: P, convert: ((v: V) -> String?) = { it.toString() }, skipIf: ((v: V) -> Boolean) = { false }) : this(dest, prop, prop.name, convert, skipIf) -+ open fun extract(prefix: String = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX): List = -+ when { -+ skipIf(prop.get(dest)) -> listOf() -+ mergeWithDelimiter != null -> listOf(prefix + name + mergeWithDelimiter + convert(prop.get(dest))).filterNotNull() -+ else -> listOf(prefix + name, convert(prop.get(dest))).filterNotNull() -+ } -+} -+ -+class BoolPropExtractor>(dest: C, prop: P, name: String? = null) -+ : PropExtractor(dest, prop, name ?: prop.name, convert = { null }, skipIf = { !prop.get(dest) }) -+ -+class RestPropExtractor>>(dest: C, prop: P) : PropExtractor, P>(dest, prop, convert = { null }) { -+ override fun extract(prefix: String): List = prop.get(dest).map { prefix + it } -+} -+ -+ -+open class PropParser>(val dest: C, -+ val prop: P, alternativeNames: List, -+ val parse: (s: String) -> V, -+ val allowMergedArg: Boolean = false) { -+ val names = listOf(prop.name) + alternativeNames -+ constructor(dest: C, prop: P, parse: (s: String) -> V, allowMergedArg: Boolean = false) : this(dest, prop, listOf(), parse, allowMergedArg) -+ fun apply(s: String) = prop.set(dest, parse(s)) -+} -+ -+class BoolPropParser>(dest: C, prop: P): PropParser(dest, prop, { true }) -+ -+class RestPropParser>>(dest: C, prop: P): PropParser, P>(dest, prop, { arrayListOf() }) { -+ fun add(s: String) { prop.get(dest).add(s) } -+} -+ -+ -+fun Iterable.filterSetProps(parsers: List>, prefix: String, restParser: RestPropParser<*,*>? = null) : Iterable { -+ var currentParser: PropParser<*,*,*>? = null -+ var matchingOption = """" -+ val res = filter { param -> -+ if (currentParser == null) { -+ val parser = parsers.find { it.names.any { name -> -+ if (param.startsWith(prefix + name)) { matchingOption = prefix + name; true } -+ else false } } -+ if (parser != null) { -+ val optionLength = matchingOption.length() -+ when { -+ parser is BoolPropParser<*,*> -> -+ if (param.length() > optionLength) throw IllegalArgumentException(""Invalid switch option '$param', expecting $matchingOption without arguments"") -+ else parser.apply("""") -+ param.length() > optionLength -> -+ if (param[optionLength] != '=') { -+ if (parser.allowMergedArg) parser.apply(param.substring(optionLength)) -+ else throw IllegalArgumentException(""Invalid option syntax '$param', expecting $matchingOption[= ]"") -+ } -+ else parser.apply(param.substring(optionLength + 1)) -+ else -> currentParser = parser -+ } -+ false -+ } -+ else if (restParser != null && param.startsWith(prefix)) { -+ restParser.add(param.removePrefix(prefix)) -+ false -+ } -+ else true -+ } -+ else { -+ currentParser!!.apply(param) -+ currentParser = null -+ false -+ } -+ } -+ if (currentParser != null) throw IllegalArgumentException(""Expecting argument for the option $matchingOption"") -+ return res -+} -+ -+// TODO: find out how to create more generic variant using first constructor -+//fun C.propsToParams() { -+// val kc = C::class -+// kc.constructors.first(). -+//} -+ -+ -+ -+public interface CmdlineParams : Serializable { -+ public val extractors: List> -+ public val parsers: List> -+} -+ -+public fun Iterable.filterSetProps(vararg cs: CmdlineParams, prefix: String) : Iterable = -+ filterSetProps(cs.flatMap { it.parsers }, prefix) -+ -+ -+public data class DaemonLaunchingOptions( -+ public var maxMemory: String = """", -+ public var maxPermSize: String = """", -+ public var reservedCodeCacheSize: String = """", -+ public var otherJvmParams: MutableCollection = arrayListOf() -+) : CmdlineParams { -+ -+ override val extractors: List> -+ get() = listOf( PropExtractor(this, ::maxMemory, ""Xmx"", skipIf = { it.isEmpty() }, mergeWithDelimiter = """"), -+ PropExtractor(this, ::maxPermSize, ""XX:MaxPermSize"", skipIf = { it.isEmpty() }, mergeWithDelimiter = ""=""), -+ PropExtractor(this, ::reservedCodeCacheSize, ""XX:ReservedCodeCacheSize"", skipIf = { it.isEmpty() }, mergeWithDelimiter = ""=""), -+ RestPropExtractor(this, ::otherJvmParams)) -+ -+ override val parsers: List> -+ get() = listOf( PropParser(this, ::maxMemory, listOf(""Xmx""), { it }, allowMergedArg = true),","i'd extract `{ it }` or use `identity()` from `core/util.runtime/src/org/jetbrains/kotlin/utils/functions.kt` -",Maybe use a different nam -221,"@@ -0,0 +1,272 @@ -+/* -+ * 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.rmi -+ -+import java.io.File -+import java.io.Serializable -+import java.lang.management.ManagementFactory -+import java.security.DigestInputStream -+import java.security.MessageDigest -+import kotlin.platform.platformStatic -+import kotlin.reflect.KMutableProperty1 -+import kotlin.reflect.KProperty1 -+ -+ -+public val COMPILER_JAR_NAME: String = ""kotlin-compiler.jar"" -+public val COMPILER_SERVICE_RMI_NAME: String = ""KotlinJvmCompilerService"" -+public val COMPILER_DAEMON_CLASS_FQN: String = ""org.jetbrains.kotlin.rmi.service.CompileDaemon"" -+public val COMPILE_DAEMON_DEFAULT_PORT: Int = 17031 -+public val COMPILE_DAEMON_ENABLED_PROPERTY: String =""kotlin.daemon.enabled"" -+public val COMPILE_DAEMON_JVM_OPTIONS_PROPERTY: String =""kotlin.daemon.jvm.options"" -+public val COMPILE_DAEMON_OPTIONS_PROPERTY: String =""kotlin.daemon.options"" -+public val COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX: String =""--daemon-"" -+ -+ -+open class PropExtractor>(val dest: C, -+ val prop: P, -+ val name: String, -+ val convert: ((v: V) -> String?) = { it.toString() }, -+ val skipIf: ((v: V) -> Boolean) = { false }, -+ val mergeWithDelimiter: String? = null) -+{ -+ constructor(dest: C, prop: P, convert: ((v: V) -> String?) = { it.toString() }, skipIf: ((v: V) -> Boolean) = { false }) : this(dest, prop, prop.name, convert, skipIf) -+ open fun extract(prefix: String = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX): List = -+ when { -+ skipIf(prop.get(dest)) -> listOf() -+ mergeWithDelimiter != null -> listOf(prefix + name + mergeWithDelimiter + convert(prop.get(dest))).filterNotNull() -+ else -> listOf(prefix + name, convert(prop.get(dest))).filterNotNull() -+ } -+} -+ -+class BoolPropExtractor>(dest: C, prop: P, name: String? = null) -+ : PropExtractor(dest, prop, name ?: prop.name, convert = { null }, skipIf = { !prop.get(dest) }) -+ -+class RestPropExtractor>>(dest: C, prop: P) : PropExtractor, P>(dest, prop, convert = { null }) { -+ override fun extract(prefix: String): List = prop.get(dest).map { prefix + it } -+} -+ -+ -+open class PropParser>(val dest: C, -+ val prop: P, alternativeNames: List, -+ val parse: (s: String) -> V, -+ val allowMergedArg: Boolean = false) { -+ val names = listOf(prop.name) + alternativeNames -+ constructor(dest: C, prop: P, parse: (s: String) -> V, allowMergedArg: Boolean = false) : this(dest, prop, listOf(), parse, allowMergedArg) -+ fun apply(s: String) = prop.set(dest, parse(s)) -+} -+ -+class BoolPropParser>(dest: C, prop: P): PropParser(dest, prop, { true }) -+ -+class RestPropParser>>(dest: C, prop: P): PropParser, P>(dest, prop, { arrayListOf() }) { -+ fun add(s: String) { prop.get(dest).add(s) } -+} -+ -+ -+fun Iterable.filterSetProps(parsers: List>, prefix: String, restParser: RestPropParser<*,*>? = null) : Iterable { -+ var currentParser: PropParser<*,*,*>? = null -+ var matchingOption = """" -+ val res = filter { param -> -+ if (currentParser == null) { -+ val parser = parsers.find { it.names.any { name -> -+ if (param.startsWith(prefix + name)) { matchingOption = prefix + name; true } -+ else false } } -+ if (parser != null) { -+ val optionLength = matchingOption.length() -+ when { -+ parser is BoolPropParser<*,*> -> -+ if (param.length() > optionLength) throw IllegalArgumentException(""Invalid switch option '$param', expecting $matchingOption without arguments"") -+ else parser.apply("""") -+ param.length() > optionLength -> -+ if (param[optionLength] != '=') { -+ if (parser.allowMergedArg) parser.apply(param.substring(optionLength)) -+ else throw IllegalArgumentException(""Invalid option syntax '$param', expecting $matchingOption[= ]"") -+ } -+ else parser.apply(param.substring(optionLength + 1)) -+ else -> currentParser = parser -+ } -+ false -+ } -+ else if (restParser != null && param.startsWith(prefix)) { -+ restParser.add(param.removePrefix(prefix)) -+ false -+ } -+ else true -+ } -+ else { -+ currentParser!!.apply(param) -+ currentParser = null -+ false -+ } -+ } -+ if (currentParser != null) throw IllegalArgumentException(""Expecting argument for the option $matchingOption"") -+ return res -+} -+ -+// TODO: find out how to create more generic variant using first constructor -+//fun C.propsToParams() { -+// val kc = C::class -+// kc.constructors.first(). -+//} -+ -+ -+ -+public interface CmdlineParams : Serializable { -+ public val extractors: List> -+ public val parsers: List> -+} -+ -+public fun Iterable.filterSetProps(vararg cs: CmdlineParams, prefix: String) : Iterable = -+ filterSetProps(cs.flatMap { it.parsers }, prefix) -+ -+ -+public data class DaemonLaunchingOptions( -+ public var maxMemory: String = """", -+ public var maxPermSize: String = """", -+ public var reservedCodeCacheSize: String = """", -+ public var otherJvmParams: MutableCollection = arrayListOf() -+) : CmdlineParams { -+ -+ override val extractors: List> -+ get() = listOf( PropExtractor(this, ::maxMemory, ""Xmx"", skipIf = { it.isEmpty() }, mergeWithDelimiter = """"), -+ PropExtractor(this, ::maxPermSize, ""XX:MaxPermSize"", skipIf = { it.isEmpty() }, mergeWithDelimiter = ""=""), -+ PropExtractor(this, ::reservedCodeCacheSize, ""XX:ReservedCodeCacheSize"", skipIf = { it.isEmpty() }, mergeWithDelimiter = ""=""), -+ RestPropExtractor(this, ::otherJvmParams)) -+ -+ override val parsers: List> -+ get() = listOf( PropParser(this, ::maxMemory, listOf(""Xmx""), { it }, allowMergedArg = true), -+ PropParser(this, ::maxPermSize, listOf(""XX:MaxPermSize""), { it }, allowMergedArg = true),","Should `allowMergedArg` be false here? -",Maybe use a different nam -222,"@@ -0,0 +1,272 @@ -+/* -+ * 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.rmi -+ -+import java.io.File -+import java.io.Serializable -+import java.lang.management.ManagementFactory -+import java.security.DigestInputStream -+import java.security.MessageDigest -+import kotlin.platform.platformStatic -+import kotlin.reflect.KMutableProperty1 -+import kotlin.reflect.KProperty1 -+ -+ -+public val COMPILER_JAR_NAME: String = ""kotlin-compiler.jar"" -+public val COMPILER_SERVICE_RMI_NAME: String = ""KotlinJvmCompilerService"" -+public val COMPILER_DAEMON_CLASS_FQN: String = ""org.jetbrains.kotlin.rmi.service.CompileDaemon"" -+public val COMPILE_DAEMON_DEFAULT_PORT: Int = 17031 -+public val COMPILE_DAEMON_ENABLED_PROPERTY: String =""kotlin.daemon.enabled"" -+public val COMPILE_DAEMON_JVM_OPTIONS_PROPERTY: String =""kotlin.daemon.jvm.options"" -+public val COMPILE_DAEMON_OPTIONS_PROPERTY: String =""kotlin.daemon.options"" -+public val COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX: String =""--daemon-"" -+ -+ -+open class PropExtractor>(val dest: C, -+ val prop: P, -+ val name: String, -+ val convert: ((v: V) -> String?) = { it.toString() }, -+ val skipIf: ((v: V) -> Boolean) = { false }, -+ val mergeWithDelimiter: String? = null) -+{ -+ constructor(dest: C, prop: P, convert: ((v: V) -> String?) = { it.toString() }, skipIf: ((v: V) -> Boolean) = { false }) : this(dest, prop, prop.name, convert, skipIf) -+ open fun extract(prefix: String = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX): List = -+ when { -+ skipIf(prop.get(dest)) -> listOf() -+ mergeWithDelimiter != null -> listOf(prefix + name + mergeWithDelimiter + convert(prop.get(dest))).filterNotNull() -+ else -> listOf(prefix + name, convert(prop.get(dest))).filterNotNull() -+ } -+} -+ -+class BoolPropExtractor>(dest: C, prop: P, name: String? = null) -+ : PropExtractor(dest, prop, name ?: prop.name, convert = { null }, skipIf = { !prop.get(dest) }) -+ -+class RestPropExtractor>>(dest: C, prop: P) : PropExtractor, P>(dest, prop, convert = { null }) { -+ override fun extract(prefix: String): List = prop.get(dest).map { prefix + it } -+} -+ -+ -+open class PropParser>(val dest: C, -+ val prop: P, alternativeNames: List, -+ val parse: (s: String) -> V, -+ val allowMergedArg: Boolean = false) { -+ val names = listOf(prop.name) + alternativeNames -+ constructor(dest: C, prop: P, parse: (s: String) -> V, allowMergedArg: Boolean = false) : this(dest, prop, listOf(), parse, allowMergedArg) -+ fun apply(s: String) = prop.set(dest, parse(s)) -+} -+ -+class BoolPropParser>(dest: C, prop: P): PropParser(dest, prop, { true }) -+ -+class RestPropParser>>(dest: C, prop: P): PropParser, P>(dest, prop, { arrayListOf() }) { -+ fun add(s: String) { prop.get(dest).add(s) } -+} -+ -+ -+fun Iterable.filterSetProps(parsers: List>, prefix: String, restParser: RestPropParser<*,*>? = null) : Iterable { -+ var currentParser: PropParser<*,*,*>? = null -+ var matchingOption = """" -+ val res = filter { param -> -+ if (currentParser == null) { -+ val parser = parsers.find { it.names.any { name -> -+ if (param.startsWith(prefix + name)) { matchingOption = prefix + name; true } -+ else false } } -+ if (parser != null) { -+ val optionLength = matchingOption.length() -+ when { -+ parser is BoolPropParser<*,*> -> -+ if (param.length() > optionLength) throw IllegalArgumentException(""Invalid switch option '$param', expecting $matchingOption without arguments"") -+ else parser.apply("""") -+ param.length() > optionLength -> -+ if (param[optionLength] != '=') { -+ if (parser.allowMergedArg) parser.apply(param.substring(optionLength)) -+ else throw IllegalArgumentException(""Invalid option syntax '$param', expecting $matchingOption[= ]"") -+ } -+ else parser.apply(param.substring(optionLength + 1)) -+ else -> currentParser = parser -+ } -+ false -+ } -+ else if (restParser != null && param.startsWith(prefix)) { -+ restParser.add(param.removePrefix(prefix)) -+ false -+ } -+ else true -+ } -+ else { -+ currentParser!!.apply(param) -+ currentParser = null -+ false -+ } -+ } -+ if (currentParser != null) throw IllegalArgumentException(""Expecting argument for the option $matchingOption"") -+ return res -+} -+ -+// TODO: find out how to create more generic variant using first constructor -+//fun C.propsToParams() { -+// val kc = C::class -+// kc.constructors.first(). -+//} -+ -+ -+ -+public interface CmdlineParams : Serializable { -+ public val extractors: List> -+ public val parsers: List> -+} -+ -+public fun Iterable.filterSetProps(vararg cs: CmdlineParams, prefix: String) : Iterable = -+ filterSetProps(cs.flatMap { it.parsers }, prefix) -+ -+ -+public data class DaemonLaunchingOptions( -+ public var maxMemory: String = """", -+ public var maxPermSize: String = """", -+ public var reservedCodeCacheSize: String = """", -+ public var otherJvmParams: MutableCollection = arrayListOf() -+) : CmdlineParams { -+ -+ override val extractors: List> -+ get() = listOf( PropExtractor(this, ::maxMemory, ""Xmx"", skipIf = { it.isEmpty() }, mergeWithDelimiter = """"), -+ PropExtractor(this, ::maxPermSize, ""XX:MaxPermSize"", skipIf = { it.isEmpty() }, mergeWithDelimiter = ""=""), -+ PropExtractor(this, ::reservedCodeCacheSize, ""XX:ReservedCodeCacheSize"", skipIf = { it.isEmpty() }, mergeWithDelimiter = ""=""), -+ RestPropExtractor(this, ::otherJvmParams)) -+ -+ override val parsers: List> -+ get() = listOf( PropParser(this, ::maxMemory, listOf(""Xmx""), { it }, allowMergedArg = true), -+ PropParser(this, ::maxPermSize, listOf(""XX:MaxPermSize""), { it }, allowMergedArg = true), -+ PropParser(this, ::reservedCodeCacheSize, listOf(""XX:ReservedCodeCacheSize""), { it }, allowMergedArg = true)) -+ // otherJvmParams is missing here deliberately, it is used explicitly as a restParser param to filterSetProps -+} -+ -+public data class DaemonOptions( -+ public var port: Int = COMPILE_DAEMON_DEFAULT_PORT, -+ public var autoshutdownMemoryThreshold: Long = 0 /* 0 means unchecked */,","I'd toggle case of `s` or drop `auto` prefix -",Maybe use a different nam -223,"@@ -0,0 +1,272 @@ -+/* -+ * 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.rmi -+ -+import java.io.File -+import java.io.Serializable -+import java.lang.management.ManagementFactory -+import java.security.DigestInputStream -+import java.security.MessageDigest -+import kotlin.platform.platformStatic -+import kotlin.reflect.KMutableProperty1 -+import kotlin.reflect.KProperty1 -+ -+ -+public val COMPILER_JAR_NAME: String = ""kotlin-compiler.jar"" -+public val COMPILER_SERVICE_RMI_NAME: String = ""KotlinJvmCompilerService"" -+public val COMPILER_DAEMON_CLASS_FQN: String = ""org.jetbrains.kotlin.rmi.service.CompileDaemon"" -+public val COMPILE_DAEMON_DEFAULT_PORT: Int = 17031 -+public val COMPILE_DAEMON_ENABLED_PROPERTY: String =""kotlin.daemon.enabled"" -+public val COMPILE_DAEMON_JVM_OPTIONS_PROPERTY: String =""kotlin.daemon.jvm.options"" -+public val COMPILE_DAEMON_OPTIONS_PROPERTY: String =""kotlin.daemon.options"" -+public val COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX: String =""--daemon-"" -+ -+ -+open class PropExtractor>(val dest: C, -+ val prop: P, -+ val name: String, -+ val convert: ((v: V) -> String?) = { it.toString() }, -+ val skipIf: ((v: V) -> Boolean) = { false }, -+ val mergeWithDelimiter: String? = null) -+{ -+ constructor(dest: C, prop: P, convert: ((v: V) -> String?) = { it.toString() }, skipIf: ((v: V) -> Boolean) = { false }) : this(dest, prop, prop.name, convert, skipIf) -+ open fun extract(prefix: String = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX): List = -+ when { -+ skipIf(prop.get(dest)) -> listOf() -+ mergeWithDelimiter != null -> listOf(prefix + name + mergeWithDelimiter + convert(prop.get(dest))).filterNotNull() -+ else -> listOf(prefix + name, convert(prop.get(dest))).filterNotNull() -+ } -+} -+ -+class BoolPropExtractor>(dest: C, prop: P, name: String? = null) -+ : PropExtractor(dest, prop, name ?: prop.name, convert = { null }, skipIf = { !prop.get(dest) }) -+ -+class RestPropExtractor>>(dest: C, prop: P) : PropExtractor, P>(dest, prop, convert = { null }) { -+ override fun extract(prefix: String): List = prop.get(dest).map { prefix + it } -+} -+ -+ -+open class PropParser>(val dest: C, -+ val prop: P, alternativeNames: List, -+ val parse: (s: String) -> V, -+ val allowMergedArg: Boolean = false) { -+ val names = listOf(prop.name) + alternativeNames -+ constructor(dest: C, prop: P, parse: (s: String) -> V, allowMergedArg: Boolean = false) : this(dest, prop, listOf(), parse, allowMergedArg) -+ fun apply(s: String) = prop.set(dest, parse(s)) -+} -+ -+class BoolPropParser>(dest: C, prop: P): PropParser(dest, prop, { true }) -+ -+class RestPropParser>>(dest: C, prop: P): PropParser, P>(dest, prop, { arrayListOf() }) { -+ fun add(s: String) { prop.get(dest).add(s) } -+} -+ -+ -+fun Iterable.filterSetProps(parsers: List>, prefix: String, restParser: RestPropParser<*,*>? = null) : Iterable { -+ var currentParser: PropParser<*,*,*>? = null -+ var matchingOption = """" -+ val res = filter { param -> -+ if (currentParser == null) { -+ val parser = parsers.find { it.names.any { name -> -+ if (param.startsWith(prefix + name)) { matchingOption = prefix + name; true } -+ else false } } -+ if (parser != null) { -+ val optionLength = matchingOption.length() -+ when { -+ parser is BoolPropParser<*,*> -> -+ if (param.length() > optionLength) throw IllegalArgumentException(""Invalid switch option '$param', expecting $matchingOption without arguments"") -+ else parser.apply("""") -+ param.length() > optionLength -> -+ if (param[optionLength] != '=') { -+ if (parser.allowMergedArg) parser.apply(param.substring(optionLength)) -+ else throw IllegalArgumentException(""Invalid option syntax '$param', expecting $matchingOption[= ]"") -+ } -+ else parser.apply(param.substring(optionLength + 1)) -+ else -> currentParser = parser -+ } -+ false -+ } -+ else if (restParser != null && param.startsWith(prefix)) { -+ restParser.add(param.removePrefix(prefix)) -+ false -+ } -+ else true -+ } -+ else { -+ currentParser!!.apply(param) -+ currentParser = null -+ false -+ } -+ } -+ if (currentParser != null) throw IllegalArgumentException(""Expecting argument for the option $matchingOption"") -+ return res -+} -+ -+// TODO: find out how to create more generic variant using first constructor -+//fun C.propsToParams() { -+// val kc = C::class -+// kc.constructors.first(). -+//} -+ -+ -+ -+public interface CmdlineParams : Serializable { -+ public val extractors: List> -+ public val parsers: List> -+} -+ -+public fun Iterable.filterSetProps(vararg cs: CmdlineParams, prefix: String) : Iterable = -+ filterSetProps(cs.flatMap { it.parsers }, prefix) -+ -+ -+public data class DaemonLaunchingOptions( -+ public var maxMemory: String = """", -+ public var maxPermSize: String = """", -+ public var reservedCodeCacheSize: String = """", -+ public var otherJvmParams: MutableCollection = arrayListOf() -+) : CmdlineParams { -+ -+ override val extractors: List> -+ get() = listOf( PropExtractor(this, ::maxMemory, ""Xmx"", skipIf = { it.isEmpty() }, mergeWithDelimiter = """"), -+ PropExtractor(this, ::maxPermSize, ""XX:MaxPermSize"", skipIf = { it.isEmpty() }, mergeWithDelimiter = ""=""), -+ PropExtractor(this, ::reservedCodeCacheSize, ""XX:ReservedCodeCacheSize"", skipIf = { it.isEmpty() }, mergeWithDelimiter = ""=""), -+ RestPropExtractor(this, ::otherJvmParams)) -+ -+ override val parsers: List> -+ get() = listOf( PropParser(this, ::maxMemory, listOf(""Xmx""), { it }, allowMergedArg = true), -+ PropParser(this, ::maxPermSize, listOf(""XX:MaxPermSize""), { it }, allowMergedArg = true), -+ PropParser(this, ::reservedCodeCacheSize, listOf(""XX:ReservedCodeCacheSize""), { it }, allowMergedArg = true)) -+ // otherJvmParams is missing here deliberately, it is used explicitly as a restParser param to filterSetProps -+} -+ -+public data class DaemonOptions( -+ public var port: Int = COMPILE_DAEMON_DEFAULT_PORT, -+ public var autoshutdownMemoryThreshold: Long = 0 /* 0 means unchecked */, -+ public var autoshutdownIdleSeconds: Int = 0 /* 0 means unchecked */, -+ public var startEcho: String = COMPILER_SERVICE_RMI_NAME -+) : CmdlineParams { -+ -+ override val extractors: List> -+ get() = listOf( PropExtractor(this, ::port), -+ PropExtractor(this, ::autoshutdownMemoryThreshold, skipIf = { it == 0L }), -+ PropExtractor(this, ::autoshutdownIdleSeconds, skipIf = { it == 0 }), -+ PropExtractor(this, ::startEcho)) -+ -+ override val parsers: List> -+ get() = listOf( PropParser(this, ::port, { it.toInt()}), -+ PropParser(this, ::autoshutdownMemoryThreshold, { it.toLong()}), -+ PropParser(this, ::autoshutdownIdleSeconds, { it.toInt()}), -+ PropParser(this, ::startEcho, { it.trim('""') })) -+} -+ -+ -+val COMPILER_ID_DIGEST = ""MD5""","private? -",Maybe use a different nam -224,"@@ -0,0 +1,272 @@ -+/* -+ * 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.rmi -+ -+import java.io.File -+import java.io.Serializable -+import java.lang.management.ManagementFactory -+import java.security.DigestInputStream -+import java.security.MessageDigest -+import kotlin.platform.platformStatic -+import kotlin.reflect.KMutableProperty1 -+import kotlin.reflect.KProperty1 -+ -+ -+public val COMPILER_JAR_NAME: String = ""kotlin-compiler.jar"" -+public val COMPILER_SERVICE_RMI_NAME: String = ""KotlinJvmCompilerService"" -+public val COMPILER_DAEMON_CLASS_FQN: String = ""org.jetbrains.kotlin.rmi.service.CompileDaemon"" -+public val COMPILE_DAEMON_DEFAULT_PORT: Int = 17031 -+public val COMPILE_DAEMON_ENABLED_PROPERTY: String =""kotlin.daemon.enabled"" -+public val COMPILE_DAEMON_JVM_OPTIONS_PROPERTY: String =""kotlin.daemon.jvm.options"" -+public val COMPILE_DAEMON_OPTIONS_PROPERTY: String =""kotlin.daemon.options"" -+public val COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX: String =""--daemon-"" -+ -+ -+open class PropExtractor>(val dest: C, -+ val prop: P, -+ val name: String, -+ val convert: ((v: V) -> String?) = { it.toString() }, -+ val skipIf: ((v: V) -> Boolean) = { false }, -+ val mergeWithDelimiter: String? = null) -+{ -+ constructor(dest: C, prop: P, convert: ((v: V) -> String?) = { it.toString() }, skipIf: ((v: V) -> Boolean) = { false }) : this(dest, prop, prop.name, convert, skipIf) -+ open fun extract(prefix: String = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX): List = -+ when { -+ skipIf(prop.get(dest)) -> listOf() -+ mergeWithDelimiter != null -> listOf(prefix + name + mergeWithDelimiter + convert(prop.get(dest))).filterNotNull() -+ else -> listOf(prefix + name, convert(prop.get(dest))).filterNotNull() -+ } -+} -+ -+class BoolPropExtractor>(dest: C, prop: P, name: String? = null) -+ : PropExtractor(dest, prop, name ?: prop.name, convert = { null }, skipIf = { !prop.get(dest) }) -+ -+class RestPropExtractor>>(dest: C, prop: P) : PropExtractor, P>(dest, prop, convert = { null }) { -+ override fun extract(prefix: String): List = prop.get(dest).map { prefix + it } -+} -+ -+ -+open class PropParser>(val dest: C, -+ val prop: P, alternativeNames: List, -+ val parse: (s: String) -> V, -+ val allowMergedArg: Boolean = false) { -+ val names = listOf(prop.name) + alternativeNames -+ constructor(dest: C, prop: P, parse: (s: String) -> V, allowMergedArg: Boolean = false) : this(dest, prop, listOf(), parse, allowMergedArg) -+ fun apply(s: String) = prop.set(dest, parse(s)) -+} -+ -+class BoolPropParser>(dest: C, prop: P): PropParser(dest, prop, { true }) -+ -+class RestPropParser>>(dest: C, prop: P): PropParser, P>(dest, prop, { arrayListOf() }) { -+ fun add(s: String) { prop.get(dest).add(s) } -+} -+ -+ -+fun Iterable.filterSetProps(parsers: List>, prefix: String, restParser: RestPropParser<*,*>? = null) : Iterable { -+ var currentParser: PropParser<*,*,*>? = null -+ var matchingOption = """" -+ val res = filter { param -> -+ if (currentParser == null) { -+ val parser = parsers.find { it.names.any { name -> -+ if (param.startsWith(prefix + name)) { matchingOption = prefix + name; true } -+ else false } } -+ if (parser != null) { -+ val optionLength = matchingOption.length() -+ when { -+ parser is BoolPropParser<*,*> -> -+ if (param.length() > optionLength) throw IllegalArgumentException(""Invalid switch option '$param', expecting $matchingOption without arguments"") -+ else parser.apply("""") -+ param.length() > optionLength -> -+ if (param[optionLength] != '=') { -+ if (parser.allowMergedArg) parser.apply(param.substring(optionLength)) -+ else throw IllegalArgumentException(""Invalid option syntax '$param', expecting $matchingOption[= ]"") -+ } -+ else parser.apply(param.substring(optionLength + 1)) -+ else -> currentParser = parser -+ } -+ false -+ } -+ else if (restParser != null && param.startsWith(prefix)) { -+ restParser.add(param.removePrefix(prefix)) -+ false -+ } -+ else true -+ } -+ else { -+ currentParser!!.apply(param) -+ currentParser = null -+ false -+ } -+ } -+ if (currentParser != null) throw IllegalArgumentException(""Expecting argument for the option $matchingOption"") -+ return res -+} -+ -+// TODO: find out how to create more generic variant using first constructor -+//fun C.propsToParams() { -+// val kc = C::class -+// kc.constructors.first(). -+//} -+ -+ -+ -+public interface CmdlineParams : Serializable { -+ public val extractors: List> -+ public val parsers: List> -+} -+ -+public fun Iterable.filterSetProps(vararg cs: CmdlineParams, prefix: String) : Iterable = -+ filterSetProps(cs.flatMap { it.parsers }, prefix) -+ -+ -+public data class DaemonLaunchingOptions( -+ public var maxMemory: String = """", -+ public var maxPermSize: String = """", -+ public var reservedCodeCacheSize: String = """", -+ public var otherJvmParams: MutableCollection = arrayListOf() -+) : CmdlineParams { -+ -+ override val extractors: List> -+ get() = listOf( PropExtractor(this, ::maxMemory, ""Xmx"", skipIf = { it.isEmpty() }, mergeWithDelimiter = """"), -+ PropExtractor(this, ::maxPermSize, ""XX:MaxPermSize"", skipIf = { it.isEmpty() }, mergeWithDelimiter = ""=""), -+ PropExtractor(this, ::reservedCodeCacheSize, ""XX:ReservedCodeCacheSize"", skipIf = { it.isEmpty() }, mergeWithDelimiter = ""=""), -+ RestPropExtractor(this, ::otherJvmParams)) -+ -+ override val parsers: List> -+ get() = listOf( PropParser(this, ::maxMemory, listOf(""Xmx""), { it }, allowMergedArg = true), -+ PropParser(this, ::maxPermSize, listOf(""XX:MaxPermSize""), { it }, allowMergedArg = true), -+ PropParser(this, ::reservedCodeCacheSize, listOf(""XX:ReservedCodeCacheSize""), { it }, allowMergedArg = true)) -+ // otherJvmParams is missing here deliberately, it is used explicitly as a restParser param to filterSetProps -+} -+ -+public data class DaemonOptions( -+ public var port: Int = COMPILE_DAEMON_DEFAULT_PORT, -+ public var autoshutdownMemoryThreshold: Long = 0 /* 0 means unchecked */, -+ public var autoshutdownIdleSeconds: Int = 0 /* 0 means unchecked */, -+ public var startEcho: String = COMPILER_SERVICE_RMI_NAME -+) : CmdlineParams { -+ -+ override val extractors: List> -+ get() = listOf( PropExtractor(this, ::port), -+ PropExtractor(this, ::autoshutdownMemoryThreshold, skipIf = { it == 0L }), -+ PropExtractor(this, ::autoshutdownIdleSeconds, skipIf = { it == 0 }), -+ PropExtractor(this, ::startEcho)) -+ -+ override val parsers: List> -+ get() = listOf( PropParser(this, ::port, { it.toInt()}), -+ PropParser(this, ::autoshutdownMemoryThreshold, { it.toLong()}), -+ PropParser(this, ::autoshutdownIdleSeconds, { it.toInt()}), -+ PropParser(this, ::startEcho, { it.trim('""') })) -+} -+ -+ -+val COMPILER_ID_DIGEST = ""MD5"" -+ -+ -+fun updateSingleFileDigest(file: File, md: MessageDigest) {","private? -","Maybe use a different name, e.g. `kotlin.rmi.options`?" -225,"@@ -0,0 +1,272 @@ -+/* -+ * 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.rmi -+ -+import java.io.File -+import java.io.Serializable -+import java.lang.management.ManagementFactory -+import java.security.DigestInputStream -+import java.security.MessageDigest -+import kotlin.platform.platformStatic -+import kotlin.reflect.KMutableProperty1 -+import kotlin.reflect.KProperty1 -+ -+ -+public val COMPILER_JAR_NAME: String = ""kotlin-compiler.jar"" -+public val COMPILER_SERVICE_RMI_NAME: String = ""KotlinJvmCompilerService"" -+public val COMPILER_DAEMON_CLASS_FQN: String = ""org.jetbrains.kotlin.rmi.service.CompileDaemon"" -+public val COMPILE_DAEMON_DEFAULT_PORT: Int = 17031 -+public val COMPILE_DAEMON_ENABLED_PROPERTY: String =""kotlin.daemon.enabled"" -+public val COMPILE_DAEMON_JVM_OPTIONS_PROPERTY: String =""kotlin.daemon.jvm.options"" -+public val COMPILE_DAEMON_OPTIONS_PROPERTY: String =""kotlin.daemon.options"" -+public val COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX: String =""--daemon-"" -+ -+ -+open class PropExtractor>(val dest: C, -+ val prop: P, -+ val name: String, -+ val convert: ((v: V) -> String?) = { it.toString() }, -+ val skipIf: ((v: V) -> Boolean) = { false }, -+ val mergeWithDelimiter: String? = null) -+{ -+ constructor(dest: C, prop: P, convert: ((v: V) -> String?) = { it.toString() }, skipIf: ((v: V) -> Boolean) = { false }) : this(dest, prop, prop.name, convert, skipIf) -+ open fun extract(prefix: String = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX): List = -+ when { -+ skipIf(prop.get(dest)) -> listOf() -+ mergeWithDelimiter != null -> listOf(prefix + name + mergeWithDelimiter + convert(prop.get(dest))).filterNotNull() -+ else -> listOf(prefix + name, convert(prop.get(dest))).filterNotNull() -+ } -+} -+ -+class BoolPropExtractor>(dest: C, prop: P, name: String? = null) -+ : PropExtractor(dest, prop, name ?: prop.name, convert = { null }, skipIf = { !prop.get(dest) }) -+ -+class RestPropExtractor>>(dest: C, prop: P) : PropExtractor, P>(dest, prop, convert = { null }) { -+ override fun extract(prefix: String): List = prop.get(dest).map { prefix + it } -+} -+ -+ -+open class PropParser>(val dest: C, -+ val prop: P, alternativeNames: List, -+ val parse: (s: String) -> V, -+ val allowMergedArg: Boolean = false) { -+ val names = listOf(prop.name) + alternativeNames -+ constructor(dest: C, prop: P, parse: (s: String) -> V, allowMergedArg: Boolean = false) : this(dest, prop, listOf(), parse, allowMergedArg) -+ fun apply(s: String) = prop.set(dest, parse(s)) -+} -+ -+class BoolPropParser>(dest: C, prop: P): PropParser(dest, prop, { true }) -+ -+class RestPropParser>>(dest: C, prop: P): PropParser, P>(dest, prop, { arrayListOf() }) { -+ fun add(s: String) { prop.get(dest).add(s) } -+} -+ -+ -+fun Iterable.filterSetProps(parsers: List>, prefix: String, restParser: RestPropParser<*,*>? = null) : Iterable { -+ var currentParser: PropParser<*,*,*>? = null -+ var matchingOption = """" -+ val res = filter { param -> -+ if (currentParser == null) { -+ val parser = parsers.find { it.names.any { name -> -+ if (param.startsWith(prefix + name)) { matchingOption = prefix + name; true } -+ else false } } -+ if (parser != null) { -+ val optionLength = matchingOption.length() -+ when { -+ parser is BoolPropParser<*,*> -> -+ if (param.length() > optionLength) throw IllegalArgumentException(""Invalid switch option '$param', expecting $matchingOption without arguments"") -+ else parser.apply("""") -+ param.length() > optionLength -> -+ if (param[optionLength] != '=') { -+ if (parser.allowMergedArg) parser.apply(param.substring(optionLength)) -+ else throw IllegalArgumentException(""Invalid option syntax '$param', expecting $matchingOption[= ]"") -+ } -+ else parser.apply(param.substring(optionLength + 1)) -+ else -> currentParser = parser -+ } -+ false -+ } -+ else if (restParser != null && param.startsWith(prefix)) { -+ restParser.add(param.removePrefix(prefix)) -+ false -+ } -+ else true -+ } -+ else { -+ currentParser!!.apply(param) -+ currentParser = null -+ false -+ } -+ } -+ if (currentParser != null) throw IllegalArgumentException(""Expecting argument for the option $matchingOption"") -+ return res -+} -+ -+// TODO: find out how to create more generic variant using first constructor -+//fun C.propsToParams() { -+// val kc = C::class -+// kc.constructors.first(). -+//} -+ -+ -+ -+public interface CmdlineParams : Serializable { -+ public val extractors: List> -+ public val parsers: List> -+} -+ -+public fun Iterable.filterSetProps(vararg cs: CmdlineParams, prefix: String) : Iterable = -+ filterSetProps(cs.flatMap { it.parsers }, prefix) -+ -+ -+public data class DaemonLaunchingOptions( -+ public var maxMemory: String = """", -+ public var maxPermSize: String = """", -+ public var reservedCodeCacheSize: String = """", -+ public var otherJvmParams: MutableCollection = arrayListOf() -+) : CmdlineParams { -+ -+ override val extractors: List> -+ get() = listOf( PropExtractor(this, ::maxMemory, ""Xmx"", skipIf = { it.isEmpty() }, mergeWithDelimiter = """"), -+ PropExtractor(this, ::maxPermSize, ""XX:MaxPermSize"", skipIf = { it.isEmpty() }, mergeWithDelimiter = ""=""), -+ PropExtractor(this, ::reservedCodeCacheSize, ""XX:ReservedCodeCacheSize"", skipIf = { it.isEmpty() }, mergeWithDelimiter = ""=""), -+ RestPropExtractor(this, ::otherJvmParams)) -+ -+ override val parsers: List> -+ get() = listOf( PropParser(this, ::maxMemory, listOf(""Xmx""), { it }, allowMergedArg = true), -+ PropParser(this, ::maxPermSize, listOf(""XX:MaxPermSize""), { it }, allowMergedArg = true), -+ PropParser(this, ::reservedCodeCacheSize, listOf(""XX:ReservedCodeCacheSize""), { it }, allowMergedArg = true)) -+ // otherJvmParams is missing here deliberately, it is used explicitly as a restParser param to filterSetProps -+} -+ -+public data class DaemonOptions( -+ public var port: Int = COMPILE_DAEMON_DEFAULT_PORT, -+ public var autoshutdownMemoryThreshold: Long = 0 /* 0 means unchecked */, -+ public var autoshutdownIdleSeconds: Int = 0 /* 0 means unchecked */, -+ public var startEcho: String = COMPILER_SERVICE_RMI_NAME -+) : CmdlineParams { -+ -+ override val extractors: List> -+ get() = listOf( PropExtractor(this, ::port), -+ PropExtractor(this, ::autoshutdownMemoryThreshold, skipIf = { it == 0L }), -+ PropExtractor(this, ::autoshutdownIdleSeconds, skipIf = { it == 0 }), -+ PropExtractor(this, ::startEcho)) -+ -+ override val parsers: List> -+ get() = listOf( PropParser(this, ::port, { it.toInt()}), -+ PropParser(this, ::autoshutdownMemoryThreshold, { it.toLong()}), -+ PropParser(this, ::autoshutdownIdleSeconds, { it.toInt()}), -+ PropParser(this, ::startEcho, { it.trim('""') })) -+} -+ -+ -+val COMPILER_ID_DIGEST = ""MD5"" -+ -+ -+fun updateSingleFileDigest(file: File, md: MessageDigest) { -+ DigestInputStream(file.inputStream(), md).use { -+ val buf = ByteArray(1024) -+ while (it.read(buf) != -1) { } -+ it.close() -+ } -+} -+ -+fun updateForAllClasses(dir: File, md: MessageDigest) { -+ dir.walk().forEach { updateEntryDigest(it, md) } -+} -+ -+fun updateEntryDigest(entry: File, md: MessageDigest) { -+ when { -+ entry.isDirectory -+ -> updateForAllClasses(entry, md) -+ entry.isFile && -+ (entry.getName().endsWith("".class"", ignoreCase = true) ||","`getName()` can be replaces with `name` -","Maybe use a different name, e.g. `kotlin.rmi.options`?" -226,"@@ -0,0 +1,272 @@ -+/* -+ * 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.rmi -+ -+import java.io.File -+import java.io.Serializable -+import java.lang.management.ManagementFactory -+import java.security.DigestInputStream -+import java.security.MessageDigest -+import kotlin.platform.platformStatic -+import kotlin.reflect.KMutableProperty1 -+import kotlin.reflect.KProperty1 -+ -+ -+public val COMPILER_JAR_NAME: String = ""kotlin-compiler.jar"" -+public val COMPILER_SERVICE_RMI_NAME: String = ""KotlinJvmCompilerService"" -+public val COMPILER_DAEMON_CLASS_FQN: String = ""org.jetbrains.kotlin.rmi.service.CompileDaemon"" -+public val COMPILE_DAEMON_DEFAULT_PORT: Int = 17031 -+public val COMPILE_DAEMON_ENABLED_PROPERTY: String =""kotlin.daemon.enabled"" -+public val COMPILE_DAEMON_JVM_OPTIONS_PROPERTY: String =""kotlin.daemon.jvm.options"" -+public val COMPILE_DAEMON_OPTIONS_PROPERTY: String =""kotlin.daemon.options"" -+public val COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX: String =""--daemon-"" -+ -+ -+open class PropExtractor>(val dest: C, -+ val prop: P, -+ val name: String, -+ val convert: ((v: V) -> String?) = { it.toString() }, -+ val skipIf: ((v: V) -> Boolean) = { false }, -+ val mergeWithDelimiter: String? = null) -+{ -+ constructor(dest: C, prop: P, convert: ((v: V) -> String?) = { it.toString() }, skipIf: ((v: V) -> Boolean) = { false }) : this(dest, prop, prop.name, convert, skipIf) -+ open fun extract(prefix: String = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX): List = -+ when { -+ skipIf(prop.get(dest)) -> listOf() -+ mergeWithDelimiter != null -> listOf(prefix + name + mergeWithDelimiter + convert(prop.get(dest))).filterNotNull() -+ else -> listOf(prefix + name, convert(prop.get(dest))).filterNotNull() -+ } -+} -+ -+class BoolPropExtractor>(dest: C, prop: P, name: String? = null) -+ : PropExtractor(dest, prop, name ?: prop.name, convert = { null }, skipIf = { !prop.get(dest) }) -+ -+class RestPropExtractor>>(dest: C, prop: P) : PropExtractor, P>(dest, prop, convert = { null }) { -+ override fun extract(prefix: String): List = prop.get(dest).map { prefix + it } -+} -+ -+ -+open class PropParser>(val dest: C, -+ val prop: P, alternativeNames: List, -+ val parse: (s: String) -> V, -+ val allowMergedArg: Boolean = false) { -+ val names = listOf(prop.name) + alternativeNames -+ constructor(dest: C, prop: P, parse: (s: String) -> V, allowMergedArg: Boolean = false) : this(dest, prop, listOf(), parse, allowMergedArg) -+ fun apply(s: String) = prop.set(dest, parse(s)) -+} -+ -+class BoolPropParser>(dest: C, prop: P): PropParser(dest, prop, { true }) -+ -+class RestPropParser>>(dest: C, prop: P): PropParser, P>(dest, prop, { arrayListOf() }) { -+ fun add(s: String) { prop.get(dest).add(s) } -+} -+ -+ -+fun Iterable.filterSetProps(parsers: List>, prefix: String, restParser: RestPropParser<*,*>? = null) : Iterable { -+ var currentParser: PropParser<*,*,*>? = null -+ var matchingOption = """" -+ val res = filter { param -> -+ if (currentParser == null) { -+ val parser = parsers.find { it.names.any { name -> -+ if (param.startsWith(prefix + name)) { matchingOption = prefix + name; true } -+ else false } } -+ if (parser != null) { -+ val optionLength = matchingOption.length() -+ when { -+ parser is BoolPropParser<*,*> -> -+ if (param.length() > optionLength) throw IllegalArgumentException(""Invalid switch option '$param', expecting $matchingOption without arguments"") -+ else parser.apply("""") -+ param.length() > optionLength -> -+ if (param[optionLength] != '=') { -+ if (parser.allowMergedArg) parser.apply(param.substring(optionLength)) -+ else throw IllegalArgumentException(""Invalid option syntax '$param', expecting $matchingOption[= ]"") -+ } -+ else parser.apply(param.substring(optionLength + 1)) -+ else -> currentParser = parser -+ } -+ false -+ } -+ else if (restParser != null && param.startsWith(prefix)) { -+ restParser.add(param.removePrefix(prefix)) -+ false -+ } -+ else true -+ } -+ else { -+ currentParser!!.apply(param) -+ currentParser = null -+ false -+ } -+ } -+ if (currentParser != null) throw IllegalArgumentException(""Expecting argument for the option $matchingOption"") -+ return res -+} -+ -+// TODO: find out how to create more generic variant using first constructor -+//fun C.propsToParams() { -+// val kc = C::class -+// kc.constructors.first(). -+//} -+ -+ -+ -+public interface CmdlineParams : Serializable { -+ public val extractors: List> -+ public val parsers: List> -+} -+ -+public fun Iterable.filterSetProps(vararg cs: CmdlineParams, prefix: String) : Iterable = -+ filterSetProps(cs.flatMap { it.parsers }, prefix) -+ -+ -+public data class DaemonLaunchingOptions( -+ public var maxMemory: String = """", -+ public var maxPermSize: String = """", -+ public var reservedCodeCacheSize: String = """", -+ public var otherJvmParams: MutableCollection = arrayListOf() -+) : CmdlineParams { -+ -+ override val extractors: List> -+ get() = listOf( PropExtractor(this, ::maxMemory, ""Xmx"", skipIf = { it.isEmpty() }, mergeWithDelimiter = """"), -+ PropExtractor(this, ::maxPermSize, ""XX:MaxPermSize"", skipIf = { it.isEmpty() }, mergeWithDelimiter = ""=""), -+ PropExtractor(this, ::reservedCodeCacheSize, ""XX:ReservedCodeCacheSize"", skipIf = { it.isEmpty() }, mergeWithDelimiter = ""=""), -+ RestPropExtractor(this, ::otherJvmParams)) -+ -+ override val parsers: List> -+ get() = listOf( PropParser(this, ::maxMemory, listOf(""Xmx""), { it }, allowMergedArg = true), -+ PropParser(this, ::maxPermSize, listOf(""XX:MaxPermSize""), { it }, allowMergedArg = true), -+ PropParser(this, ::reservedCodeCacheSize, listOf(""XX:ReservedCodeCacheSize""), { it }, allowMergedArg = true)) -+ // otherJvmParams is missing here deliberately, it is used explicitly as a restParser param to filterSetProps -+} -+ -+public data class DaemonOptions( -+ public var port: Int = COMPILE_DAEMON_DEFAULT_PORT, -+ public var autoshutdownMemoryThreshold: Long = 0 /* 0 means unchecked */, -+ public var autoshutdownIdleSeconds: Int = 0 /* 0 means unchecked */, -+ public var startEcho: String = COMPILER_SERVICE_RMI_NAME -+) : CmdlineParams { -+ -+ override val extractors: List> -+ get() = listOf( PropExtractor(this, ::port), -+ PropExtractor(this, ::autoshutdownMemoryThreshold, skipIf = { it == 0L }), -+ PropExtractor(this, ::autoshutdownIdleSeconds, skipIf = { it == 0 }), -+ PropExtractor(this, ::startEcho)) -+ -+ override val parsers: List> -+ get() = listOf( PropParser(this, ::port, { it.toInt()}), -+ PropParser(this, ::autoshutdownMemoryThreshold, { it.toLong()}), -+ PropParser(this, ::autoshutdownIdleSeconds, { it.toInt()}), -+ PropParser(this, ::startEcho, { it.trim('""') })) -+} -+ -+ -+val COMPILER_ID_DIGEST = ""MD5"" -+ -+ -+fun updateSingleFileDigest(file: File, md: MessageDigest) { -+ DigestInputStream(file.inputStream(), md).use { -+ val buf = ByteArray(1024) -+ while (it.read(buf) != -1) { } -+ it.close() -+ } -+} -+ -+fun updateForAllClasses(dir: File, md: MessageDigest) { -+ dir.walk().forEach { updateEntryDigest(it, md) } -+} -+ -+fun updateEntryDigest(entry: File, md: MessageDigest) { -+ when { -+ entry.isDirectory -+ -> updateForAllClasses(entry, md) -+ entry.isFile && -+ (entry.getName().endsWith("".class"", ignoreCase = true) || -+ entry.getName().endsWith("".jar"", ignoreCase = true)) -+ -> updateSingleFileDigest(entry, md) -+ // else skip -+ } -+} -+ -+fun Iterable.getFilesClasspathDigest(): String { -+ val md = MessageDigest.getInstance(COMPILER_ID_DIGEST) -+ this.forEach { updateEntryDigest(it, md) } -+ return md.digest().joinToString("""", transform = { ""%02x"".format(it) }) -+} -+ -+fun Iterable.getClasspathDigest(): String = map { File(it) }.getFilesClasspathDigest() -+ -+ -+public data class CompilerId( -+ public var compilerClasspath: List = listOf(), -+ public var compilerDigest: String = """", -+ public var compilerVersion: String = """" -+ // TODO: checksum -+) : CmdlineParams { -+ -+ override val extractors: List> -+ get() = listOf( PropExtractor(this, ::compilerClasspath, convert = { it.joinToString(File.pathSeparator) }), -+ PropExtractor(this, ::compilerDigest), -+ PropExtractor(this, ::compilerVersion, skipIf = { it.isEmpty() })) -+ -+ override val parsers: List> -+ get() = -+ listOf( PropParser(this, ::compilerClasspath, { it.trim('""').split(File.pathSeparator)}), -+ PropParser(this, ::compilerDigest, { it.trim('""') }), -+ PropParser(this, ::compilerVersion, { it.trim('""') })) -+ -+ public fun updateDigest() { -+ compilerDigest = compilerClasspath.getClasspathDigest() -+ } -+ -+ companion object { -+ public platformStatic fun makeCompilerId(vararg paths: File): CompilerId = makeCompilerId(paths.asIterable())","`platformStatic` deprecated now -","Maybe use a different name, e.g. `kotlin.rmi.options`?" -227,"@@ -0,0 +1,272 @@ -+/* -+ * 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.rmi -+ -+import java.io.File -+import java.io.Serializable -+import java.lang.management.ManagementFactory -+import java.security.DigestInputStream -+import java.security.MessageDigest -+import kotlin.platform.platformStatic -+import kotlin.reflect.KMutableProperty1 -+import kotlin.reflect.KProperty1 -+ -+ -+public val COMPILER_JAR_NAME: String = ""kotlin-compiler.jar"" -+public val COMPILER_SERVICE_RMI_NAME: String = ""KotlinJvmCompilerService"" -+public val COMPILER_DAEMON_CLASS_FQN: String = ""org.jetbrains.kotlin.rmi.service.CompileDaemon"" -+public val COMPILE_DAEMON_DEFAULT_PORT: Int = 17031 -+public val COMPILE_DAEMON_ENABLED_PROPERTY: String =""kotlin.daemon.enabled"" -+public val COMPILE_DAEMON_JVM_OPTIONS_PROPERTY: String =""kotlin.daemon.jvm.options"" -+public val COMPILE_DAEMON_OPTIONS_PROPERTY: String =""kotlin.daemon.options"" -+public val COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX: String =""--daemon-"" -+ -+ -+open class PropExtractor>(val dest: C, -+ val prop: P, -+ val name: String, -+ val convert: ((v: V) -> String?) = { it.toString() }, -+ val skipIf: ((v: V) -> Boolean) = { false }, -+ val mergeWithDelimiter: String? = null) -+{ -+ constructor(dest: C, prop: P, convert: ((v: V) -> String?) = { it.toString() }, skipIf: ((v: V) -> Boolean) = { false }) : this(dest, prop, prop.name, convert, skipIf) -+ open fun extract(prefix: String = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX): List = -+ when { -+ skipIf(prop.get(dest)) -> listOf() -+ mergeWithDelimiter != null -> listOf(prefix + name + mergeWithDelimiter + convert(prop.get(dest))).filterNotNull() -+ else -> listOf(prefix + name, convert(prop.get(dest))).filterNotNull() -+ } -+} -+ -+class BoolPropExtractor>(dest: C, prop: P, name: String? = null) -+ : PropExtractor(dest, prop, name ?: prop.name, convert = { null }, skipIf = { !prop.get(dest) }) -+ -+class RestPropExtractor>>(dest: C, prop: P) : PropExtractor, P>(dest, prop, convert = { null }) { -+ override fun extract(prefix: String): List = prop.get(dest).map { prefix + it } -+} -+ -+ -+open class PropParser>(val dest: C, -+ val prop: P, alternativeNames: List, -+ val parse: (s: String) -> V, -+ val allowMergedArg: Boolean = false) { -+ val names = listOf(prop.name) + alternativeNames -+ constructor(dest: C, prop: P, parse: (s: String) -> V, allowMergedArg: Boolean = false) : this(dest, prop, listOf(), parse, allowMergedArg) -+ fun apply(s: String) = prop.set(dest, parse(s)) -+} -+ -+class BoolPropParser>(dest: C, prop: P): PropParser(dest, prop, { true }) -+ -+class RestPropParser>>(dest: C, prop: P): PropParser, P>(dest, prop, { arrayListOf() }) { -+ fun add(s: String) { prop.get(dest).add(s) } -+} -+ -+ -+fun Iterable.filterSetProps(parsers: List>, prefix: String, restParser: RestPropParser<*,*>? = null) : Iterable { -+ var currentParser: PropParser<*,*,*>? = null -+ var matchingOption = """" -+ val res = filter { param -> -+ if (currentParser == null) { -+ val parser = parsers.find { it.names.any { name -> -+ if (param.startsWith(prefix + name)) { matchingOption = prefix + name; true } -+ else false } } -+ if (parser != null) { -+ val optionLength = matchingOption.length() -+ when { -+ parser is BoolPropParser<*,*> -> -+ if (param.length() > optionLength) throw IllegalArgumentException(""Invalid switch option '$param', expecting $matchingOption without arguments"") -+ else parser.apply("""") -+ param.length() > optionLength -> -+ if (param[optionLength] != '=') { -+ if (parser.allowMergedArg) parser.apply(param.substring(optionLength)) -+ else throw IllegalArgumentException(""Invalid option syntax '$param', expecting $matchingOption[= ]"") -+ } -+ else parser.apply(param.substring(optionLength + 1)) -+ else -> currentParser = parser -+ } -+ false -+ } -+ else if (restParser != null && param.startsWith(prefix)) { -+ restParser.add(param.removePrefix(prefix)) -+ false -+ } -+ else true -+ } -+ else { -+ currentParser!!.apply(param) -+ currentParser = null -+ false -+ } -+ } -+ if (currentParser != null) throw IllegalArgumentException(""Expecting argument for the option $matchingOption"") -+ return res -+} -+ -+// TODO: find out how to create more generic variant using first constructor -+//fun C.propsToParams() { -+// val kc = C::class -+// kc.constructors.first(). -+//} -+ -+ -+ -+public interface CmdlineParams : Serializable { -+ public val extractors: List> -+ public val parsers: List> -+} -+ -+public fun Iterable.filterSetProps(vararg cs: CmdlineParams, prefix: String) : Iterable = -+ filterSetProps(cs.flatMap { it.parsers }, prefix) -+ -+ -+public data class DaemonLaunchingOptions( -+ public var maxMemory: String = """", -+ public var maxPermSize: String = """", -+ public var reservedCodeCacheSize: String = """", -+ public var otherJvmParams: MutableCollection = arrayListOf() -+) : CmdlineParams { -+ -+ override val extractors: List> -+ get() = listOf( PropExtractor(this, ::maxMemory, ""Xmx"", skipIf = { it.isEmpty() }, mergeWithDelimiter = """"), -+ PropExtractor(this, ::maxPermSize, ""XX:MaxPermSize"", skipIf = { it.isEmpty() }, mergeWithDelimiter = ""=""), -+ PropExtractor(this, ::reservedCodeCacheSize, ""XX:ReservedCodeCacheSize"", skipIf = { it.isEmpty() }, mergeWithDelimiter = ""=""), -+ RestPropExtractor(this, ::otherJvmParams)) -+ -+ override val parsers: List> -+ get() = listOf( PropParser(this, ::maxMemory, listOf(""Xmx""), { it }, allowMergedArg = true), -+ PropParser(this, ::maxPermSize, listOf(""XX:MaxPermSize""), { it }, allowMergedArg = true), -+ PropParser(this, ::reservedCodeCacheSize, listOf(""XX:ReservedCodeCacheSize""), { it }, allowMergedArg = true)) -+ // otherJvmParams is missing here deliberately, it is used explicitly as a restParser param to filterSetProps -+} -+ -+public data class DaemonOptions( -+ public var port: Int = COMPILE_DAEMON_DEFAULT_PORT, -+ public var autoshutdownMemoryThreshold: Long = 0 /* 0 means unchecked */, -+ public var autoshutdownIdleSeconds: Int = 0 /* 0 means unchecked */, -+ public var startEcho: String = COMPILER_SERVICE_RMI_NAME -+) : CmdlineParams { -+ -+ override val extractors: List> -+ get() = listOf( PropExtractor(this, ::port), -+ PropExtractor(this, ::autoshutdownMemoryThreshold, skipIf = { it == 0L }), -+ PropExtractor(this, ::autoshutdownIdleSeconds, skipIf = { it == 0 }), -+ PropExtractor(this, ::startEcho)) -+ -+ override val parsers: List> -+ get() = listOf( PropParser(this, ::port, { it.toInt()}), -+ PropParser(this, ::autoshutdownMemoryThreshold, { it.toLong()}), -+ PropParser(this, ::autoshutdownIdleSeconds, { it.toInt()}), -+ PropParser(this, ::startEcho, { it.trim('""') })) -+} -+ -+ -+val COMPILER_ID_DIGEST = ""MD5"" -+ -+ -+fun updateSingleFileDigest(file: File, md: MessageDigest) { -+ DigestInputStream(file.inputStream(), md).use { -+ val buf = ByteArray(1024) -+ while (it.read(buf) != -1) { } -+ it.close() -+ } -+} -+ -+fun updateForAllClasses(dir: File, md: MessageDigest) { -+ dir.walk().forEach { updateEntryDigest(it, md) } -+} -+ -+fun updateEntryDigest(entry: File, md: MessageDigest) { -+ when { -+ entry.isDirectory -+ -> updateForAllClasses(entry, md) -+ entry.isFile && -+ (entry.getName().endsWith("".class"", ignoreCase = true) || -+ entry.getName().endsWith("".jar"", ignoreCase = true)) -+ -> updateSingleFileDigest(entry, md) -+ // else skip -+ } -+} -+ -+fun Iterable.getFilesClasspathDigest(): String { -+ val md = MessageDigest.getInstance(COMPILER_ID_DIGEST) -+ this.forEach { updateEntryDigest(it, md) } -+ return md.digest().joinToString("""", transform = { ""%02x"".format(it) }) -+} -+ -+fun Iterable.getClasspathDigest(): String = map { File(it) }.getFilesClasspathDigest() -+ -+ -+public data class CompilerId( -+ public var compilerClasspath: List = listOf(), -+ public var compilerDigest: String = """", -+ public var compilerVersion: String = """" -+ // TODO: checksum -+) : CmdlineParams { -+ -+ override val extractors: List> -+ get() = listOf( PropExtractor(this, ::compilerClasspath, convert = { it.joinToString(File.pathSeparator) }), -+ PropExtractor(this, ::compilerDigest), -+ PropExtractor(this, ::compilerVersion, skipIf = { it.isEmpty() })) -+ -+ override val parsers: List> -+ get() = -+ listOf( PropParser(this, ::compilerClasspath, { it.trim('""').split(File.pathSeparator)}), -+ PropParser(this, ::compilerDigest, { it.trim('""') }), -+ PropParser(this, ::compilerVersion, { it.trim('""') })) -+ -+ public fun updateDigest() { -+ compilerDigest = compilerClasspath.getClasspathDigest() -+ } -+ -+ companion object { -+ public platformStatic fun makeCompilerId(vararg paths: File): CompilerId = makeCompilerId(paths.asIterable()) -+ -+ public platformStatic fun makeCompilerId(paths: Iterable): CompilerId =","it has only one usage -","Maybe use a different name, e.g. `kotlin.rmi.options`?" -228,"@@ -0,0 +1,276 @@ -+/* -+ * 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.rmi.kotlinr -+ -+import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache -+import org.jetbrains.kotlin.rmi.* -+import java.io.File -+import java.io.OutputStream -+import java.io.PrintStream -+import java.rmi.ConnectException -+import java.rmi.Remote -+import java.rmi.registry.LocateRegistry -+import java.util.concurrent.TimeUnit -+import java.util.concurrent.locks.ReentrantReadWriteLock -+import kotlin.concurrent.read -+import kotlin.concurrent.thread -+import kotlin.concurrent.write -+import kotlin.platform.platformStatic -+ -+fun Process.isAlive() = -+ try { -+ this.exitValue() -+ false -+ } -+ catch (e: IllegalThreadStateException) { -+ true -+ } -+ -+public class KotlinCompilerClient { -+ -+ companion object { -+ -+ val DAEMON_STARTUP_TIMEOUT_MS = 10000L -+ val DAEMON_STARTUP_CHECK_INTERVAL_MS = 100L -+ -+ private fun connectToService(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): CompileService? { -+ -+ val compilerObj = connectToDaemon(compilerId, daemonOptions, errStream) ?: return null // no registry - no daemon running -+ return compilerObj as? CompileService ?: -+ throw ClassCastException(""Unable to cast compiler service, actual class received: ${compilerObj.javaClass}"") -+ } -+ -+ private fun connectToDaemon(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): Remote? { -+ try { -+ val daemon = LocateRegistry.getRegistry(""localhost"", daemonOptions.port) -+ ?.lookup(COMPILER_SERVICE_RMI_NAME) -+ if (daemon != null) -+ return daemon -+ errStream.println(""[daemon client] daemon not found"") -+ } -+ catch (e: ConnectException) { -+ errStream.println(""[daemon client] cannot connect to registry: "" + (e.getCause()?.getMessage() ?: e.getMessage() ?: ""unknown exception"")) -+ // ignoring it - processing below -+ } -+ return null -+ } -+ -+ -+ private fun startDaemon(compilerId: CompilerId, daemonLaunchingOptions: DaemonLaunchingOptions, daemonOptions: DaemonOptions, errStream: PrintStream) { -+ val javaExecutable = listOf(System.getProperty(""java.home""), ""bin"", ""java"").joinToString(File.separator) -+ // TODO: add some specific environment variables to the cp and may be command line, to allow some specific startup configs -+ val args = listOf(javaExecutable, -+ ""-cp"", compilerId.compilerClasspath.joinToString(File.pathSeparator)) + -+ daemonLaunchingOptions.jvmParams + -+ COMPILER_DAEMON_CLASS_FQN + -+ daemonOptions.asParams + -+ compilerId.asParams -+ errStream.println(""[daemon client] starting the daemon as: "" + args.joinToString("" "")) -+ val processBuilder = ProcessBuilder(args).redirectErrorStream(true) -+ // assuming daemon process is deaf and (mostly) silent, so do not handle streams -+ val daemon = processBuilder.start() -+ -+ val lock = ReentrantReadWriteLock() -+ var isEchoRead = false","Would be simpler to use an AtomicBoolean here. Or better yet, a semaphore, in which case you won't need a wait loop. -","This isn't related to this PR, but there is a typo her" -229,"@@ -0,0 +1,276 @@ -+/* -+ * 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.rmi.kotlinr -+ -+import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache -+import org.jetbrains.kotlin.rmi.* -+import java.io.File -+import java.io.OutputStream -+import java.io.PrintStream -+import java.rmi.ConnectException -+import java.rmi.Remote -+import java.rmi.registry.LocateRegistry -+import java.util.concurrent.TimeUnit -+import java.util.concurrent.locks.ReentrantReadWriteLock -+import kotlin.concurrent.read -+import kotlin.concurrent.thread -+import kotlin.concurrent.write -+import kotlin.platform.platformStatic -+ -+fun Process.isAlive() = -+ try { -+ this.exitValue() -+ false -+ } -+ catch (e: IllegalThreadStateException) { -+ true -+ } -+ -+public class KotlinCompilerClient { -+ -+ companion object { -+ -+ val DAEMON_STARTUP_TIMEOUT_MS = 10000L -+ val DAEMON_STARTUP_CHECK_INTERVAL_MS = 100L -+ -+ private fun connectToService(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): CompileService? { -+ -+ val compilerObj = connectToDaemon(compilerId, daemonOptions, errStream) ?: return null // no registry - no daemon running -+ return compilerObj as? CompileService ?: -+ throw ClassCastException(""Unable to cast compiler service, actual class received: ${compilerObj.javaClass}"") -+ } -+ -+ private fun connectToDaemon(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): Remote? { -+ try { -+ val daemon = LocateRegistry.getRegistry(""localhost"", daemonOptions.port) -+ ?.lookup(COMPILER_SERVICE_RMI_NAME) -+ if (daemon != null) -+ return daemon -+ errStream.println(""[daemon client] daemon not found"") -+ } -+ catch (e: ConnectException) { -+ errStream.println(""[daemon client] cannot connect to registry: "" + (e.getCause()?.getMessage() ?: e.getMessage() ?: ""unknown exception"")) -+ // ignoring it - processing below -+ } -+ return null -+ } -+ -+ -+ private fun startDaemon(compilerId: CompilerId, daemonLaunchingOptions: DaemonLaunchingOptions, daemonOptions: DaemonOptions, errStream: PrintStream) { -+ val javaExecutable = listOf(System.getProperty(""java.home""), ""bin"", ""java"").joinToString(File.separator) -+ // TODO: add some specific environment variables to the cp and may be command line, to allow some specific startup configs -+ val args = listOf(javaExecutable, -+ ""-cp"", compilerId.compilerClasspath.joinToString(File.pathSeparator)) + -+ daemonLaunchingOptions.jvmParams + -+ COMPILER_DAEMON_CLASS_FQN + -+ daemonOptions.asParams + -+ compilerId.asParams -+ errStream.println(""[daemon client] starting the daemon as: "" + args.joinToString("" "")) -+ val processBuilder = ProcessBuilder(args).redirectErrorStream(true) -+ // assuming daemon process is deaf and (mostly) silent, so do not handle streams -+ val daemon = processBuilder.start() -+ -+ val lock = ReentrantReadWriteLock() -+ var isEchoRead = false -+ -+ val stdouThread =","typo: stdoutThread -","This isn't related to this PR, but there is a typo her" -230,"@@ -0,0 +1,276 @@ -+/* -+ * 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.rmi.kotlinr -+ -+import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache -+import org.jetbrains.kotlin.rmi.* -+import java.io.File -+import java.io.OutputStream -+import java.io.PrintStream -+import java.rmi.ConnectException -+import java.rmi.Remote -+import java.rmi.registry.LocateRegistry -+import java.util.concurrent.TimeUnit -+import java.util.concurrent.locks.ReentrantReadWriteLock -+import kotlin.concurrent.read -+import kotlin.concurrent.thread -+import kotlin.concurrent.write -+import kotlin.platform.platformStatic -+ -+fun Process.isAlive() = -+ try { -+ this.exitValue() -+ false -+ } -+ catch (e: IllegalThreadStateException) { -+ true -+ } -+ -+public class KotlinCompilerClient { -+ -+ companion object { -+ -+ val DAEMON_STARTUP_TIMEOUT_MS = 10000L -+ val DAEMON_STARTUP_CHECK_INTERVAL_MS = 100L -+ -+ private fun connectToService(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): CompileService? { -+ -+ val compilerObj = connectToDaemon(compilerId, daemonOptions, errStream) ?: return null // no registry - no daemon running -+ return compilerObj as? CompileService ?: -+ throw ClassCastException(""Unable to cast compiler service, actual class received: ${compilerObj.javaClass}"") -+ } -+ -+ private fun connectToDaemon(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): Remote? { -+ try { -+ val daemon = LocateRegistry.getRegistry(""localhost"", daemonOptions.port) -+ ?.lookup(COMPILER_SERVICE_RMI_NAME) -+ if (daemon != null) -+ return daemon -+ errStream.println(""[daemon client] daemon not found"") -+ } -+ catch (e: ConnectException) { -+ errStream.println(""[daemon client] cannot connect to registry: "" + (e.getCause()?.getMessage() ?: e.getMessage() ?: ""unknown exception"")) -+ // ignoring it - processing below -+ } -+ return null -+ } -+ -+ -+ private fun startDaemon(compilerId: CompilerId, daemonLaunchingOptions: DaemonLaunchingOptions, daemonOptions: DaemonOptions, errStream: PrintStream) { -+ val javaExecutable = listOf(System.getProperty(""java.home""), ""bin"", ""java"").joinToString(File.separator) -+ // TODO: add some specific environment variables to the cp and may be command line, to allow some specific startup configs -+ val args = listOf(javaExecutable, -+ ""-cp"", compilerId.compilerClasspath.joinToString(File.pathSeparator)) + -+ daemonLaunchingOptions.jvmParams + -+ COMPILER_DAEMON_CLASS_FQN + -+ daemonOptions.asParams + -+ compilerId.asParams -+ errStream.println(""[daemon client] starting the daemon as: "" + args.joinToString("" "")) -+ val processBuilder = ProcessBuilder(args).redirectErrorStream(true) -+ // assuming daemon process is deaf and (mostly) silent, so do not handle streams -+ val daemon = processBuilder.start() -+ -+ val lock = ReentrantReadWriteLock() -+ var isEchoRead = false -+ -+ val stdouThread = -+ thread { -+ daemon.getInputStream() -+ .reader() -+ .forEachLine { -+ if (daemonOptions.startEcho.isNotEmpty() && it.contains(daemonOptions.startEcho)) -+ lock.write { isEchoRead = true; return@forEachLine } -+ errStream.println(""[daemon] "" + it) -+ } -+ } -+ try { -+ // trying to wait for process -+ if (daemonOptions.startEcho.isNotEmpty()) { -+ errStream.println(""[daemon client] waiting for daemon to respond"") -+ var waitMillis: Long = DAEMON_STARTUP_TIMEOUT_MS / DAEMON_STARTUP_CHECK_INTERVAL_MS -+ while (waitMillis-- > 0) { -+ Thread.sleep(DAEMON_STARTUP_CHECK_INTERVAL_MS) -+ if (!daemon.isAlive() || lock.read { isEchoRead } == true) break; -+ } -+ if (!daemon.isAlive()) -+ throw Exception(""Daemon terminated unexpectedly"") -+ if (lock.read { isEchoRead } == false) -+ throw Exception(""Unable to get response from daemon in $DAEMON_STARTUP_TIMEOUT_MS ms"") -+ } -+ else -+ // without startEcho defined waiting for max timeout -+ Thread.sleep(DAEMON_STARTUP_TIMEOUT_MS) -+ } -+ finally { -+ // assuming that all important output is already done, the rest should be routed to the log by the daemon itself -+ if (stdouThread.isAlive) -+ // TODO: find better method to stop the thread, but seems it will require asynchronous consuming of the stream -+ lock.write { stdouThread.stop() } -+ } -+ } -+ -+ public fun checkCompilerId(compiler: CompileService, localId: CompilerId, errStream: PrintStream): Boolean { -+ val remoteId = compiler.getCompilerId() -+ errStream.println(""[daemon client] remoteId = "" + remoteId.toString()) -+ errStream.println(""[daemon client] localId = "" + localId.toString()) -+ return (localId.compilerVersion.isEmpty() || localId.compilerVersion == remoteId.compilerVersion) && -+ (localId.compilerClasspath.all { remoteId.compilerClasspath.contains(it) }) && -+ (localId.compilerDigest.isEmpty() || remoteId.compilerDigest.isEmpty() || localId.compilerDigest == remoteId.compilerDigest) -+ } -+ -+ public fun connectToCompileService(compilerId: CompilerId, daemonLaunchingOptions: DaemonLaunchingOptions, daemonOptions: DaemonOptions, errStream: PrintStream, autostart: Boolean = true, checkId: Boolean = true): CompileService? { -+ val service = connectToService(compilerId, daemonOptions, errStream) -+ if (service != null) { -+ if (!checkId || checkCompilerId(service, compilerId, errStream)) { -+ errStream.println(""[daemon client] found the suitable daemon"") -+ return service -+ } -+ errStream.println(""[daemon client] compiler identity don't match: "" + compilerId.asParams.joinToString("" "")) -+ if (!autostart) return null; -+ errStream.println(""[daemon client] shutdown the daemon"") -+ service.shutdown() -+ // TODO: find more reliable way -+ Thread.sleep(1000) -+ errStream.println(""[daemon client] daemon shut down correctly, restarting"") -+ } -+ else { -+ if (!autostart) return null; -+ else errStream.println(""[daemon client] cannot connect to Compile Daemon, trying to start"") -+ } -+ -+ startDaemon(compilerId, daemonLaunchingOptions, daemonOptions, errStream) -+ errStream.println(""[daemon client] daemon started, trying to connect"") -+ return connectToService(compilerId, daemonOptions, errStream) -+ } -+ -+ public fun shutdownCompileService(daemonOptions: DaemonOptions): Unit { -+ KotlinCompilerClient.connectToCompileService(CompilerId(), DaemonLaunchingOptions(), daemonOptions, System.out, autostart = false, checkId = false) -+ ?.shutdown() -+ } -+ -+ public fun shutdownCompileService(): Unit { -+ shutdownCompileService(DaemonOptions()) -+ } -+ -+ public fun compile(compiler: CompileService, args: Array, out: OutputStream): Int { -+ -+ val outStrm = RemoteOutputStreamServer(out) -+ try { -+ return compiler.remoteCompile(args, outStrm, CompileService.OutputFormat.PLAIN) -+ } -+ finally { -+ outStrm.disconnect() -+ } -+ } -+ -+ public fun incrementalCompile(compiler: CompileService, args: Array, caches: Map, out: OutputStream): Int { -+ -+ val outStrm = RemoteOutputStreamServer(out) -+ val cacheServers = hashMapOf() -+ try { -+ caches.forEach { cacheServers.put( it.getKey(), RemoteIncrementalCacheServer( it.getValue())) }","`mapValues()` -","This isn't related to this PR, but there is a typo her" -231,"@@ -0,0 +1,276 @@ -+/* -+ * 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.rmi.kotlinr -+ -+import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache -+import org.jetbrains.kotlin.rmi.* -+import java.io.File -+import java.io.OutputStream -+import java.io.PrintStream -+import java.rmi.ConnectException -+import java.rmi.Remote -+import java.rmi.registry.LocateRegistry -+import java.util.concurrent.TimeUnit -+import java.util.concurrent.locks.ReentrantReadWriteLock -+import kotlin.concurrent.read -+import kotlin.concurrent.thread -+import kotlin.concurrent.write -+import kotlin.platform.platformStatic -+ -+fun Process.isAlive() = -+ try { -+ this.exitValue() -+ false -+ } -+ catch (e: IllegalThreadStateException) { -+ true -+ } -+ -+public class KotlinCompilerClient { -+ -+ companion object { -+ -+ val DAEMON_STARTUP_TIMEOUT_MS = 10000L -+ val DAEMON_STARTUP_CHECK_INTERVAL_MS = 100L -+ -+ private fun connectToService(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): CompileService? { -+ -+ val compilerObj = connectToDaemon(compilerId, daemonOptions, errStream) ?: return null // no registry - no daemon running -+ return compilerObj as? CompileService ?: -+ throw ClassCastException(""Unable to cast compiler service, actual class received: ${compilerObj.javaClass}"") -+ } -+ -+ private fun connectToDaemon(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): Remote? { -+ try { -+ val daemon = LocateRegistry.getRegistry(""localhost"", daemonOptions.port) -+ ?.lookup(COMPILER_SERVICE_RMI_NAME) -+ if (daemon != null) -+ return daemon -+ errStream.println(""[daemon client] daemon not found"") -+ } -+ catch (e: ConnectException) { -+ errStream.println(""[daemon client] cannot connect to registry: "" + (e.getCause()?.getMessage() ?: e.getMessage() ?: ""unknown exception"")) -+ // ignoring it - processing below -+ } -+ return null -+ } -+ -+ -+ private fun startDaemon(compilerId: CompilerId, daemonLaunchingOptions: DaemonLaunchingOptions, daemonOptions: DaemonOptions, errStream: PrintStream) { -+ val javaExecutable = listOf(System.getProperty(""java.home""), ""bin"", ""java"").joinToString(File.separator) -+ // TODO: add some specific environment variables to the cp and may be command line, to allow some specific startup configs -+ val args = listOf(javaExecutable, -+ ""-cp"", compilerId.compilerClasspath.joinToString(File.pathSeparator)) + -+ daemonLaunchingOptions.jvmParams + -+ COMPILER_DAEMON_CLASS_FQN + -+ daemonOptions.asParams + -+ compilerId.asParams -+ errStream.println(""[daemon client] starting the daemon as: "" + args.joinToString("" "")) -+ val processBuilder = ProcessBuilder(args).redirectErrorStream(true) -+ // assuming daemon process is deaf and (mostly) silent, so do not handle streams -+ val daemon = processBuilder.start() -+ -+ val lock = ReentrantReadWriteLock() -+ var isEchoRead = false -+ -+ val stdouThread = -+ thread { -+ daemon.getInputStream() -+ .reader() -+ .forEachLine { -+ if (daemonOptions.startEcho.isNotEmpty() && it.contains(daemonOptions.startEcho)) -+ lock.write { isEchoRead = true; return@forEachLine } -+ errStream.println(""[daemon] "" + it) -+ } -+ } -+ try { -+ // trying to wait for process -+ if (daemonOptions.startEcho.isNotEmpty()) { -+ errStream.println(""[daemon client] waiting for daemon to respond"") -+ var waitMillis: Long = DAEMON_STARTUP_TIMEOUT_MS / DAEMON_STARTUP_CHECK_INTERVAL_MS -+ while (waitMillis-- > 0) { -+ Thread.sleep(DAEMON_STARTUP_CHECK_INTERVAL_MS) -+ if (!daemon.isAlive() || lock.read { isEchoRead } == true) break; -+ } -+ if (!daemon.isAlive()) -+ throw Exception(""Daemon terminated unexpectedly"") -+ if (lock.read { isEchoRead } == false) -+ throw Exception(""Unable to get response from daemon in $DAEMON_STARTUP_TIMEOUT_MS ms"") -+ } -+ else -+ // without startEcho defined waiting for max timeout -+ Thread.sleep(DAEMON_STARTUP_TIMEOUT_MS) -+ } -+ finally { -+ // assuming that all important output is already done, the rest should be routed to the log by the daemon itself -+ if (stdouThread.isAlive) -+ // TODO: find better method to stop the thread, but seems it will require asynchronous consuming of the stream -+ lock.write { stdouThread.stop() } -+ } -+ } -+ -+ public fun checkCompilerId(compiler: CompileService, localId: CompilerId, errStream: PrintStream): Boolean { -+ val remoteId = compiler.getCompilerId() -+ errStream.println(""[daemon client] remoteId = "" + remoteId.toString()) -+ errStream.println(""[daemon client] localId = "" + localId.toString()) -+ return (localId.compilerVersion.isEmpty() || localId.compilerVersion == remoteId.compilerVersion) && -+ (localId.compilerClasspath.all { remoteId.compilerClasspath.contains(it) }) && -+ (localId.compilerDigest.isEmpty() || remoteId.compilerDigest.isEmpty() || localId.compilerDigest == remoteId.compilerDigest) -+ } -+ -+ public fun connectToCompileService(compilerId: CompilerId, daemonLaunchingOptions: DaemonLaunchingOptions, daemonOptions: DaemonOptions, errStream: PrintStream, autostart: Boolean = true, checkId: Boolean = true): CompileService? { -+ val service = connectToService(compilerId, daemonOptions, errStream) -+ if (service != null) { -+ if (!checkId || checkCompilerId(service, compilerId, errStream)) { -+ errStream.println(""[daemon client] found the suitable daemon"") -+ return service -+ } -+ errStream.println(""[daemon client] compiler identity don't match: "" + compilerId.asParams.joinToString("" "")) -+ if (!autostart) return null; -+ errStream.println(""[daemon client] shutdown the daemon"") -+ service.shutdown() -+ // TODO: find more reliable way -+ Thread.sleep(1000) -+ errStream.println(""[daemon client] daemon shut down correctly, restarting"") -+ } -+ else { -+ if (!autostart) return null; -+ else errStream.println(""[daemon client] cannot connect to Compile Daemon, trying to start"") -+ } -+ -+ startDaemon(compilerId, daemonLaunchingOptions, daemonOptions, errStream) -+ errStream.println(""[daemon client] daemon started, trying to connect"") -+ return connectToService(compilerId, daemonOptions, errStream) -+ } -+ -+ public fun shutdownCompileService(daemonOptions: DaemonOptions): Unit { -+ KotlinCompilerClient.connectToCompileService(CompilerId(), DaemonLaunchingOptions(), daemonOptions, System.out, autostart = false, checkId = false) -+ ?.shutdown() -+ } -+ -+ public fun shutdownCompileService(): Unit { -+ shutdownCompileService(DaemonOptions()) -+ } -+ -+ public fun compile(compiler: CompileService, args: Array, out: OutputStream): Int { -+ -+ val outStrm = RemoteOutputStreamServer(out) -+ try { -+ return compiler.remoteCompile(args, outStrm, CompileService.OutputFormat.PLAIN) -+ } -+ finally { -+ outStrm.disconnect() -+ } -+ } -+ -+ public fun incrementalCompile(compiler: CompileService, args: Array, caches: Map, out: OutputStream): Int { -+ -+ val outStrm = RemoteOutputStreamServer(out) -+ val cacheServers = hashMapOf() -+ try { -+ caches.forEach { cacheServers.put( it.getKey(), RemoteIncrementalCacheServer( it.getValue())) } -+ return compiler.remoteIncrementalCompile(args, cacheServers, outStrm, CompileService.OutputFormat.XML) -+ } -+ finally { -+ cacheServers.forEach { it.getValue().disconnect() } -+ outStrm.disconnect() -+ } -+ } -+ -+ public fun isDaemonEnabled(): Boolean = System.getProperty(COMPILE_DAEMON_ENABLED_PROPERTY) != null -+ -+ public fun configureDaemonLaunchingOptions(opts: DaemonLaunchingOptions) { -+ System.getProperty(COMPILE_DAEMON_JVM_OPTIONS_PROPERTY)?.let { -+ // TODO: find better way to pass and parse jvm options for daemon -+ opts.jvmParams = it.split(""##"") -+ } -+ } -+ -+ data class ClientOptions( -+ public var stop: Boolean = false -+ ) :CmdlineParams { -+ override val asParams: Iterable -+ get() = -+ if (stop) listOf(""stop"") else listOf() -+ -+ override val parsers: List> -+ get() = listOf( BoolPropParser(this, ::stop)) -+ } -+ -+ platformStatic public fun main(vararg args: String) { -+ val compilerId = CompilerId() -+ val daemonOptions = DaemonOptions() -+ val daemonLaunchingOptions = DaemonLaunchingOptions() -+ val clientOptions = ClientOptions() -+ val filteredArgs = args.asIterable().propParseFilter(compilerId, daemonOptions, daemonLaunchingOptions, clientOptions) -+ -+ if (!clientOptions.stop) { -+ if (compilerId.compilerClasspath.none()) { -+ // attempt to find compiler to use -+ println(""compiler wasn't explicitly specified, attempt to find appropriate jar"") -+ System.getProperty(""java.class.path"") -+ ?.split(File.pathSeparator) -+ ?.map { File(it).parent } -+ ?.distinct() -+ ?.map { -+ it?.walk() -+ ?.firstOrNull { it.getName().equals(COMPILER_JAR_NAME, ignoreCase = true) } -+ } -+ ?.filterNotNull() -+ ?.firstOrNull() -+ ?.let { compilerId.compilerClasspath = listOf(it.absolutePath) } -+ } -+ if (compilerId.compilerClasspath.none()) -+ throw IllegalArgumentException(""Cannot find compiler jar"") -+ else -+ println(""desired compiler classpath: "" + compilerId.compilerClasspath.joinToString(File.pathSeparator)) -+ -+ compilerId.updateDigest() -+ } -+ -+ connectToCompileService(compilerId, daemonLaunchingOptions, daemonOptions, System.out, autostart = !clientOptions.stop, checkId = !clientOptions.stop)?.let { -+ when { -+ clientOptions.stop -> { -+ println(""Shutdown the daemon"") -+ it.shutdown() -+ println(""Daemon shut down successfully"") -+ } -+ else -> { -+ println(""Executing daemon compilation with args: "" + filteredArgs.joinToString("" "")) -+ val outStrm = RemoteOutputStreamServer(System.out) -+ try { -+ val memBefore = it.getUsedMemory() / 1024 -+ val startTime = System.nanoTime() -+ val res = it.remoteCompile(filteredArgs.toArrayList().toTypedArray(), outStrm, CompileService.OutputFormat.PLAIN) -+ val endTime = System.nanoTime() -+ println(""Compilation result code: $res"") -+ val memAfter = it.getUsedMemory() / 1024 -+ println(""Compilation time: "" + TimeUnit.NANOSECONDS.toMillis(endTime - startTime) + "" ms"") -+ println(""Used memory $memAfter (${""%+d"".format(memAfter - memBefore)} kb)"") -+ } -+ finally { -+ outStrm.disconnect() -+ } -+ } -+ } -+ } -+ ?: if (clientOptions.stop) println(""No daemon found to shut down"")","I think that such dangling `?:` are fairly hard to understand. -","This isn't related to this PR, but there is a typo her" -232,"@@ -0,0 +1,278 @@ -+/* -+ * 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.idea.caches -+ -+import com.intellij.openapi.projectRoots.Sdk -+import com.intellij.psi.PsiField -+import com.intellij.psi.PsiMethod -+import com.intellij.psi.PsiModifier -+import com.intellij.psi.search.GlobalSearchScope -+import com.intellij.psi.search.PsiShortNamesCache -+import com.sun.tools.javac.util.Convert.shortName -+import junit.framework.TestCase -+import org.jetbrains.kotlin.asJava.elements.KtLightField -+import org.jetbrains.kotlin.asJava.elements.KtLightMethod -+import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName -+import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil -+import org.jetbrains.kotlin.idea.test.KotlinCodeInsightTestCase -+import org.jetbrains.kotlin.idea.test.PluginTestCaseBase -+import org.jetbrains.kotlin.load.java.JvmAbi -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.psi.KtProperty -+import org.jetbrains.kotlin.test.KotlinTestUtils -+ -+ -+/**","Please remove this comment -",Could you please move this package to the new package? -233,"@@ -0,0 +1,278 @@ -+package kotlin.collections -+ -+/** -+ * Represents a source of elements with a [keyOf] function, which can be applied to each element to get its key. -+ * -+ * A [Grouping] structure serves as an intermediate step in group-and-fold operations: -+ * they group elements by their keys and then fold each group with some aggregating operation. -+ * -+ * It is created by attaching `keySelector: (T) -> K` function to a source of elements. -+ * To get an instance of [Grouping] use one of `groupingBy` extension functions: -+ * - [Iterable.groupingBy] -+ * - [Sequence.groupingBy] -+ * - [Array.groupingBy] -+ * - [CharSequence.groupingBy] -+ * -+ * For the list of group-and-fold operations available, see the [extension functions](#extension-functions) for `Grouping`. -+ */ -+@SinceKotlin(""1.1"") -+public interface Grouping { -+ /** Returns an [Iterator] which iterates through the elements of the source. */ -+ fun elementIterator(): Iterator","@{18f15b45-4413-42a3-82e7-d057983d1e65,Ilya Gorbunov} `sourceIterator()` or just `source()` ? Need to be documented: whether it creates iterator every time or keep the same instance. If the behaviour is undefined we have to notice it here.",I'm not sure this is worth mentioning in the commit me -234,"@@ -0,0 +1,278 @@ -+package kotlin.collections -+ -+/** -+ * Represents a source of elements with a [keyOf] function, which can be applied to each element to get its key. -+ * -+ * A [Grouping] structure serves as an intermediate step in group-and-fold operations: -+ * they group elements by their keys and then fold each group with some aggregating operation. -+ * -+ * It is created by attaching `keySelector: (T) -> K` function to a source of elements. -+ * To get an instance of [Grouping] use one of `groupingBy` extension functions: -+ * - [Iterable.groupingBy] -+ * - [Sequence.groupingBy] -+ * - [Array.groupingBy] -+ * - [CharSequence.groupingBy] -+ * -+ * For the list of group-and-fold operations available, see the [extension functions](#extension-functions) for `Grouping`. -+ */ -+@SinceKotlin(""1.1"") -+public interface Grouping { -+ /** Returns an [Iterator] which iterates through the elements of the source. */ -+ fun elementIterator(): Iterator -+ /** Extracts the key of an [element]. */ -+ fun keyOf(element: T): K -+} -+ -+/** -+ * Groups elements from the [Grouping] source by key and aggregates elements of each group with the specified [operation]. -+ * -+ * The key for each element is provided by the [Grouping.keyOf] function. -+ * -+ * @param operation function is invoked on each element with the following parameters: -+ * - `key`: the key of a group this element belongs to; -+ * - `value`: the current value of the accumulator of a group, can be `null` if it's first `element` encountered in the group; -+ * - `element`: the element from the source being aggregated; -+ * - `first`: indicates whether it's first `element` encountered in the group. -+ * -+ * @return a [Map] associating the key of each group with the result of aggregation of the group elements. -+ */ -+@SinceKotlin(""1.1"") -+public inline fun Grouping.aggregate( -+ operation: (key: K, value: R?, element: T, first: Boolean) -> R -+): Map { -+ val result = mutableMapOf()",Why don't we use `aggregateTo` instead?,Since the return type is `Object` (it's not an `Iterat -235,"@@ -0,0 +1,278 @@ -+package kotlin.collections -+ -+/** -+ * Represents a source of elements with a [keyOf] function, which can be applied to each element to get its key. -+ * -+ * A [Grouping] structure serves as an intermediate step in group-and-fold operations: -+ * they group elements by their keys and then fold each group with some aggregating operation. -+ * -+ * It is created by attaching `keySelector: (T) -> K` function to a source of elements. -+ * To get an instance of [Grouping] use one of `groupingBy` extension functions: -+ * - [Iterable.groupingBy] -+ * - [Sequence.groupingBy] -+ * - [Array.groupingBy] -+ * - [CharSequence.groupingBy] -+ * -+ * For the list of group-and-fold operations available, see the [extension functions](#extension-functions) for `Grouping`. -+ */ -+@SinceKotlin(""1.1"") -+public interface Grouping { -+ /** Returns an [Iterator] which iterates through the elements of the source. */ -+ fun elementIterator(): Iterator -+ /** Extracts the key of an [element]. */ -+ fun keyOf(element: T): K -+} -+ -+/** -+ * Groups elements from the [Grouping] source by key and aggregates elements of each group with the specified [operation]. -+ * -+ * The key for each element is provided by the [Grouping.keyOf] function. -+ * -+ * @param operation function is invoked on each element with the following parameters: -+ * - `key`: the key of a group this element belongs to; -+ * - `value`: the current value of the accumulator of a group, can be `null` if it's first `element` encountered in the group; -+ * - `element`: the element from the source being aggregated; -+ * - `first`: indicates whether it's first `element` encountered in the group. -+ * -+ * @return a [Map] associating the key of each group with the result of aggregation of the group elements. -+ */ -+@SinceKotlin(""1.1"") -+public inline fun Grouping.aggregate( -+ operation: (key: K, value: R?, element: T, first: Boolean) -> R -+): Map { -+ val result = mutableMapOf() -+ for (e in this.elementIterator()) { -+ val key = keyOf(e) -+ val value = result[key] -+ result[key] = operation(key, value, e, value == null && !result.containsKey(key)) -+ } -+ return result -+} -+ -+/** -+ * Groups elements from the [Grouping] source by key and aggregates elements of each group with the specified [operation] -+ * to the given [destination] map. -+ * -+ * The key for each element is provided by the [Grouping.keyOf] function. -+ * -+ * @param operation a function that is invoked on each element with the following parameters: -+ * - `key`: the key of a group this element belongs to; -+ * - `accumulator`: the current value of the accumulator of the group, can be `null` if it's first `element` encountered in the group; -+ * - `element`: the element from the source being aggregated; -+ * - `first`: indicates whether it's first `element` encountered in the group. -+ * -+ * If the [destination] map already has a value corresponding to some key, -+ * then the elements being aggregated for that key are never considered as `first`. -+ * -+ * @return the [destination] map associating the key of each group with the result of aggregation of the group elements. -+ */ -+@SinceKotlin(""1.1"") -+public inline fun > Grouping.aggregateTo( -+ destination: M, -+ operation: (key: K, accumulator: R?, element: T, first: Boolean) -> R","`value` vs `accumulator`, `v` vs `acc`",Since the return type is `Object` (it's not an `Iterat -236,"@@ -0,0 +1,278 @@ -+package kotlin.collections -+ -+/** -+ * Represents a source of elements with a [keyOf] function, which can be applied to each element to get its key. -+ * -+ * A [Grouping] structure serves as an intermediate step in group-and-fold operations: -+ * they group elements by their keys and then fold each group with some aggregating operation. -+ * -+ * It is created by attaching `keySelector: (T) -> K` function to a source of elements. -+ * To get an instance of [Grouping] use one of `groupingBy` extension functions: -+ * - [Iterable.groupingBy] -+ * - [Sequence.groupingBy] -+ * - [Array.groupingBy] -+ * - [CharSequence.groupingBy] -+ * -+ * For the list of group-and-fold operations available, see the [extension functions](#extension-functions) for `Grouping`. -+ */ -+@SinceKotlin(""1.1"") -+public interface Grouping { -+ /** Returns an [Iterator] which iterates through the elements of the source. */ -+ fun elementIterator(): Iterator -+ /** Extracts the key of an [element]. */ -+ fun keyOf(element: T): K -+} -+ -+/** -+ * Groups elements from the [Grouping] source by key and aggregates elements of each group with the specified [operation]. -+ * -+ * The key for each element is provided by the [Grouping.keyOf] function. -+ * -+ * @param operation function is invoked on each element with the following parameters: -+ * - `key`: the key of a group this element belongs to; -+ * - `value`: the current value of the accumulator of a group, can be `null` if it's first `element` encountered in the group; -+ * - `element`: the element from the source being aggregated; -+ * - `first`: indicates whether it's first `element` encountered in the group. -+ * -+ * @return a [Map] associating the key of each group with the result of aggregation of the group elements. -+ */ -+@SinceKotlin(""1.1"") -+public inline fun Grouping.aggregate( -+ operation: (key: K, value: R?, element: T, first: Boolean) -> R -+): Map { -+ val result = mutableMapOf() -+ for (e in this.elementIterator()) { -+ val key = keyOf(e) -+ val value = result[key] -+ result[key] = operation(key, value, e, value == null && !result.containsKey(key)) -+ } -+ return result -+} -+ -+/** -+ * Groups elements from the [Grouping] source by key and aggregates elements of each group with the specified [operation] -+ * to the given [destination] map. -+ * -+ * The key for each element is provided by the [Grouping.keyOf] function. -+ * -+ * @param operation a function that is invoked on each element with the following parameters: -+ * - `key`: the key of a group this element belongs to; -+ * - `accumulator`: the current value of the accumulator of the group, can be `null` if it's first `element` encountered in the group; -+ * - `element`: the element from the source being aggregated; -+ * - `first`: indicates whether it's first `element` encountered in the group. -+ * -+ * If the [destination] map already has a value corresponding to some key, -+ * then the elements being aggregated for that key are never considered as `first`. -+ * -+ * @return the [destination] map associating the key of each group with the result of aggregation of the group elements. -+ */ -+@SinceKotlin(""1.1"") -+public inline fun > Grouping.aggregateTo( -+ destination: M, -+ operation: (key: K, accumulator: R?, element: T, first: Boolean) -> R -+): M { -+ for (e in this.elementIterator()) { -+ val key = keyOf(e) -+ val acc = destination[key] -+ destination[key] = operation(key, acc, e, acc == null && !destination.containsKey(key)) -+ } -+ return destination -+} -+ -+/** -+ * Groups elements from the [Grouping] source by key and accumulates elements of each group with the specified [operation] -+ * starting with an initial value of accumulator provided by the [initialValueSelector] function. -+ * -+ * @param initialValueSelector a function that provides an initial value of accumulator for an each group. -+ * It's invoked with parameters: -+ * - `key`: the key of a group; -+ * - `element`: the first element being encountered in that group. -+ * -+ * @param operation a function that is invoked on each element with the following parameters: -+ * - `key`: the key of a group this element belongs to; -+ * - `accumulator`: the current value of the accumulator of the group; -+ * - `element`: the element from the source being accumulated. -+ * -+ * @return a [Map] associating the key of each group with the result of accumulating the group elements. -+ */ -+@SinceKotlin(""1.1"") -+public inline fun Grouping.fold( -+ initialValueSelector: (key: K, element: T) -> R, -+ operation: (key: K, accumulator: R, element: T) -> R -+): Map = -+ aggregate { key, value, e, first -> operation(key, if (first) initialValueSelector(key, e) else value as R, e) } -+ -+/** -+ * Groups elements from the [Grouping] source by key and accumulates elements of each group with the specified [operation] -+ * starting with an initial value of accumulator provided by the [initialValueSelector] function -+ * to the given [destination] map. -+ * -+ * @param initialValueSelector a function that provides an initial value of accumulator for an each group. -+ * It's invoked with parameters: -+ * - `key`: the key of a group; -+ * - `element`: the first element being encountered in that group. -+ * -+ * If the [destination] map already has a value corresponding to some key, that value is used as an initial value of -+ * the accumulator for that group and the [initialValueSelector] function is not called for that group. -+ * -+ * @param operation a function that is invoked on each element with the following parameters: -+ * - `key`: the key of a group this element belongs to; -+ * - `accumulator`: the current value of the accumulator of the group; -+ * - `element`: the element from the source being accumulated. -+ * -+ * @return the [destination] map associating the key of each group with the result of accumulating the group elements. -+ */ -+@SinceKotlin(""1.1"") -+public inline fun > Grouping.foldTo( -+ destination: M, -+ initialValueSelector: (key: K, element: T) -> R, -+ operation: (key: K, accumulator: R, element: T) -> R -+): M = -+ aggregateTo(destination) { key, value, e, first -> operation(key, if (first) initialValueSelector(key, e) else value as R, e) } -+ -+ -+/** -+ * Groups elements from the [Grouping] source by key and accumulates elements of each group with the specified [operation] -+ * starting with the [initialValue]. -+ * -+ * @param operation a function that is invoked on each element with the following parameters: -+ * - `accumulator`: the current value of the accumulator of the group; -+ * - `element`: the element from the source being accumulated. -+ * -+ * @return a [Map] associating the key of each group with the result of accumulating the group elements. -+ */ -+@SinceKotlin(""1.1"") -+public inline fun Grouping.fold( -+ initialValue: R, -+ operation: (accumulator: R, element: T) -> R -+): Map = -+ aggregate { k, v, e, first -> operation(if (first) initialValue else v as R, e) } -+ -+/** -+ * Groups elements from the [Grouping] source by key and accumulates elements of each group with the specified [operation] -+ * starting with the [initialValue] to the given [destination] map. -+ * -+ * If the [destination] map already has a value corresponding to the key of some group, -+ * that value is used as an initial value of the accumulator for that group. -+ * -+ * @param operation a function that is invoked on each element with the following parameters: -+ * - `accumulator`: the current value of the accumulator of the group; -+ * - `element`: the element from the source being accumulated. -+ * -+ * @return the [destination] map associating the key of each group with the result of accumulating the group elements. -+ */ -+@SinceKotlin(""1.1"") -+public inline fun > Grouping.foldTo( -+ destination: M, -+ initialValue: R, -+ operation: (accumulator: R, element: T) -> R -+): M = -+ aggregateTo(destination) { k, v, e, first -> operation(if (first) initialValue else v as R, e) } -+ -+ -+/** -+ * Groups elements from the [Grouping] source by key and accumulates elements of each group with the specified [operation] -+ * starting the first element in that group. -+ * -+ * @param operation a function that is invoked on each subsequent element of the group with the following parameters: -+ * - `key`: the key of a group this element belongs to; -+ * - `accumulator`: the current value of the accumulator of the group; -+ * - `element`: the element from the source being accumulated. -+ * -+ * @return a [Map] associating the key of each group with the result of accumulating the group elements. -+ */ -+@SinceKotlin(""1.1"") -+public inline fun Grouping.reduce( -+ operation: (key: K, accumulator: S, element: T) -> S -+): Map = -+ aggregate { key, value, e, first -> -+ if (first) e else operation(key, value as S, e) -+ } -+ -+/** -+ * Groups elements from the [Grouping] source by key and accumulates elements of each group with the specified [operation] -+ * starting the first element in that group to the given [destination] map. -+ * -+ * If the [destination] map already has a value corresponding to the key of some group, -+ * that value is used as an initial value of the accumulator for that group and the first element of that group is also -+ * subjected to the [operation]. -+ -+ * @param operation a function that is invoked on each subsequent element of the group with the following parameters: -+ * - `accumulator`: the current value of the accumulator of the group; -+ * - `element`: the element from the source being folded; -+ * -+ * @return the [destination] map associating the key of each group with the result of accumulating the group elements. -+ */ -+@SinceKotlin(""1.1"") -+public inline fun > Grouping.reduceTo( -+ destination: M, -+ operation: (key: K, accumulator: S, element: T) -> S -+): M = -+ aggregateTo(destination) { key, value, e, first -> -+ if (first) e else operation(key, value as S, e) -+ } -+ -+ -+/** -+ * Groups elements from the [Grouping] source by key and counts elements in each group. -+ * -+ * @return a [Map] associating the key of each group with the count of element in the group. -+ */ -+@SinceKotlin(""1.1"") -+@JvmVersion -+public fun Grouping.eachCount(): Map = -+ // fold(0) { acc, e -> acc + 1 } optimized for boxing -+ fold( -+ initialValueSelector = { k, e -> kotlin.jvm.internal.Ref.IntRef() }, -+ operation = { k, acc, e -> acc.apply { element += 1 } }) -+ .mapValues { it.value.element } -+ -+/** -+ * Groups elements from the [Grouping] source by key and counts elements in each group to the given [destination] map. -+ * -+ * @return the [destination] map associating the key of each group with the count of element in the group. -+ */ -+@SinceKotlin(""1.1"") -+public fun > Grouping.eachCountTo(destination: M): M = -+ foldTo(destination, 0) { acc, e -> acc + 1 } -+ -+/** -+ * Groups elements from the [Grouping] source by key and sums values provided by the [valueSelector] function for elements in each group. -+ * -+ * @return a [Map] associating the key of each group with the count of element in the group. -+ */ -+@SinceKotlin(""1.1"") -+@JvmVersion -+public inline fun Grouping.eachSumOf(valueSelector: (T) -> Int): Map = -+ // fold(0) { acc, e -> acc + valueSelector(e)} optimized for boxing -+ fold( -+ initialValueSelector = { k, e -> kotlin.jvm.internal.Ref.IntRef() }, -+ operation = { k, acc, e -> acc.apply { element += valueSelector(e) } }) -+ .mapValues { it.value.element }",as we already use internal API hack we could do even more: we can create replace `IntRef` to `Int` inplace and then do unchecked cast.,Since the return type is `Object` (it's not an `Iterat -237,"@@ -0,0 +1,28 @@ -+/* -+ * 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.components -+ -+import org.jetbrains.kotlin.descriptors.PropertyDescriptor -+import org.jetbrains.kotlin.load.java.components.JavaPropertyInitializerEvaluator -+import org.jetbrains.kotlin.load.java.structure.JavaField -+ -+class JavacJavaPropertyInitializerEvaluator : JavaPropertyInitializerEvaluator {",There is already `JavaPropertyInitializerEvaluator.DO_NOTHING` with the same functionality,"Could you make this a bit more specific, please? `org." -238,"@@ -0,0 +1,282 @@ -+package kotlin.collections -+ -+/** -+ * Represents a source of elements with a [keyOf] function, which can be applied to each element to get its key. -+ * -+ * A [Grouping] structure serves as an intermediate step in group-and-fold operations: -+ * they group elements by their keys and then fold each group with some aggregating operation. -+ * -+ * It is created by attaching `keySelector: (T) -> K` function to a source of elements. -+ * To get an instance of [Grouping] use one of `groupingBy` extension functions:","|`line 32`| -|---| -""a group"" -> ""the group"" here and below","Missing `.` at the end of the sentence (sorry, late to" -239,"@@ -0,0 +1,282 @@ -+package kotlin.collections -+ -+/** -+ * Represents a source of elements with a [keyOf] function, which can be applied to each element to get its key. -+ * -+ * A [Grouping] structure serves as an intermediate step in group-and-fold operations: -+ * they group elements by their keys and then fold each group with some aggregating operation. -+ * -+ * It is created by attaching `keySelector: (T) -> K` function to a source of elements. -+ * To get an instance of [Grouping] use one of `groupingBy` extension functions: -+ * - [Iterable.groupingBy] -+ * - [Sequence.groupingBy]","|`line 61`| -|---| -Any chance for some `@sample`'s?",Missing `.` at the end of the sentence. -240,"@@ -0,0 +1,285 @@ -+/* -+ * 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.editor -+ -+import com.intellij.codeInsight.editorActions.CopyPastePreProcessor -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.editor.RawText -+import com.intellij.openapi.project.Project -+import com.intellij.openapi.util.TextRange -+import com.intellij.openapi.util.text.LineTokenizer -+import com.intellij.openapi.util.text.StringUtil -+import com.intellij.psi.PsiDocumentManager -+import com.intellij.psi.PsiElement -+import com.intellij.psi.PsiFile -+import org.jetbrains.kotlin.idea.editor.fixers.range -+import org.jetbrains.kotlin.lexer.KotlinLexer -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.KtEscapeStringTemplateEntry -+import org.jetbrains.kotlin.psi.KtFile -+import org.jetbrains.kotlin.psi.KtStringTemplateEntry -+import org.jetbrains.kotlin.psi.KtStringTemplateExpression -+import org.jetbrains.kotlin.psi.psiUtil.endOffset -+import org.jetbrains.kotlin.psi.psiUtil.isSingleQuoted -+import org.jetbrains.kotlin.psi.psiUtil.startOffset -+import kotlin.coroutines.experimental.SequenceBuilder -+import kotlin.coroutines.experimental.buildIterator -+ -+private fun PsiElement.findContainingTemplate(): PsiElement { -+ val parent = this.parent -+ @Suppress(""IfThenToElvis"") -+ return if (parent is KtStringTemplateEntry) parent.parent else parent -+} -+ -+private fun PsiFile.getTemplateIfAtLiteral(offset: Int): KtStringTemplateExpression? { -+ val at = this.findElementAt(offset) ?: return null -+ return when (at.node?.elementType) {",Why not simply `at.getNonStrictParentOfType`()?,Why not `import org.jetbrains.kotlin.psi.Editor;`? -241,"@@ -0,0 +1,285 @@ -+/* -+ * 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.editor -+ -+import com.intellij.codeInsight.editorActions.CopyPastePreProcessor -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.editor.RawText -+import com.intellij.openapi.project.Project -+import com.intellij.openapi.util.TextRange -+import com.intellij.openapi.util.text.LineTokenizer -+import com.intellij.openapi.util.text.StringUtil -+import com.intellij.psi.PsiDocumentManager -+import com.intellij.psi.PsiElement -+import com.intellij.psi.PsiFile -+import org.jetbrains.kotlin.idea.editor.fixers.range -+import org.jetbrains.kotlin.lexer.KotlinLexer -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.KtEscapeStringTemplateEntry -+import org.jetbrains.kotlin.psi.KtFile -+import org.jetbrains.kotlin.psi.KtStringTemplateEntry -+import org.jetbrains.kotlin.psi.KtStringTemplateExpression -+import org.jetbrains.kotlin.psi.psiUtil.endOffset -+import org.jetbrains.kotlin.psi.psiUtil.isSingleQuoted -+import org.jetbrains.kotlin.psi.psiUtil.startOffset -+import kotlin.coroutines.experimental.SequenceBuilder -+import kotlin.coroutines.experimental.buildIterator -+ -+private fun PsiElement.findContainingTemplate(): PsiElement { -+ val parent = this.parent -+ @Suppress(""IfThenToElvis"") -+ return if (parent is KtStringTemplateEntry) parent.parent else parent -+} -+ -+private fun PsiFile.getTemplateIfAtLiteral(offset: Int): KtStringTemplateExpression? { -+ val at = this.findElementAt(offset) ?: return null -+ return when (at.node?.elementType) { -+ KtTokens.REGULAR_STRING_PART, KtTokens.ESCAPE_SEQUENCE, KtTokens.LONG_TEMPLATE_ENTRY_START, KtTokens.SHORT_TEMPLATE_ENTRY_START -> at.parent.parent as? KtStringTemplateExpression -+ KtTokens.CLOSING_QUOTE -> if (offset == at.startOffset) at.parent as? KtStringTemplateExpression else null -+ else -> null -+ -+ } -+} -+ -+ -+//Copied from StringLiteralCopyPasteProcessor to avoid erroneous inheritance -+private fun deduceBlockSelectionWidth(startOffsets: IntArray, endOffsets: IntArray, text: String): Int { -+ val fragmentCount = startOffsets.size -+ assert(fragmentCount > 0) -+ var totalLength = fragmentCount - 1 // number of line breaks inserted between fragments -+ for (i in 0..fragmentCount - 1) { -+ totalLength += endOffsets[i] - startOffsets[i] -+ } -+ if (totalLength < text.length && (text.length + 1) % fragmentCount == 0) { -+ return (text.length + 1) / fragmentCount - 1 -+ } -+ else { -+ return -1 -+ } -+} -+ -+class KotlinLiteralCopyPasteProcessor : CopyPastePreProcessor { -+ override fun preprocessOnCopy(file: PsiFile, startOffsets: IntArray, endOffsets: IntArray, text: String): String? { -+ if (file !is KtFile){ -+ return null -+ } -+ val buffer = StringBuilder() -+ var changed = false -+ val fileText = file.text -+ val deducedBlockSelectionWidth = deduceBlockSelectionWidth(startOffsets, endOffsets, text) -+ -+ for (i in startOffsets.indices) { -+ if (i > 0) { -+ buffer.append('\n') // LF is added for block selection -+ } -+ -+ val fileRange = TextRange(startOffsets[i], endOffsets[i]) -+ -+ var givenTextOffset = fileRange.startOffset -+ while (givenTextOffset < fileRange.endOffset) { -+ val element: PsiElement? = file.findElementAt(givenTextOffset) -+ if (element == null) { -+ buffer.append(fileText.substring(givenTextOffset, fileRange.endOffset)) -+ break -+ } -+ val elTp = element.node.elementType -+ if (elTp == KtTokens.ESCAPE_SEQUENCE && fileRange.contains(element.range) && !fileRange.contains(element.findContainingTemplate().range)) { -+ val tpEntry = element.parent as KtEscapeStringTemplateEntry -+ changed = true -+ buffer.append(tpEntry.unescapedValue) -+ givenTextOffset = element.endOffset -+ } -+ else if (elTp == KtTokens.SHORT_TEMPLATE_ENTRY_START || elTp == KtTokens.LONG_TEMPLATE_ENTRY_START) { -+ //Process inner templates without escaping -+ val tpEntry = element.parent -+ val inter = fileRange.intersection(tpEntry.range)!! -+ buffer.append(fileText.substring(inter.startOffset, inter.endOffset)) -+ givenTextOffset = inter.endOffset -+ } -+ else { -+ val inter = fileRange.intersection(element.range)!! -+ buffer.append(fileText.substring(inter.startOffset, inter.endOffset)) -+ givenTextOffset = inter.endOffset -+ } -+ -+ } -+ val blockSelectionPadding = deducedBlockSelectionWidth - fileRange.length -+ for (j in 0..blockSelectionPadding - 1) { -+ buffer.append(' ') -+ } -+ -+ } -+ -+ return if (changed) buffer.toString() else null -+ } -+ -+ override fun preprocessOnPaste(project: Project, file: PsiFile, editor: Editor, text: String, rawText: RawText?): String { -+ if (file !is KtFile){ -+ return text -+ } -+ PsiDocumentManager.getInstance(project).commitDocument(editor.document) -+ val selectionModel = editor.selectionModel -+ val beginTp = file.getTemplateIfAtLiteral(selectionModel.selectionStart) ?: return text -+ val endTp = file.getTemplateIfAtLiteral(selectionModel.selectionEnd) ?: return text -+ if (beginTp.isSingleQuoted() != endTp.isSingleQuoted()) { -+ return text -+ } -+ -+ -+ return if (beginTp.isSingleQuoted()) { -+ TemplateTokenizer(text).map { -+ when (it) { -+ is LiteralChunk -> StringUtil.escaper(true, ""\$\"""").`fun`(it.text)","I think that it's better to create a single `StringBuilder` to hold the entire preprocessed contents, and to use the overload of `escapeStringCharacters` that takes a `StringBuilder` as a parameter.",Why not `import org.jetbrains.kotlin.psi.Editor;`? -242,"@@ -0,0 +1,285 @@ -+/* -+ * 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.editor -+ -+import com.intellij.codeInsight.editorActions.CopyPastePreProcessor -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.editor.RawText -+import com.intellij.openapi.project.Project -+import com.intellij.openapi.util.TextRange -+import com.intellij.openapi.util.text.LineTokenizer -+import com.intellij.openapi.util.text.StringUtil -+import com.intellij.psi.PsiDocumentManager -+import com.intellij.psi.PsiElement -+import com.intellij.psi.PsiFile -+import org.jetbrains.kotlin.idea.editor.fixers.range -+import org.jetbrains.kotlin.lexer.KotlinLexer -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.KtEscapeStringTemplateEntry -+import org.jetbrains.kotlin.psi.KtFile -+import org.jetbrains.kotlin.psi.KtStringTemplateEntry -+import org.jetbrains.kotlin.psi.KtStringTemplateExpression -+import org.jetbrains.kotlin.psi.psiUtil.endOffset -+import org.jetbrains.kotlin.psi.psiUtil.isSingleQuoted -+import org.jetbrains.kotlin.psi.psiUtil.startOffset -+import kotlin.coroutines.experimental.SequenceBuilder -+import kotlin.coroutines.experimental.buildIterator -+ -+private fun PsiElement.findContainingTemplate(): PsiElement { -+ val parent = this.parent -+ @Suppress(""IfThenToElvis"") -+ return if (parent is KtStringTemplateEntry) parent.parent else parent -+} -+ -+private fun PsiFile.getTemplateIfAtLiteral(offset: Int): KtStringTemplateExpression? { -+ val at = this.findElementAt(offset) ?: return null -+ return when (at.node?.elementType) { -+ KtTokens.REGULAR_STRING_PART, KtTokens.ESCAPE_SEQUENCE, KtTokens.LONG_TEMPLATE_ENTRY_START, KtTokens.SHORT_TEMPLATE_ENTRY_START -> at.parent.parent as? KtStringTemplateExpression -+ KtTokens.CLOSING_QUOTE -> if (offset == at.startOffset) at.parent as? KtStringTemplateExpression else null -+ else -> null -+ -+ } -+} -+ -+ -+//Copied from StringLiteralCopyPasteProcessor to avoid erroneous inheritance -+private fun deduceBlockSelectionWidth(startOffsets: IntArray, endOffsets: IntArray, text: String): Int { -+ val fragmentCount = startOffsets.size -+ assert(fragmentCount > 0) -+ var totalLength = fragmentCount - 1 // number of line breaks inserted between fragments -+ for (i in 0..fragmentCount - 1) { -+ totalLength += endOffsets[i] - startOffsets[i] -+ } -+ if (totalLength < text.length && (text.length + 1) % fragmentCount == 0) { -+ return (text.length + 1) / fragmentCount - 1 -+ } -+ else { -+ return -1 -+ } -+} -+ -+class KotlinLiteralCopyPasteProcessor : CopyPastePreProcessor { -+ override fun preprocessOnCopy(file: PsiFile, startOffsets: IntArray, endOffsets: IntArray, text: String): String? { -+ if (file !is KtFile){ -+ return null -+ } -+ val buffer = StringBuilder() -+ var changed = false -+ val fileText = file.text -+ val deducedBlockSelectionWidth = deduceBlockSelectionWidth(startOffsets, endOffsets, text) -+ -+ for (i in startOffsets.indices) { -+ if (i > 0) { -+ buffer.append('\n') // LF is added for block selection -+ } -+ -+ val fileRange = TextRange(startOffsets[i], endOffsets[i]) -+ -+ var givenTextOffset = fileRange.startOffset -+ while (givenTextOffset < fileRange.endOffset) { -+ val element: PsiElement? = file.findElementAt(givenTextOffset) -+ if (element == null) { -+ buffer.append(fileText.substring(givenTextOffset, fileRange.endOffset)) -+ break -+ } -+ val elTp = element.node.elementType -+ if (elTp == KtTokens.ESCAPE_SEQUENCE && fileRange.contains(element.range) && !fileRange.contains(element.findContainingTemplate().range)) { -+ val tpEntry = element.parent as KtEscapeStringTemplateEntry -+ changed = true -+ buffer.append(tpEntry.unescapedValue) -+ givenTextOffset = element.endOffset -+ } -+ else if (elTp == KtTokens.SHORT_TEMPLATE_ENTRY_START || elTp == KtTokens.LONG_TEMPLATE_ENTRY_START) { -+ //Process inner templates without escaping -+ val tpEntry = element.parent -+ val inter = fileRange.intersection(tpEntry.range)!! -+ buffer.append(fileText.substring(inter.startOffset, inter.endOffset)) -+ givenTextOffset = inter.endOffset -+ } -+ else { -+ val inter = fileRange.intersection(element.range)!! -+ buffer.append(fileText.substring(inter.startOffset, inter.endOffset)) -+ givenTextOffset = inter.endOffset -+ } -+ -+ } -+ val blockSelectionPadding = deducedBlockSelectionWidth - fileRange.length -+ for (j in 0..blockSelectionPadding - 1) { -+ buffer.append(' ') -+ } -+ -+ } -+ -+ return if (changed) buffer.toString() else null -+ } -+ -+ override fun preprocessOnPaste(project: Project, file: PsiFile, editor: Editor, text: String, rawText: RawText?): String { -+ if (file !is KtFile){ -+ return text -+ } -+ PsiDocumentManager.getInstance(project).commitDocument(editor.document) -+ val selectionModel = editor.selectionModel -+ val beginTp = file.getTemplateIfAtLiteral(selectionModel.selectionStart) ?: return text -+ val endTp = file.getTemplateIfAtLiteral(selectionModel.selectionEnd) ?: return text -+ if (beginTp.isSingleQuoted() != endTp.isSingleQuoted()) { -+ return text -+ } -+ -+ -+ return if (beginTp.isSingleQuoted()) { -+ TemplateTokenizer(text).map { -+ when (it) { -+ is LiteralChunk -> StringUtil.escaper(true, ""\$\"""").`fun`(it.text) -+ is EntryChunk -> it.text -+ is NewLineChunk -> ""\\n\""+\n \"""" -+ -+ } -+ }.joinToString(separator = """") -+ } -+ else { -+ val tripleQuoteRe = Regex(""[\""]{3,}"") -+ TemplateTokenizer(text).map { chunk -> -+ when (chunk) { -+ is LiteralChunk -> chunk.text.replace(""\$"", ""\${'$'}"").let { escapedDollar -> -+ tripleQuoteRe.replace(escapedDollar) { ""\""\"""" + ""\${'\""'}"".repeat(it.value.count() - 2) } -+ } -+ -+ is EntryChunk -> chunk.text -+ is NewLineChunk -> ""\n"" -+ -+ } -+ }.joinToString(separator = """") -+ } -+",Please reformat the files to remove unnecessary blank lines.,Why not `import org.jetbrains.kotlin.psi.Editor;`? -243,"@@ -0,0 +1,285 @@ -+/* -+ * 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.editor -+ -+import com.intellij.codeInsight.editorActions.CopyPastePreProcessor -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.editor.RawText -+import com.intellij.openapi.project.Project -+import com.intellij.openapi.util.TextRange -+import com.intellij.openapi.util.text.LineTokenizer -+import com.intellij.openapi.util.text.StringUtil -+import com.intellij.psi.PsiDocumentManager -+import com.intellij.psi.PsiElement -+import com.intellij.psi.PsiFile -+import org.jetbrains.kotlin.idea.editor.fixers.range -+import org.jetbrains.kotlin.lexer.KotlinLexer -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.KtEscapeStringTemplateEntry -+import org.jetbrains.kotlin.psi.KtFile -+import org.jetbrains.kotlin.psi.KtStringTemplateEntry -+import org.jetbrains.kotlin.psi.KtStringTemplateExpression -+import org.jetbrains.kotlin.psi.psiUtil.endOffset -+import org.jetbrains.kotlin.psi.psiUtil.isSingleQuoted -+import org.jetbrains.kotlin.psi.psiUtil.startOffset -+import kotlin.coroutines.experimental.SequenceBuilder -+import kotlin.coroutines.experimental.buildIterator -+ -+private fun PsiElement.findContainingTemplate(): PsiElement { -+ val parent = this.parent -+ @Suppress(""IfThenToElvis"") -+ return if (parent is KtStringTemplateEntry) parent.parent else parent -+} -+ -+private fun PsiFile.getTemplateIfAtLiteral(offset: Int): KtStringTemplateExpression? { -+ val at = this.findElementAt(offset) ?: return null -+ return when (at.node?.elementType) { -+ KtTokens.REGULAR_STRING_PART, KtTokens.ESCAPE_SEQUENCE, KtTokens.LONG_TEMPLATE_ENTRY_START, KtTokens.SHORT_TEMPLATE_ENTRY_START -> at.parent.parent as? KtStringTemplateExpression -+ KtTokens.CLOSING_QUOTE -> if (offset == at.startOffset) at.parent as? KtStringTemplateExpression else null -+ else -> null -+ -+ } -+} -+ -+ -+//Copied from StringLiteralCopyPasteProcessor to avoid erroneous inheritance -+private fun deduceBlockSelectionWidth(startOffsets: IntArray, endOffsets: IntArray, text: String): Int { -+ val fragmentCount = startOffsets.size -+ assert(fragmentCount > 0) -+ var totalLength = fragmentCount - 1 // number of line breaks inserted between fragments -+ for (i in 0..fragmentCount - 1) { -+ totalLength += endOffsets[i] - startOffsets[i] -+ } -+ if (totalLength < text.length && (text.length + 1) % fragmentCount == 0) { -+ return (text.length + 1) / fragmentCount - 1 -+ } -+ else { -+ return -1 -+ } -+} -+ -+class KotlinLiteralCopyPasteProcessor : CopyPastePreProcessor { -+ override fun preprocessOnCopy(file: PsiFile, startOffsets: IntArray, endOffsets: IntArray, text: String): String? { -+ if (file !is KtFile){ -+ return null -+ } -+ val buffer = StringBuilder() -+ var changed = false -+ val fileText = file.text -+ val deducedBlockSelectionWidth = deduceBlockSelectionWidth(startOffsets, endOffsets, text) -+ -+ for (i in startOffsets.indices) { -+ if (i > 0) { -+ buffer.append('\n') // LF is added for block selection -+ } -+ -+ val fileRange = TextRange(startOffsets[i], endOffsets[i]) -+ -+ var givenTextOffset = fileRange.startOffset -+ while (givenTextOffset < fileRange.endOffset) { -+ val element: PsiElement? = file.findElementAt(givenTextOffset) -+ if (element == null) { -+ buffer.append(fileText.substring(givenTextOffset, fileRange.endOffset)) -+ break -+ } -+ val elTp = element.node.elementType -+ if (elTp == KtTokens.ESCAPE_SEQUENCE && fileRange.contains(element.range) && !fileRange.contains(element.findContainingTemplate().range)) { -+ val tpEntry = element.parent as KtEscapeStringTemplateEntry -+ changed = true -+ buffer.append(tpEntry.unescapedValue) -+ givenTextOffset = element.endOffset -+ } -+ else if (elTp == KtTokens.SHORT_TEMPLATE_ENTRY_START || elTp == KtTokens.LONG_TEMPLATE_ENTRY_START) { -+ //Process inner templates without escaping -+ val tpEntry = element.parent -+ val inter = fileRange.intersection(tpEntry.range)!! -+ buffer.append(fileText.substring(inter.startOffset, inter.endOffset)) -+ givenTextOffset = inter.endOffset -+ } -+ else { -+ val inter = fileRange.intersection(element.range)!! -+ buffer.append(fileText.substring(inter.startOffset, inter.endOffset)) -+ givenTextOffset = inter.endOffset -+ } -+ -+ } -+ val blockSelectionPadding = deducedBlockSelectionWidth - fileRange.length -+ for (j in 0..blockSelectionPadding - 1) { -+ buffer.append(' ') -+ } -+ -+ } -+ -+ return if (changed) buffer.toString() else null -+ } -+ -+ override fun preprocessOnPaste(project: Project, file: PsiFile, editor: Editor, text: String, rawText: RawText?): String { -+ if (file !is KtFile){ -+ return text -+ } -+ PsiDocumentManager.getInstance(project).commitDocument(editor.document) -+ val selectionModel = editor.selectionModel -+ val beginTp = file.getTemplateIfAtLiteral(selectionModel.selectionStart) ?: return text -+ val endTp = file.getTemplateIfAtLiteral(selectionModel.selectionEnd) ?: return text -+ if (beginTp.isSingleQuoted() != endTp.isSingleQuoted()) { -+ return text -+ } -+ -+ -+ return if (beginTp.isSingleQuoted()) { -+ TemplateTokenizer(text).map { -+ when (it) { -+ is LiteralChunk -> StringUtil.escaper(true, ""\$\"""").`fun`(it.text) -+ is EntryChunk -> it.text -+ is NewLineChunk -> ""\\n\""+\n \"""" -+ -+ } -+ }.joinToString(separator = """") -+ } -+ else { -+ val tripleQuoteRe = Regex(""[\""]{3,}"") -+ TemplateTokenizer(text).map { chunk -> -+ when (chunk) { -+ is LiteralChunk -> chunk.text.replace(""\$"", ""\${'$'}"").let { escapedDollar -> -+ tripleQuoteRe.replace(escapedDollar) { ""\""\"""" + ""\${'\""'}"".repeat(it.value.count() - 2) } -+ } -+ -+ is EntryChunk -> chunk.text -+ is NewLineChunk -> ""\n"" -+ -+ } -+ }.joinToString(separator = """") -+ } -+ -+ } -+ -+ -+} -+ -+private sealed class TemplateChunk -+private data class LiteralChunk(val text: String) : TemplateChunk() -+private data class EntryChunk(val text: String) : TemplateChunk() -+private class NewLineChunk : TemplateChunk()",Can be `object NewLineChunk`,Why not `import org.jetbrains.kotlin.psi.Editor;`? -244,"@@ -0,0 +1,285 @@ -+/* -+ * 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.editor -+ -+import com.intellij.codeInsight.editorActions.CopyPastePreProcessor -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.editor.RawText -+import com.intellij.openapi.project.Project -+import com.intellij.openapi.util.TextRange -+import com.intellij.openapi.util.text.LineTokenizer -+import com.intellij.openapi.util.text.StringUtil -+import com.intellij.psi.PsiDocumentManager -+import com.intellij.psi.PsiElement -+import com.intellij.psi.PsiFile -+import org.jetbrains.kotlin.idea.editor.fixers.range -+import org.jetbrains.kotlin.lexer.KotlinLexer -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.KtEscapeStringTemplateEntry -+import org.jetbrains.kotlin.psi.KtFile -+import org.jetbrains.kotlin.psi.KtStringTemplateEntry -+import org.jetbrains.kotlin.psi.KtStringTemplateExpression -+import org.jetbrains.kotlin.psi.psiUtil.endOffset -+import org.jetbrains.kotlin.psi.psiUtil.isSingleQuoted -+import org.jetbrains.kotlin.psi.psiUtil.startOffset -+import kotlin.coroutines.experimental.SequenceBuilder -+import kotlin.coroutines.experimental.buildIterator -+ -+private fun PsiElement.findContainingTemplate(): PsiElement { -+ val parent = this.parent -+ @Suppress(""IfThenToElvis"") -+ return if (parent is KtStringTemplateEntry) parent.parent else parent -+} -+ -+private fun PsiFile.getTemplateIfAtLiteral(offset: Int): KtStringTemplateExpression? { -+ val at = this.findElementAt(offset) ?: return null -+ return when (at.node?.elementType) { -+ KtTokens.REGULAR_STRING_PART, KtTokens.ESCAPE_SEQUENCE, KtTokens.LONG_TEMPLATE_ENTRY_START, KtTokens.SHORT_TEMPLATE_ENTRY_START -> at.parent.parent as? KtStringTemplateExpression -+ KtTokens.CLOSING_QUOTE -> if (offset == at.startOffset) at.parent as? KtStringTemplateExpression else null -+ else -> null -+ -+ } -+} -+ -+ -+//Copied from StringLiteralCopyPasteProcessor to avoid erroneous inheritance -+private fun deduceBlockSelectionWidth(startOffsets: IntArray, endOffsets: IntArray, text: String): Int { -+ val fragmentCount = startOffsets.size -+ assert(fragmentCount > 0) -+ var totalLength = fragmentCount - 1 // number of line breaks inserted between fragments -+ for (i in 0..fragmentCount - 1) { -+ totalLength += endOffsets[i] - startOffsets[i] -+ } -+ if (totalLength < text.length && (text.length + 1) % fragmentCount == 0) { -+ return (text.length + 1) / fragmentCount - 1 -+ } -+ else { -+ return -1 -+ } -+} -+ -+class KotlinLiteralCopyPasteProcessor : CopyPastePreProcessor { -+ override fun preprocessOnCopy(file: PsiFile, startOffsets: IntArray, endOffsets: IntArray, text: String): String? { -+ if (file !is KtFile){ -+ return null -+ } -+ val buffer = StringBuilder() -+ var changed = false -+ val fileText = file.text -+ val deducedBlockSelectionWidth = deduceBlockSelectionWidth(startOffsets, endOffsets, text) -+ -+ for (i in startOffsets.indices) { -+ if (i > 0) { -+ buffer.append('\n') // LF is added for block selection -+ } -+ -+ val fileRange = TextRange(startOffsets[i], endOffsets[i]) -+ -+ var givenTextOffset = fileRange.startOffset -+ while (givenTextOffset < fileRange.endOffset) { -+ val element: PsiElement? = file.findElementAt(givenTextOffset) -+ if (element == null) { -+ buffer.append(fileText.substring(givenTextOffset, fileRange.endOffset)) -+ break -+ } -+ val elTp = element.node.elementType -+ if (elTp == KtTokens.ESCAPE_SEQUENCE && fileRange.contains(element.range) && !fileRange.contains(element.findContainingTemplate().range)) { -+ val tpEntry = element.parent as KtEscapeStringTemplateEntry -+ changed = true -+ buffer.append(tpEntry.unescapedValue) -+ givenTextOffset = element.endOffset -+ } -+ else if (elTp == KtTokens.SHORT_TEMPLATE_ENTRY_START || elTp == KtTokens.LONG_TEMPLATE_ENTRY_START) { -+ //Process inner templates without escaping -+ val tpEntry = element.parent -+ val inter = fileRange.intersection(tpEntry.range)!! -+ buffer.append(fileText.substring(inter.startOffset, inter.endOffset)) -+ givenTextOffset = inter.endOffset -+ } -+ else { -+ val inter = fileRange.intersection(element.range)!! -+ buffer.append(fileText.substring(inter.startOffset, inter.endOffset)) -+ givenTextOffset = inter.endOffset -+ } -+ -+ } -+ val blockSelectionPadding = deducedBlockSelectionWidth - fileRange.length -+ for (j in 0..blockSelectionPadding - 1) { -+ buffer.append(' ') -+ } -+ -+ } -+ -+ return if (changed) buffer.toString() else null -+ } -+ -+ override fun preprocessOnPaste(project: Project, file: PsiFile, editor: Editor, text: String, rawText: RawText?): String { -+ if (file !is KtFile){ -+ return text -+ } -+ PsiDocumentManager.getInstance(project).commitDocument(editor.document) -+ val selectionModel = editor.selectionModel -+ val beginTp = file.getTemplateIfAtLiteral(selectionModel.selectionStart) ?: return text -+ val endTp = file.getTemplateIfAtLiteral(selectionModel.selectionEnd) ?: return text -+ if (beginTp.isSingleQuoted() != endTp.isSingleQuoted()) { -+ return text -+ } -+ -+ -+ return if (beginTp.isSingleQuoted()) { -+ TemplateTokenizer(text).map { -+ when (it) { -+ is LiteralChunk -> StringUtil.escaper(true, ""\$\"""").`fun`(it.text) -+ is EntryChunk -> it.text -+ is NewLineChunk -> ""\\n\""+\n \"""" -+ -+ } -+ }.joinToString(separator = """") -+ } -+ else { -+ val tripleQuoteRe = Regex(""[\""]{3,}"") -+ TemplateTokenizer(text).map { chunk -> -+ when (chunk) { -+ is LiteralChunk -> chunk.text.replace(""\$"", ""\${'$'}"").let { escapedDollar -> -+ tripleQuoteRe.replace(escapedDollar) { ""\""\"""" + ""\${'\""'}"".repeat(it.value.count() - 2) } -+ } -+ -+ is EntryChunk -> chunk.text -+ is NewLineChunk -> ""\n"" -+ -+ } -+ }.joinToString(separator = """") -+ } -+ -+ } -+ -+ -+} -+ -+private sealed class TemplateChunk -+private data class LiteralChunk(val text: String) : TemplateChunk() -+private data class EntryChunk(val text: String) : TemplateChunk() -+private class NewLineChunk : TemplateChunk() -+ -+private class TemplateTokenizer(private val inputString: String) : Sequence {","I think this naming is kind of confusing; a tokenizer is something that returns a sequence, not something that is a sequence. I'd call it `TemplateTokenSequence`",Why not `import org.jetbrains.kotlin.psi.Editor;`? -245,"@@ -0,0 +1,285 @@ -+/* -+ * 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.editor -+ -+import com.intellij.codeInsight.editorActions.CopyPastePreProcessor -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.editor.RawText -+import com.intellij.openapi.project.Project -+import com.intellij.openapi.util.TextRange -+import com.intellij.openapi.util.text.LineTokenizer -+import com.intellij.openapi.util.text.StringUtil -+import com.intellij.psi.PsiDocumentManager -+import com.intellij.psi.PsiElement -+import com.intellij.psi.PsiFile -+import org.jetbrains.kotlin.idea.editor.fixers.range -+import org.jetbrains.kotlin.lexer.KotlinLexer -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.KtEscapeStringTemplateEntry -+import org.jetbrains.kotlin.psi.KtFile -+import org.jetbrains.kotlin.psi.KtStringTemplateEntry -+import org.jetbrains.kotlin.psi.KtStringTemplateExpression -+import org.jetbrains.kotlin.psi.psiUtil.endOffset -+import org.jetbrains.kotlin.psi.psiUtil.isSingleQuoted -+import org.jetbrains.kotlin.psi.psiUtil.startOffset -+import kotlin.coroutines.experimental.SequenceBuilder -+import kotlin.coroutines.experimental.buildIterator -+ -+private fun PsiElement.findContainingTemplate(): PsiElement { -+ val parent = this.parent -+ @Suppress(""IfThenToElvis"") -+ return if (parent is KtStringTemplateEntry) parent.parent else parent -+} -+ -+private fun PsiFile.getTemplateIfAtLiteral(offset: Int): KtStringTemplateExpression? { -+ val at = this.findElementAt(offset) ?: return null -+ return when (at.node?.elementType) { -+ KtTokens.REGULAR_STRING_PART, KtTokens.ESCAPE_SEQUENCE, KtTokens.LONG_TEMPLATE_ENTRY_START, KtTokens.SHORT_TEMPLATE_ENTRY_START -> at.parent.parent as? KtStringTemplateExpression -+ KtTokens.CLOSING_QUOTE -> if (offset == at.startOffset) at.parent as? KtStringTemplateExpression else null -+ else -> null -+ -+ } -+} -+ -+ -+//Copied from StringLiteralCopyPasteProcessor to avoid erroneous inheritance -+private fun deduceBlockSelectionWidth(startOffsets: IntArray, endOffsets: IntArray, text: String): Int { -+ val fragmentCount = startOffsets.size -+ assert(fragmentCount > 0) -+ var totalLength = fragmentCount - 1 // number of line breaks inserted between fragments -+ for (i in 0..fragmentCount - 1) { -+ totalLength += endOffsets[i] - startOffsets[i] -+ } -+ if (totalLength < text.length && (text.length + 1) % fragmentCount == 0) { -+ return (text.length + 1) / fragmentCount - 1 -+ } -+ else { -+ return -1 -+ } -+} -+ -+class KotlinLiteralCopyPasteProcessor : CopyPastePreProcessor { -+ override fun preprocessOnCopy(file: PsiFile, startOffsets: IntArray, endOffsets: IntArray, text: String): String? { -+ if (file !is KtFile){ -+ return null -+ } -+ val buffer = StringBuilder() -+ var changed = false -+ val fileText = file.text -+ val deducedBlockSelectionWidth = deduceBlockSelectionWidth(startOffsets, endOffsets, text) -+ -+ for (i in startOffsets.indices) { -+ if (i > 0) { -+ buffer.append('\n') // LF is added for block selection -+ } -+ -+ val fileRange = TextRange(startOffsets[i], endOffsets[i]) -+ -+ var givenTextOffset = fileRange.startOffset -+ while (givenTextOffset < fileRange.endOffset) { -+ val element: PsiElement? = file.findElementAt(givenTextOffset) -+ if (element == null) { -+ buffer.append(fileText.substring(givenTextOffset, fileRange.endOffset)) -+ break -+ } -+ val elTp = element.node.elementType -+ if (elTp == KtTokens.ESCAPE_SEQUENCE && fileRange.contains(element.range) && !fileRange.contains(element.findContainingTemplate().range)) { -+ val tpEntry = element.parent as KtEscapeStringTemplateEntry -+ changed = true -+ buffer.append(tpEntry.unescapedValue) -+ givenTextOffset = element.endOffset -+ } -+ else if (elTp == KtTokens.SHORT_TEMPLATE_ENTRY_START || elTp == KtTokens.LONG_TEMPLATE_ENTRY_START) { -+ //Process inner templates without escaping -+ val tpEntry = element.parent -+ val inter = fileRange.intersection(tpEntry.range)!! -+ buffer.append(fileText.substring(inter.startOffset, inter.endOffset)) -+ givenTextOffset = inter.endOffset -+ } -+ else { -+ val inter = fileRange.intersection(element.range)!! -+ buffer.append(fileText.substring(inter.startOffset, inter.endOffset)) -+ givenTextOffset = inter.endOffset -+ } -+ -+ } -+ val blockSelectionPadding = deducedBlockSelectionWidth - fileRange.length -+ for (j in 0..blockSelectionPadding - 1) { -+ buffer.append(' ') -+ } -+ -+ } -+ -+ return if (changed) buffer.toString() else null -+ } -+ -+ override fun preprocessOnPaste(project: Project, file: PsiFile, editor: Editor, text: String, rawText: RawText?): String { -+ if (file !is KtFile){ -+ return text -+ } -+ PsiDocumentManager.getInstance(project).commitDocument(editor.document) -+ val selectionModel = editor.selectionModel -+ val beginTp = file.getTemplateIfAtLiteral(selectionModel.selectionStart) ?: return text -+ val endTp = file.getTemplateIfAtLiteral(selectionModel.selectionEnd) ?: return text -+ if (beginTp.isSingleQuoted() != endTp.isSingleQuoted()) { -+ return text -+ } -+ -+ -+ return if (beginTp.isSingleQuoted()) { -+ TemplateTokenizer(text).map { -+ when (it) { -+ is LiteralChunk -> StringUtil.escaper(true, ""\$\"""").`fun`(it.text) -+ is EntryChunk -> it.text -+ is NewLineChunk -> ""\\n\""+\n \"""" -+ -+ } -+ }.joinToString(separator = """") -+ } -+ else { -+ val tripleQuoteRe = Regex(""[\""]{3,}"") -+ TemplateTokenizer(text).map { chunk -> -+ when (chunk) { -+ is LiteralChunk -> chunk.text.replace(""\$"", ""\${'$'}"").let { escapedDollar -> -+ tripleQuoteRe.replace(escapedDollar) { ""\""\"""" + ""\${'\""'}"".repeat(it.value.count() - 2) } -+ } -+ -+ is EntryChunk -> chunk.text -+ is NewLineChunk -> ""\n"" -+ -+ } -+ }.joinToString(separator = """") -+ } -+ -+ } -+ -+ -+} -+ -+private sealed class TemplateChunk -+private data class LiteralChunk(val text: String) : TemplateChunk() -+private data class EntryChunk(val text: String) : TemplateChunk() -+private class NewLineChunk : TemplateChunk() -+ -+private class TemplateTokenizer(private val inputString: String) : Sequence { -+ -+ private fun String.guessIsTemplateEntryStart(): Boolean = -+ if (this.startsWith(""\${"")) { -+ true -+ } -+ else if (this.length > 1 && this[0] == '$'){ -+ KotlinLexer().apply { start(this@guessIsTemplateEntryStart.substring(1)) }.tokenType == KtTokens.IDENTIFIER",Better to declare the result of `substring` as a variable outside of the `apply` block.,Why not `import org.jetbrains.kotlin.psi.Editor;`? -246,"@@ -0,0 +1,285 @@ -+/* -+ * 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.editor -+ -+import com.intellij.codeInsight.editorActions.CopyPastePreProcessor -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.editor.RawText -+import com.intellij.openapi.project.Project -+import com.intellij.openapi.util.TextRange -+import com.intellij.openapi.util.text.LineTokenizer -+import com.intellij.openapi.util.text.StringUtil -+import com.intellij.psi.PsiDocumentManager -+import com.intellij.psi.PsiElement -+import com.intellij.psi.PsiFile -+import org.jetbrains.kotlin.idea.editor.fixers.range -+import org.jetbrains.kotlin.lexer.KotlinLexer -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.KtEscapeStringTemplateEntry -+import org.jetbrains.kotlin.psi.KtFile -+import org.jetbrains.kotlin.psi.KtStringTemplateEntry -+import org.jetbrains.kotlin.psi.KtStringTemplateExpression -+import org.jetbrains.kotlin.psi.psiUtil.endOffset -+import org.jetbrains.kotlin.psi.psiUtil.isSingleQuoted -+import org.jetbrains.kotlin.psi.psiUtil.startOffset -+import kotlin.coroutines.experimental.SequenceBuilder -+import kotlin.coroutines.experimental.buildIterator -+ -+private fun PsiElement.findContainingTemplate(): PsiElement { -+ val parent = this.parent -+ @Suppress(""IfThenToElvis"") -+ return if (parent is KtStringTemplateEntry) parent.parent else parent -+} -+ -+private fun PsiFile.getTemplateIfAtLiteral(offset: Int): KtStringTemplateExpression? { -+ val at = this.findElementAt(offset) ?: return null -+ return when (at.node?.elementType) { -+ KtTokens.REGULAR_STRING_PART, KtTokens.ESCAPE_SEQUENCE, KtTokens.LONG_TEMPLATE_ENTRY_START, KtTokens.SHORT_TEMPLATE_ENTRY_START -> at.parent.parent as? KtStringTemplateExpression -+ KtTokens.CLOSING_QUOTE -> if (offset == at.startOffset) at.parent as? KtStringTemplateExpression else null -+ else -> null -+ -+ } -+} -+ -+ -+//Copied from StringLiteralCopyPasteProcessor to avoid erroneous inheritance -+private fun deduceBlockSelectionWidth(startOffsets: IntArray, endOffsets: IntArray, text: String): Int { -+ val fragmentCount = startOffsets.size -+ assert(fragmentCount > 0) -+ var totalLength = fragmentCount - 1 // number of line breaks inserted between fragments -+ for (i in 0..fragmentCount - 1) { -+ totalLength += endOffsets[i] - startOffsets[i] -+ } -+ if (totalLength < text.length && (text.length + 1) % fragmentCount == 0) { -+ return (text.length + 1) / fragmentCount - 1 -+ } -+ else { -+ return -1 -+ } -+} -+ -+class KotlinLiteralCopyPasteProcessor : CopyPastePreProcessor { -+ override fun preprocessOnCopy(file: PsiFile, startOffsets: IntArray, endOffsets: IntArray, text: String): String? { -+ if (file !is KtFile){ -+ return null -+ } -+ val buffer = StringBuilder() -+ var changed = false -+ val fileText = file.text -+ val deducedBlockSelectionWidth = deduceBlockSelectionWidth(startOffsets, endOffsets, text) -+ -+ for (i in startOffsets.indices) { -+ if (i > 0) { -+ buffer.append('\n') // LF is added for block selection -+ } -+ -+ val fileRange = TextRange(startOffsets[i], endOffsets[i]) -+ -+ var givenTextOffset = fileRange.startOffset -+ while (givenTextOffset < fileRange.endOffset) { -+ val element: PsiElement? = file.findElementAt(givenTextOffset) -+ if (element == null) { -+ buffer.append(fileText.substring(givenTextOffset, fileRange.endOffset)) -+ break -+ } -+ val elTp = element.node.elementType -+ if (elTp == KtTokens.ESCAPE_SEQUENCE && fileRange.contains(element.range) && !fileRange.contains(element.findContainingTemplate().range)) { -+ val tpEntry = element.parent as KtEscapeStringTemplateEntry -+ changed = true -+ buffer.append(tpEntry.unescapedValue) -+ givenTextOffset = element.endOffset -+ } -+ else if (elTp == KtTokens.SHORT_TEMPLATE_ENTRY_START || elTp == KtTokens.LONG_TEMPLATE_ENTRY_START) { -+ //Process inner templates without escaping -+ val tpEntry = element.parent -+ val inter = fileRange.intersection(tpEntry.range)!! -+ buffer.append(fileText.substring(inter.startOffset, inter.endOffset)) -+ givenTextOffset = inter.endOffset -+ } -+ else { -+ val inter = fileRange.intersection(element.range)!! -+ buffer.append(fileText.substring(inter.startOffset, inter.endOffset)) -+ givenTextOffset = inter.endOffset -+ } -+ -+ } -+ val blockSelectionPadding = deducedBlockSelectionWidth - fileRange.length -+ for (j in 0..blockSelectionPadding - 1) { -+ buffer.append(' ') -+ } -+ -+ } -+ -+ return if (changed) buffer.toString() else null -+ } -+ -+ override fun preprocessOnPaste(project: Project, file: PsiFile, editor: Editor, text: String, rawText: RawText?): String { -+ if (file !is KtFile){ -+ return text -+ } -+ PsiDocumentManager.getInstance(project).commitDocument(editor.document) -+ val selectionModel = editor.selectionModel -+ val beginTp = file.getTemplateIfAtLiteral(selectionModel.selectionStart) ?: return text -+ val endTp = file.getTemplateIfAtLiteral(selectionModel.selectionEnd) ?: return text -+ if (beginTp.isSingleQuoted() != endTp.isSingleQuoted()) { -+ return text -+ } -+ -+ -+ return if (beginTp.isSingleQuoted()) { -+ TemplateTokenizer(text).map { -+ when (it) { -+ is LiteralChunk -> StringUtil.escaper(true, ""\$\"""").`fun`(it.text) -+ is EntryChunk -> it.text -+ is NewLineChunk -> ""\\n\""+\n \"""" -+ -+ } -+ }.joinToString(separator = """") -+ } -+ else { -+ val tripleQuoteRe = Regex(""[\""]{3,}"") -+ TemplateTokenizer(text).map { chunk -> -+ when (chunk) { -+ is LiteralChunk -> chunk.text.replace(""\$"", ""\${'$'}"").let { escapedDollar -> -+ tripleQuoteRe.replace(escapedDollar) { ""\""\"""" + ""\${'\""'}"".repeat(it.value.count() - 2) } -+ } -+ -+ is EntryChunk -> chunk.text -+ is NewLineChunk -> ""\n"" -+ -+ } -+ }.joinToString(separator = """") -+ } -+ -+ } -+ -+ -+} -+ -+private sealed class TemplateChunk -+private data class LiteralChunk(val text: String) : TemplateChunk() -+private data class EntryChunk(val text: String) : TemplateChunk() -+private class NewLineChunk : TemplateChunk() -+ -+private class TemplateTokenizer(private val inputString: String) : Sequence { -+ -+ private fun String.guessIsTemplateEntryStart(): Boolean = -+ if (this.startsWith(""\${"")) { -+ true -+ } -+ else if (this.length > 1 && this[0] == '$'){ -+ KotlinLexer().apply { start(this@guessIsTemplateEntryStart.substring(1)) }.tokenType == KtTokens.IDENTIFIER -+ } -+ else { -+ false -+ } -+ -+ private fun findTemplateEntryEnd(input: String, from: Int): Int{ -+ val wrapped = '""' + input.substring(from) + '""' -+ val lexer = KotlinLexer().apply { start(wrapped) }.apply { advance() } -+ -+ if (lexer.tokenType == KtTokens.SHORT_TEMPLATE_ENTRY_START){ -+ lexer.advance() -+ return if (lexer.tokenType == KtTokens.IDENTIFIER){ -+ from + lexer.tokenEnd -1 -+ } else{ -+ -1 -+ } -+ } -+ else if(lexer.tokenType == KtTokens.LONG_TEMPLATE_ENTRY_START) { -+ var depth = 0 -+ while (lexer.tokenType != null) { -+ if (lexer.tokenType == KtTokens.LONG_TEMPLATE_ENTRY_START) { -+ depth++ -+ } -+ else if (lexer.tokenType == KtTokens.LONG_TEMPLATE_ENTRY_END) { -+ depth-- -+ if (depth == 0) { -+ return from + lexer.currentPosition.offset - 1 -+ } -+ } -+ lexer.advance() -+ } -+ return -1 -+ } -+ else { -+ return -1 -+ } -+ } -+ -+ private suspend fun SequenceBuilder.yieldLiteral(chunk: String) { -+ -+ val splitLines = LineTokenizer.tokenize(chunk, false, true) -+ for (i in 0..splitLines.size - 1) { -+ if (i != 0) { -+ yield(NewLineChunk()) -+ } -+ splitLines[i].takeIf { !it.isEmpty() }?.let { yield(LiteralChunk(it)) } -+ } -+ -+ } -+ -+ private fun iterTemplateChunks(): Iterator { -+ if (inputString.isEmpty()) { -+ return emptySequence().iterator() -+ } -+ return buildIterator { -+ var from = 0 -+ var to = 0 -+ while (to < inputString.length) { -+ val c = inputString[to] -+ if (c == '\\') { -+ to += 1 -+ if (to < inputString.length) -+ to += 1",I think this assumes that all escapes are single-character? That's not true; there are also `\uxxxx` escape sequences.,Why not `import org.jetbrains.kotlin.psi.Editor;`? -247,"@@ -0,0 +1,285 @@ -+/* -+ * 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.editor -+ -+import com.intellij.codeInsight.editorActions.CopyPastePreProcessor -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.editor.RawText -+import com.intellij.openapi.project.Project -+import com.intellij.openapi.util.TextRange -+import com.intellij.openapi.util.text.LineTokenizer -+import com.intellij.openapi.util.text.StringUtil -+import com.intellij.psi.PsiDocumentManager -+import com.intellij.psi.PsiElement -+import com.intellij.psi.PsiFile -+import org.jetbrains.kotlin.idea.editor.fixers.range -+import org.jetbrains.kotlin.lexer.KotlinLexer -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.KtEscapeStringTemplateEntry -+import org.jetbrains.kotlin.psi.KtFile -+import org.jetbrains.kotlin.psi.KtStringTemplateEntry -+import org.jetbrains.kotlin.psi.KtStringTemplateExpression -+import org.jetbrains.kotlin.psi.psiUtil.endOffset -+import org.jetbrains.kotlin.psi.psiUtil.isSingleQuoted -+import org.jetbrains.kotlin.psi.psiUtil.startOffset -+import kotlin.coroutines.experimental.SequenceBuilder -+import kotlin.coroutines.experimental.buildIterator -+ -+private fun PsiElement.findContainingTemplate(): PsiElement { -+ val parent = this.parent -+ @Suppress(""IfThenToElvis"") -+ return if (parent is KtStringTemplateEntry) parent.parent else parent -+} -+ -+private fun PsiFile.getTemplateIfAtLiteral(offset: Int): KtStringTemplateExpression? { -+ val at = this.findElementAt(offset) ?: return null -+ return when (at.node?.elementType) { -+ KtTokens.REGULAR_STRING_PART, KtTokens.ESCAPE_SEQUENCE, KtTokens.LONG_TEMPLATE_ENTRY_START, KtTokens.SHORT_TEMPLATE_ENTRY_START -> at.parent.parent as? KtStringTemplateExpression -+ KtTokens.CLOSING_QUOTE -> if (offset == at.startOffset) at.parent as? KtStringTemplateExpression else null -+ else -> null -+ -+ } -+} -+ -+ -+//Copied from StringLiteralCopyPasteProcessor to avoid erroneous inheritance -+private fun deduceBlockSelectionWidth(startOffsets: IntArray, endOffsets: IntArray, text: String): Int { -+ val fragmentCount = startOffsets.size -+ assert(fragmentCount > 0) -+ var totalLength = fragmentCount - 1 // number of line breaks inserted between fragments -+ for (i in 0..fragmentCount - 1) { -+ totalLength += endOffsets[i] - startOffsets[i] -+ } -+ if (totalLength < text.length && (text.length + 1) % fragmentCount == 0) { -+ return (text.length + 1) / fragmentCount - 1 -+ } -+ else { -+ return -1 -+ } -+} -+ -+class KotlinLiteralCopyPasteProcessor : CopyPastePreProcessor { -+ override fun preprocessOnCopy(file: PsiFile, startOffsets: IntArray, endOffsets: IntArray, text: String): String? { -+ if (file !is KtFile){ -+ return null -+ } -+ val buffer = StringBuilder() -+ var changed = false -+ val fileText = file.text -+ val deducedBlockSelectionWidth = deduceBlockSelectionWidth(startOffsets, endOffsets, text) -+ -+ for (i in startOffsets.indices) { -+ if (i > 0) { -+ buffer.append('\n') // LF is added for block selection -+ } -+ -+ val fileRange = TextRange(startOffsets[i], endOffsets[i]) -+ -+ var givenTextOffset = fileRange.startOffset -+ while (givenTextOffset < fileRange.endOffset) { -+ val element: PsiElement? = file.findElementAt(givenTextOffset) -+ if (element == null) { -+ buffer.append(fileText.substring(givenTextOffset, fileRange.endOffset)) -+ break -+ } -+ val elTp = element.node.elementType -+ if (elTp == KtTokens.ESCAPE_SEQUENCE && fileRange.contains(element.range) && !fileRange.contains(element.findContainingTemplate().range)) { -+ val tpEntry = element.parent as KtEscapeStringTemplateEntry -+ changed = true -+ buffer.append(tpEntry.unescapedValue) -+ givenTextOffset = element.endOffset -+ } -+ else if (elTp == KtTokens.SHORT_TEMPLATE_ENTRY_START || elTp == KtTokens.LONG_TEMPLATE_ENTRY_START) { -+ //Process inner templates without escaping -+ val tpEntry = element.parent -+ val inter = fileRange.intersection(tpEntry.range)!! -+ buffer.append(fileText.substring(inter.startOffset, inter.endOffset)) -+ givenTextOffset = inter.endOffset -+ } -+ else { -+ val inter = fileRange.intersection(element.range)!! -+ buffer.append(fileText.substring(inter.startOffset, inter.endOffset)) -+ givenTextOffset = inter.endOffset -+ } -+ -+ } -+ val blockSelectionPadding = deducedBlockSelectionWidth - fileRange.length -+ for (j in 0..blockSelectionPadding - 1) { -+ buffer.append(' ') -+ } -+ -+ } -+ -+ return if (changed) buffer.toString() else null -+ } -+ -+ override fun preprocessOnPaste(project: Project, file: PsiFile, editor: Editor, text: String, rawText: RawText?): String { -+ if (file !is KtFile){ -+ return text -+ } -+ PsiDocumentManager.getInstance(project).commitDocument(editor.document) -+ val selectionModel = editor.selectionModel -+ val beginTp = file.getTemplateIfAtLiteral(selectionModel.selectionStart) ?: return text -+ val endTp = file.getTemplateIfAtLiteral(selectionModel.selectionEnd) ?: return text -+ if (beginTp.isSingleQuoted() != endTp.isSingleQuoted()) { -+ return text -+ } -+ -+ -+ return if (beginTp.isSingleQuoted()) { -+ TemplateTokenizer(text).map { -+ when (it) { -+ is LiteralChunk -> StringUtil.escaper(true, ""\$\"""").`fun`(it.text) -+ is EntryChunk -> it.text -+ is NewLineChunk -> ""\\n\""+\n \"""" -+ -+ } -+ }.joinToString(separator = """") -+ } -+ else { -+ val tripleQuoteRe = Regex(""[\""]{3,}"") -+ TemplateTokenizer(text).map { chunk -> -+ when (chunk) { -+ is LiteralChunk -> chunk.text.replace(""\$"", ""\${'$'}"").let { escapedDollar -> -+ tripleQuoteRe.replace(escapedDollar) { ""\""\"""" + ""\${'\""'}"".repeat(it.value.count() - 2) } -+ } -+ -+ is EntryChunk -> chunk.text -+ is NewLineChunk -> ""\n"" -+ -+ } -+ }.joinToString(separator = """") -+ } -+ -+ } -+ -+ -+} -+ -+private sealed class TemplateChunk -+private data class LiteralChunk(val text: String) : TemplateChunk() -+private data class EntryChunk(val text: String) : TemplateChunk() -+private class NewLineChunk : TemplateChunk() -+ -+private class TemplateTokenizer(private val inputString: String) : Sequence { -+ -+ private fun String.guessIsTemplateEntryStart(): Boolean = -+ if (this.startsWith(""\${"")) { -+ true -+ } -+ else if (this.length > 1 && this[0] == '$'){ -+ KotlinLexer().apply { start(this@guessIsTemplateEntryStart.substring(1)) }.tokenType == KtTokens.IDENTIFIER -+ } -+ else { -+ false -+ } -+ -+ private fun findTemplateEntryEnd(input: String, from: Int): Int{ -+ val wrapped = '""' + input.substring(from) + '""' -+ val lexer = KotlinLexer().apply { start(wrapped) }.apply { advance() } -+ -+ if (lexer.tokenType == KtTokens.SHORT_TEMPLATE_ENTRY_START){ -+ lexer.advance() -+ return if (lexer.tokenType == KtTokens.IDENTIFIER){ -+ from + lexer.tokenEnd -1 -+ } else{ -+ -1 -+ } -+ } -+ else if(lexer.tokenType == KtTokens.LONG_TEMPLATE_ENTRY_START) { -+ var depth = 0 -+ while (lexer.tokenType != null) { -+ if (lexer.tokenType == KtTokens.LONG_TEMPLATE_ENTRY_START) { -+ depth++ -+ } -+ else if (lexer.tokenType == KtTokens.LONG_TEMPLATE_ENTRY_END) { -+ depth-- -+ if (depth == 0) { -+ return from + lexer.currentPosition.offset - 1 -+ } -+ } -+ lexer.advance() -+ } -+ return -1 -+ } -+ else { -+ return -1 -+ } -+ } -+ -+ private suspend fun SequenceBuilder.yieldLiteral(chunk: String) { -+ -+ val splitLines = LineTokenizer.tokenize(chunk, false, true) -+ for (i in 0..splitLines.size - 1) { -+ if (i != 0) { -+ yield(NewLineChunk()) -+ } -+ splitLines[i].takeIf { !it.isEmpty() }?.let { yield(LiteralChunk(it)) } -+ } -+ -+ } -+ -+ private fun iterTemplateChunks(): Iterator { -+ if (inputString.isEmpty()) { -+ return emptySequence().iterator() -+ } -+ return buildIterator { -+ var from = 0 -+ var to = 0 -+ while (to < inputString.length) { -+ val c = inputString[to] -+ if (c == '\\') { -+ to += 1 -+ if (to < inputString.length) -+ to += 1 -+ continue -+ -+ } -+ when (c) {",No reason to use `when` here; `if` would be cleaner.,Why not `import org.jetbrains.kotlin.psi.Editor;`? -248,"@@ -0,0 +1,3 @@ -+// INTENTION_TEXT: ""Convert to sealed class""","Since you aren't changing the intention text dynamically, there's no need to include INTENTION_TEXT in testdata files.",The `intention-text` constant is already defined i -249,"@@ -0,0 +1,3 @@ -+@JvmStatic","The template shows a top-level method, not a method inside an `object`. Please update it to show what the intention action actually does.",This will need to be added to the `JvmBUILD` file -250,"@@ -0,0 +1,3 @@ -+[3] -+ -+[3, 5]","Please update this file to be exactly the result of your intention on `before.kt.template`. Also you can use `` tag to highlight the place where the user should put his attention -",Can you add a trailing comma to avoid issues later -251,"@@ -0,0 +1,3 @@ -+for ((i,x) in foo.withIndices()) {","Please add a whitespace after the comma -","E302 expected 2 blank lines, found 1" -252,"@@ -0,0 +1,3 @@ -+fun foo(a: String?, b: String?) { -+ a?.equals(b) ?: b.identityEquals(null) -+}","Please, add test for the case of non-nullable receiver -",does this test fail on windows because the string -253,"@@ -0,0 +1,3 @@ -+fun foo(x: Boolean) : Boolean { -+ return x || x || x","This behavior is objectionable: order of predicates evaluation can change program behavior, when evaluated expressions have side effects. I'll disable intention in this case. -",This is a regression I am introducing for the `Boo -254,"@@ -0,0 +1,30 @@ -+/*","Consider merging small and relevant declarations together into one file, e.g. `JavaType` implementations into `symbolBasedTypes.kt`, `JavaAnnotationArgument` implementations into `symbolBasedAnnotationArguments.kt` and so on. I think it'd be more readable in the end",Please remove this file. -255,"@@ -0,0 +1,30 @@ -+/* -+ * 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.wrappers.symbols -+ -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.load.java.structure.JavaEnumValueAnnotationArgument -+import org.jetbrains.kotlin.name.FqName -+import javax.lang.model.element.VariableElement -+ -+class JavacReferenceAnnotationArgument(val element: VariableElement, -+ javac: Javac) : JavacAnnotationArgument(FqName(element.simpleName.toString()), javac), -+ JavaEnumValueAnnotationArgument { -+ -+ override fun resolve() = JavacField(element, javac)","In NB plugin you're using containing class at this point, but here you aren't. Are you sure it's not a mistake?",missing new line. -256,"@@ -0,0 +1,30 @@ -+/* -+ * 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.wrappers.symbols -+ -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.load.java.structure.JavaAnnotationAsAnnotationArgument -+import org.jetbrains.kotlin.name.Name -+import javax.lang.model.element.AnnotationMirror -+ -+class SymbolBasedAnnotationAsAnnotationArgument(val mirror: AnnotationMirror,","I'd assume that all `SymbolBased*AnnotationArgument`s are subclasses of `SymbolBasedAnnotationArgument`, but only one of them is (`SymbolBasedReferenceAnnotationArgument`). I suggest either inheriting all of them from `SymbolBasedAnnotationArgument`, or getting rid of the latter altogether",Add file header -257,"@@ -0,0 +1,30 @@ -+/* -+ * 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.wrappers.symbols -+ -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.load.java.structure.JavaArrayType -+import javax.lang.model.type.ArrayType -+import javax.lang.model.type.TypeMirror -+ -+class SymbolBasedArrayType(typeMirror: T,","Instead of generic type parameter, inherit from `SymbolBasedType`, cast `typeMirror` to `ArrayType` once at creation site",missing new lin -258,"@@ -0,0 +1,304 @@ -+# Function Types in Kotlin on JVM -+ -+## Goals -+ -+* Get rid of 23 hardwired physical function classes. One of the problems with them is that they should be effectively duplicated in reflection which means a lot of physical classes in the runtime.","""in the runtime"" -> ""at runtime""? -Имеется в виду ""во время выполнения программы""? -",Is there a way -259,"@@ -0,0 +1,304 @@ -+# Function Types in Kotlin on JVM -+ -+## Goals -+ -+* Get rid of 23 hardwired physical function classes. One of the problems with them is that they should be effectively duplicated in reflection which means a lot of physical classes in the runtime. -+* Make extension functions coercible to normal functions (with an extra parameter), so that it's possible to do `listOfStrings.map(String::length)`","""coercible"" usually assumes some transformation of the value representation to fit to a new type. If it's exactly the same object, just viewed as an instance of a new type, then maybe it would be better to say ""implicitly convertible"" or ""assignable""? -",Does it mean th -260,"@@ -0,0 +1,304 @@ -+# Function Types in Kotlin on JVM -+ -+## Goals -+ -+* Get rid of 23 hardwired physical function classes. One of the problems with them is that they should be effectively duplicated in reflection which means a lot of physical classes in the runtime. -+* Make extension functions coercible to normal functions (with an extra parameter), so that it's possible to do `listOfStrings.map(String::length)` -+* Allow functions with more than 23 parameters, theoretically any number of parameters (in practice 255 on JVM). -+* At the same time, allow to implement Kotlin functions easily from Java: `new Function2() { ... }` and overriding `invoke` only would be the best.","I do not get the meaning of ""overriding `invoke` only would be the best"". -",Is there an adv -261,"@@ -0,0 +1,304 @@ -+# Function Types in Kotlin on JVM -+ -+## Goals -+ -+* Get rid of 23 hardwired physical function classes. One of the problems with them is that they should be effectively duplicated in reflection which means a lot of physical classes in the runtime. -+* Make extension functions coercible to normal functions (with an extra parameter), so that it's possible to do `listOfStrings.map(String::length)` -+* Allow functions with more than 23 parameters, theoretically any number of parameters (in practice 255 on JVM). -+* At the same time, allow to implement Kotlin functions easily from Java: `new Function2() { ... }` and overriding `invoke` only would be the best. -+Enabling SAM conversions on Java 8 would also be terrific. -+ -+## Brief solution overview -+ -+* Treat extension functions almost like non-extension functions with one extra parameter, allowing to use them almost interchangeably. -+* Introduce a physical class `Function` and unlimited number of *fictitious* (synthetic) classes `Function0`, `Function1`, ... in the compiler front-end -+* On JVM, introduce `Function0`..`Function22`, which are optimized in a certain way, -+and `FunctionN` for functions with 23+ parameters. -+When passing a lambda to Kotlin from Java, one will need to implement one of these interfaces. -+* Also on JVM (under the hood) add abstract `FunctionImpl` which implements all of `Fun0`..`Fun22` and `FunN`","What is `Fun0`? -",While you're at -262,"@@ -0,0 +1,304 @@ -+# Function Types in Kotlin on JVM -+ -+## Goals -+ -+* Get rid of 23 hardwired physical function classes. One of the problems with them is that they should be effectively duplicated in reflection which means a lot of physical classes in the runtime. -+* Make extension functions coercible to normal functions (with an extra parameter), so that it's possible to do `listOfStrings.map(String::length)` -+* Allow functions with more than 23 parameters, theoretically any number of parameters (in practice 255 on JVM). -+* At the same time, allow to implement Kotlin functions easily from Java: `new Function2() { ... }` and overriding `invoke` only would be the best. -+Enabling SAM conversions on Java 8 would also be terrific. -+ -+## Brief solution overview -+ -+* Treat extension functions almost like non-extension functions with one extra parameter, allowing to use them almost interchangeably. -+* Introduce a physical class `Function` and unlimited number of *fictitious* (synthetic) classes `Function0`, `Function1`, ... in the compiler front-end -+* On JVM, introduce `Function0`..`Function22`, which are optimized in a certain way, -+and `FunctionN` for functions with 23+ parameters. -+When passing a lambda to Kotlin from Java, one will need to implement one of these interfaces. -+* Also on JVM (under the hood) add abstract `FunctionImpl` which implements all of `Fun0`..`Fun22` and `FunN` -+(throwing exceptions), and which knows its arity. -+Kotlin lambdas are translated to subclasses of this abstract class, passing the correct arity to the super constructor. -+* Provide a way to get arity of an arbitrary `Function` object (pretty straightforward). -+* Hack `is/as Function5` on any numbered function in codegen (and probably `KClass.cast()` in reflection) to check against `Function` and its arity.","So, is it `Function` or `FunctionImpl` who knows the function arity? For which type are we going to check in `is` operator? -",Is there an adv -263,"@@ -0,0 +1,304 @@ -+# Function Types in Kotlin on JVM -+ -+## Goals -+ -+* Get rid of 23 hardwired physical function classes. One of the problems with them is that they should be effectively duplicated in reflection which means a lot of physical classes in the runtime. -+* Make extension functions coercible to normal functions (with an extra parameter), so that it's possible to do `listOfStrings.map(String::length)` -+* Allow functions with more than 23 parameters, theoretically any number of parameters (in practice 255 on JVM). -+* At the same time, allow to implement Kotlin functions easily from Java: `new Function2() { ... }` and overriding `invoke` only would be the best. -+Enabling SAM conversions on Java 8 would also be terrific. -+ -+## Brief solution overview -+ -+* Treat extension functions almost like non-extension functions with one extra parameter, allowing to use them almost interchangeably. -+* Introduce a physical class `Function` and unlimited number of *fictitious* (synthetic) classes `Function0`, `Function1`, ... in the compiler front-end -+* On JVM, introduce `Function0`..`Function22`, which are optimized in a certain way, -+and `FunctionN` for functions with 23+ parameters. -+When passing a lambda to Kotlin from Java, one will need to implement one of these interfaces. -+* Also on JVM (under the hood) add abstract `FunctionImpl` which implements all of `Fun0`..`Fun22` and `FunN` -+(throwing exceptions), and which knows its arity. -+Kotlin lambdas are translated to subclasses of this abstract class, passing the correct arity to the super constructor. -+* Provide a way to get arity of an arbitrary `Function` object (pretty straightforward). -+* Hack `is/as Function5` on any numbered function in codegen (and probably `KClass.cast()` in reflection) to check against `Function` and its arity. -+ -+## Extension functions -+ -+Extension function type `T.(P) -> R` is now just a shorthand for `@kotlin.extension Function2`. -+`kotlin.extension` is a **type annotation** defined in built-ins. -+So effectively functions and extension functions now have the same type, -+which means that everything which takes a function will work with an extension function and vice versa. -+ -+To prevent unpleasant ambiguities, we introduce additional restrictions: -+* A value of an extension function type cannot be **called** as a function, and a value of a non-extension -+function type cannot be called as an extension. This requires an additional diagnostic which is only fired -+when a call is resolved to the `invoke` with the wrong extension-ness. -+* If an extension function **literal** argument has some shape (its parameters are written out explicitly -+in the code and it's evident that there is or there isn't a receiver parameter), this shape must exactly match","What could make it evident that there is or there isn't a receiver parameter? -",Is there an adv -264,"@@ -0,0 +1,304 @@ -+# Function Types in Kotlin on JVM -+ -+## Goals -+ -+* Get rid of 23 hardwired physical function classes. One of the problems with them is that they should be effectively duplicated in reflection which means a lot of physical classes in the runtime. -+* Make extension functions coercible to normal functions (with an extra parameter), so that it's possible to do `listOfStrings.map(String::length)` -+* Allow functions with more than 23 parameters, theoretically any number of parameters (in practice 255 on JVM). -+* At the same time, allow to implement Kotlin functions easily from Java: `new Function2() { ... }` and overriding `invoke` only would be the best. -+Enabling SAM conversions on Java 8 would also be terrific. -+ -+## Brief solution overview -+ -+* Treat extension functions almost like non-extension functions with one extra parameter, allowing to use them almost interchangeably. -+* Introduce a physical class `Function` and unlimited number of *fictitious* (synthetic) classes `Function0`, `Function1`, ... in the compiler front-end -+* On JVM, introduce `Function0`..`Function22`, which are optimized in a certain way, -+and `FunctionN` for functions with 23+ parameters. -+When passing a lambda to Kotlin from Java, one will need to implement one of these interfaces. -+* Also on JVM (under the hood) add abstract `FunctionImpl` which implements all of `Fun0`..`Fun22` and `FunN` -+(throwing exceptions), and which knows its arity. -+Kotlin lambdas are translated to subclasses of this abstract class, passing the correct arity to the super constructor. -+* Provide a way to get arity of an arbitrary `Function` object (pretty straightforward). -+* Hack `is/as Function5` on any numbered function in codegen (and probably `KClass.cast()` in reflection) to check against `Function` and its arity. -+ -+## Extension functions -+ -+Extension function type `T.(P) -> R` is now just a shorthand for `@kotlin.extension Function2`. -+`kotlin.extension` is a **type annotation** defined in built-ins. -+So effectively functions and extension functions now have the same type, -+which means that everything which takes a function will work with an extension function and vice versa. -+ -+To prevent unpleasant ambiguities, we introduce additional restrictions: -+* A value of an extension function type cannot be **called** as a function, and a value of a non-extension -+function type cannot be called as an extension. This requires an additional diagnostic which is only fired -+when a call is resolved to the `invoke` with the wrong extension-ness. -+* If an extension function **literal** argument has some shape (its parameters are written out explicitly -+in the code and it's evident that there is or there isn't a receiver parameter), this shape must exactly match -+the extension-ness of the corresponding parameter. You can't pass an extension function **literal** -+where a function is expected and vice versa. The same holds for function expressions. -+If you really want to do that, change the shape or use the `as` operator. -+ -+So basically you can now safely coerce values between function and extension function types, -+but still should invoke them in the format which you specified in their type (with or without `@extension`). -+ -+With this we'll get rid of classes `ExtensionFunction0`, `ExtensionFunction1`, ... -+and the rest of this article will deal only with usual functions. -+ -+## Function0, Function1, ... types -+ -+The arity of the functional interface that the type checker can create in theory **is not limited** to any number, -+but in practice should be limited to 255 on JVM. -+ -+These interfaces are named `kotlin.Function0`, `kotlin.Function1`, ..., `kotlin.Function42`, ... -+They are *fictitious*, which means they have no sources and no runtime representation. -+Type checker creates the corresponding descriptors on demand, IDE creates corresponding source files on demand as well. -+Each of them inherits from `kotlin.Function` (described below) and contains only two functions, -+both of which should be synthetically produced by the compiler: -+* (declaration) `invoke` with no receiver, with the corresponding number of parameters and return type. -+* (synthesized) `invoke` with first type parameter as the extension receiver type, and the rest as parameters and return type.","""first type parameter""? Are you talking about ``? -",Is there an adv -265,"@@ -0,0 +1,31 @@ -+/* -+ * 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.wrappers.symbols -+ -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.builtins.PrimitiveType -+import org.jetbrains.kotlin.load.java.structure.JavaPrimitiveType -+import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType -+import javax.lang.model.type.TypeMirror -+ -+class JavacPrimitiveType(typeMirror: T, -+ javac: Javac) : JavacType(typeMirror, javac), JavaPrimitiveType { -+ -+ override val type: PrimitiveType? -+ get() = if (""void"" == typeMirror.toString()) null else JvmPrimitiveType.get(typeMirror.toString()).primitiveType",You can extract `typeMirror.toString()`,This should pro -266,"@@ -0,0 +1,31 @@ -+/* -+ * 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.wrappers.trees -+ -+import com.sun.tools.javac.tree.JCTree -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.load.java.structure.JavaAnnotationArgument -+import org.jetbrains.kotlin.load.java.structure.JavaElement -+import org.jetbrains.kotlin.name.FqName -+ -+open class TreeBasedAnnotationArgument(val tree: JCTree.JCExpression, -+ fqName: FqName,",`Name` should be enough here as well,Why not `tree: -267,"@@ -0,0 +1,313 @@ -+/* -+ * 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.rmi -+ -+import java.io.File -+import java.io.Serializable -+import java.lang.management.ManagementFactory -+import java.security.DigestInputStream -+import java.security.MessageDigest -+import kotlin.reflect.KMutableProperty1 -+ -+ -+public val COMPILER_JAR_NAME: String = ""kotlin-compiler.jar"" -+public val COMPILER_SERVICE_RMI_NAME: String = ""KotlinJvmCompilerService"" -+public val COMPILER_DAEMON_CLASS_FQN: String = ""org.jetbrains.kotlin.rmi.service.CompileDaemon"" -+public val COMPILE_DAEMON_DEFAULT_PORT: Int = 17031 -+public val COMPILE_DAEMON_ENABLED_PROPERTY: String =""kotlin.daemon.enabled"" -+public val COMPILE_DAEMON_JVM_OPTIONS_PROPERTY: String =""kotlin.daemon.jvm.options"" -+public val COMPILE_DAEMON_OPTIONS_PROPERTY: String =""kotlin.daemon.options"" -+public val COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX: String =""--daemon-"" -+public val COMPILE_DAEMON_TIMEOUT_INFINITE_S: Int = 0 -+public val COMPILE_DAEMON_MEMORY_THRESHOLD_INFINITE: Long = 0L -+ -+val COMPILER_ID_DIGEST = ""MD5"" -+ -+//open class PropExtractor>(val dest: C, -+// val prop: P, -+// val name: String, -+// val convert: ((v: V) -> String?) = { it.toString() }, -+// val skipIf: ((v: V) -> Boolean) = { false }, -+// val mergeWithDelimiter: String? = null) -+//{ -+// constructor(dest: C, prop: P, convert: ((v: V) -> String?) = { it.toString() }, skipIf: ((v: V) -> Boolean) = { false }) : this(dest, prop, prop.name, convert, skipIf) -+// open fun extract(prefix: String = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX): List = -+// when { -+// skipIf(prop.get(dest)) -> listOf() -+// mergeWithDelimiter != null -> listOf(prefix + name + mergeWithDelimiter + convert(prop.get(dest))).filterNotNull() -+// else -> listOf(prefix + name, convert(prop.get(dest))).filterNotNull() -+// } -+//} -+// -+//class BoolPropExtractor>(dest: C, prop: P, name: String? = null) -+// : PropExtractor(dest, prop, name ?: prop.name, convert = { null }, skipIf = { !prop.get(dest) }) -+// -+//class RestPropExtractor>>(dest: C, prop: P) : PropExtractor, P>(dest, prop, convert = { null }) { -+// override fun extract(prefix: String): List = prop.get(dest).map { prefix + it } -+//} -+// -+// -+//open class PropParser>(val dest: C, -+// val prop: P, alternativeNames: List, -+// val parse: (s: String) -> V, -+// val allowMergedArg: Boolean = false) { -+// val names = listOf(prop.name) + alternativeNames -+// constructor(dest: C, prop: P, parse: (s: String) -> V, allowMergedArg: Boolean = false) : this(dest, prop, listOf(), parse, allowMergedArg) -+// fun apply(s: String) = prop.set(dest, parse(s)) -+//} -+// -+//class BoolPropParser>(dest: C, prop: P): PropParser(dest, prop, { true }) -+// -+//class RestPropParser>>(dest: C, prop: P): PropParser, P>(dest, prop, { arrayListOf() }) { -+// fun add(s: String) { prop.get(dest).add(s) } -+//}","let's drop it -",remove this emp -268,"@@ -0,0 +1,313 @@ -+/* -+ * 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.rmi -+ -+import java.io.File -+import java.io.Serializable -+import java.lang.management.ManagementFactory -+import java.security.DigestInputStream -+import java.security.MessageDigest -+import kotlin.reflect.KMutableProperty1 -+ -+ -+public val COMPILER_JAR_NAME: String = ""kotlin-compiler.jar"" -+public val COMPILER_SERVICE_RMI_NAME: String = ""KotlinJvmCompilerService"" -+public val COMPILER_DAEMON_CLASS_FQN: String = ""org.jetbrains.kotlin.rmi.service.CompileDaemon"" -+public val COMPILE_DAEMON_DEFAULT_PORT: Int = 17031 -+public val COMPILE_DAEMON_ENABLED_PROPERTY: String =""kotlin.daemon.enabled"" -+public val COMPILE_DAEMON_JVM_OPTIONS_PROPERTY: String =""kotlin.daemon.jvm.options"" -+public val COMPILE_DAEMON_OPTIONS_PROPERTY: String =""kotlin.daemon.options"" -+public val COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX: String =""--daemon-"" -+public val COMPILE_DAEMON_TIMEOUT_INFINITE_S: Int = 0 -+public val COMPILE_DAEMON_MEMORY_THRESHOLD_INFINITE: Long = 0L -+ -+val COMPILER_ID_DIGEST = ""MD5"" -+ -+//open class PropExtractor>(val dest: C, -+// val prop: P, -+// val name: String, -+// val convert: ((v: V) -> String?) = { it.toString() }, -+// val skipIf: ((v: V) -> Boolean) = { false }, -+// val mergeWithDelimiter: String? = null) -+//{ -+// constructor(dest: C, prop: P, convert: ((v: V) -> String?) = { it.toString() }, skipIf: ((v: V) -> Boolean) = { false }) : this(dest, prop, prop.name, convert, skipIf) -+// open fun extract(prefix: String = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX): List = -+// when { -+// skipIf(prop.get(dest)) -> listOf() -+// mergeWithDelimiter != null -> listOf(prefix + name + mergeWithDelimiter + convert(prop.get(dest))).filterNotNull() -+// else -> listOf(prefix + name, convert(prop.get(dest))).filterNotNull() -+// } -+//} -+// -+//class BoolPropExtractor>(dest: C, prop: P, name: String? = null) -+// : PropExtractor(dest, prop, name ?: prop.name, convert = { null }, skipIf = { !prop.get(dest) }) -+// -+//class RestPropExtractor>>(dest: C, prop: P) : PropExtractor, P>(dest, prop, convert = { null }) { -+// override fun extract(prefix: String): List = prop.get(dest).map { prefix + it } -+//} -+// -+// -+//open class PropParser>(val dest: C, -+// val prop: P, alternativeNames: List, -+// val parse: (s: String) -> V, -+// val allowMergedArg: Boolean = false) { -+// val names = listOf(prop.name) + alternativeNames -+// constructor(dest: C, prop: P, parse: (s: String) -> V, allowMergedArg: Boolean = false) : this(dest, prop, listOf(), parse, allowMergedArg) -+// fun apply(s: String) = prop.set(dest, parse(s)) -+//} -+// -+//class BoolPropParser>(dest: C, prop: P): PropParser(dest, prop, { true }) -+// -+//class RestPropParser>>(dest: C, prop: P): PropParser, P>(dest, prop, { arrayListOf() }) { -+// fun add(s: String) { prop.get(dest).add(s) } -+//} -+ -+// -------------------------------------------------------- -+ -+open class PropMapper>(val dest: C, -+ val prop: P, -+ val names: List = listOf(prop.name), -+ val fromString: (s: String) -> V, -+ val toString: ((v: V) -> String?) = { it.toString() }, -+ val skipIf: ((v: V) -> Boolean) = { false }, -+ val mergeDelimiter: String? = null) -+{ -+ open fun toArgs(prefix: String = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX): List = -+ when { -+ skipIf(prop.get(dest)) -> listOf() -+ mergeDelimiter != null -> listOf(prefix + names.first() + mergeDelimiter + toString(prop.get(dest))).filterNotNull()","nothing to filter out by `filterNotNull` -",remove this emp -269,"@@ -0,0 +1,313 @@ -+/* -+ * 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.rmi -+ -+import java.io.File -+import java.io.Serializable -+import java.lang.management.ManagementFactory -+import java.security.DigestInputStream -+import java.security.MessageDigest -+import kotlin.reflect.KMutableProperty1 -+ -+ -+public val COMPILER_JAR_NAME: String = ""kotlin-compiler.jar"" -+public val COMPILER_SERVICE_RMI_NAME: String = ""KotlinJvmCompilerService"" -+public val COMPILER_DAEMON_CLASS_FQN: String = ""org.jetbrains.kotlin.rmi.service.CompileDaemon"" -+public val COMPILE_DAEMON_DEFAULT_PORT: Int = 17031 -+public val COMPILE_DAEMON_ENABLED_PROPERTY: String =""kotlin.daemon.enabled"" -+public val COMPILE_DAEMON_JVM_OPTIONS_PROPERTY: String =""kotlin.daemon.jvm.options"" -+public val COMPILE_DAEMON_OPTIONS_PROPERTY: String =""kotlin.daemon.options"" -+public val COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX: String =""--daemon-"" -+public val COMPILE_DAEMON_TIMEOUT_INFINITE_S: Int = 0 -+public val COMPILE_DAEMON_MEMORY_THRESHOLD_INFINITE: Long = 0L -+ -+val COMPILER_ID_DIGEST = ""MD5"" -+ -+//open class PropExtractor>(val dest: C, -+// val prop: P, -+// val name: String, -+// val convert: ((v: V) -> String?) = { it.toString() }, -+// val skipIf: ((v: V) -> Boolean) = { false }, -+// val mergeWithDelimiter: String? = null) -+//{ -+// constructor(dest: C, prop: P, convert: ((v: V) -> String?) = { it.toString() }, skipIf: ((v: V) -> Boolean) = { false }) : this(dest, prop, prop.name, convert, skipIf) -+// open fun extract(prefix: String = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX): List = -+// when { -+// skipIf(prop.get(dest)) -> listOf() -+// mergeWithDelimiter != null -> listOf(prefix + name + mergeWithDelimiter + convert(prop.get(dest))).filterNotNull() -+// else -> listOf(prefix + name, convert(prop.get(dest))).filterNotNull() -+// } -+//} -+// -+//class BoolPropExtractor>(dest: C, prop: P, name: String? = null) -+// : PropExtractor(dest, prop, name ?: prop.name, convert = { null }, skipIf = { !prop.get(dest) }) -+// -+//class RestPropExtractor>>(dest: C, prop: P) : PropExtractor, P>(dest, prop, convert = { null }) { -+// override fun extract(prefix: String): List = prop.get(dest).map { prefix + it } -+//} -+// -+// -+//open class PropParser>(val dest: C, -+// val prop: P, alternativeNames: List, -+// val parse: (s: String) -> V, -+// val allowMergedArg: Boolean = false) { -+// val names = listOf(prop.name) + alternativeNames -+// constructor(dest: C, prop: P, parse: (s: String) -> V, allowMergedArg: Boolean = false) : this(dest, prop, listOf(), parse, allowMergedArg) -+// fun apply(s: String) = prop.set(dest, parse(s)) -+//} -+// -+//class BoolPropParser>(dest: C, prop: P): PropParser(dest, prop, { true }) -+// -+//class RestPropParser>>(dest: C, prop: P): PropParser, P>(dest, prop, { arrayListOf() }) { -+// fun add(s: String) { prop.get(dest).add(s) } -+//} -+ -+// -------------------------------------------------------- -+ -+open class PropMapper>(val dest: C, -+ val prop: P, -+ val names: List = listOf(prop.name), -+ val fromString: (s: String) -> V, -+ val toString: ((v: V) -> String?) = { it.toString() }, -+ val skipIf: ((v: V) -> Boolean) = { false }, -+ val mergeDelimiter: String? = null) -+{ -+ open fun toArgs(prefix: String = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX): List = -+ when { -+ skipIf(prop.get(dest)) -> listOf() -+ mergeDelimiter != null -> listOf(prefix + names.first() + mergeDelimiter + toString(prop.get(dest))).filterNotNull() -+ else -> listOf(prefix + names.first(), toString(prop.get(dest))).filterNotNull() -+ } -+ fun apply(s: String) = prop.set(dest, fromString(s)) -+} -+ -+class StringPropMapper>(dest: C, -+ prop: P, -+ names: List = listOf(), -+ fromString: ((String) -> String) = { it }, -+ toString: ((String) -> String?) = { it.toString() }, -+ skipIf: ((String) -> Boolean) = { it.isEmpty() }, -+ mergeDelimiter: String? = null) -+: PropMapper(dest = dest, prop = prop, names = if (names.any()) names else listOf(prop.name), -+ fromString = fromString, toString = toString, skipIf = skipIf, mergeDelimiter = mergeDelimiter) -+ -+class BoolPropMapper>(dest: C, prop: P, names: List = listOf()) -+ : PropMapper(dest = dest, prop = prop, names = if (names.any()) names else listOf(prop.name), -+ fromString = { true }, toString = { null }, skipIf = { !prop.get(dest) }) -+ -+class RestPropMapper>>(dest: C, prop: P) -+ : PropMapper, P>(dest = dest, prop = prop, toString = { null }, fromString = { arrayListOf() }) -+{ -+ override fun toArgs(prefix: String): List = prop.get(dest).map { prefix + it } -+ fun add(s: String) { prop.get(dest).add(s) } -+} -+ -+// ------------------------------------------ -+ -+fun Iterable.filterExtractProps(propMappers: List>, prefix: String, restParser: RestPropMapper<*,*>? = null) : Iterable {","During the previous review I slightly rewrite this and something else, I hope this will be useful. -https://github.com/JetBrains/kotlin/commit/ef2ea84a85c3415fc9fa1c933e44c880df979d80#diff-4ff40116c0033e709c32c7abef5b2b0eR84 -",remove this emp -270,"@@ -0,0 +1,32 @@ -+/* -+ * 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.wrappers.symbols -+ -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.load.java.structure.JavaPrimitiveType -+import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType -+import javax.lang.model.type.TypeMirror -+ -+class SymbolBasedPrimitiveType(typeMirror: T,",Drop generic type parameter here and inherit from `SymbolBasedType<*>`,Shouldn't this -271,"@@ -0,0 +1,32 @@ -+/* -+ * 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.wrappers.symbols -+ -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.load.java.structure.JavaPrimitiveType -+import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType -+import javax.lang.model.type.TypeMirror -+ -+class SymbolBasedPrimitiveType(typeMirror: T, -+ javac: JavacWrapper) : SymbolBasedType(typeMirror, javac), JavaPrimitiveType { -+ -+ override val type -+ get() = with(typeMirror.toString()) { -+ if (""void"" == this) null else JvmPrimitiveType.get(this).primitiveType",Please inspect `TypeMirror.getKind` instead of `toString`,I would prefer -272,"@@ -0,0 +1,32 @@ -+/* -+ * 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.wrappers.trees -+ -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.tree.JCTree -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.load.java.structure.JavaPrimitiveType -+import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType -+ -+class TreeBasedPrimitiveType(tree: T, -+ treePath: TreePath, -+ javac: JavacWrapper) : TreeBasedType(tree, treePath, javac), JavaPrimitiveType { -+ -+ override val type -+ get() = if (""void"" == tree.toString()) null else JvmPrimitiveType.get(tree.toString()).primitiveType","Again, please inspect `tree.getKind()` instead of the string returned by `toString`","I would move this to `org.jetbrains.kotlin.resolve.jvm` package, and rename `TreeBasedPrimitiveType` to `JavaPrimitiveTypeTree`." -273,"@@ -0,0 +1,334 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.codeInsight.template.*; -+import com.intellij.openapi.editor.CaretModel; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.project.Project; -+import com.intellij.psi.PsiDocumentManager; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.util.PsiTreeUtil; -+import com.intellij.refactoring.rename.inplace.MyLookupExpression; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.descriptors.*; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.psi.*; -+import org.jetbrains.jet.lang.resolve.BindingContext; -+import org.jetbrains.jet.lang.resolve.name.Name; -+import org.jetbrains.jet.lang.types.JetType; -+import org.jetbrains.jet.lang.types.checker.JetTypeChecker; -+import org.jetbrains.jet.plugin.JetBundle; -+import org.jetbrains.jet.plugin.caches.resolve.KotlinCacheManagerUtil; -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; -+ -+import java.util.ArrayList; -+import java.util.Collection; -+import java.util.LinkedHashSet; -+import java.util.List; -+ -+public class SpecifySuperExplicitlyFix extends JetIntentionAction {","About functionality: -1. It's not good to give a user a partial functionality. -He would be surprised to find that the case 'super.foo()' is working, but 'super.foo().bar()' isn't. -2. I'd expect some choice which receiver I'd like to invoke here. -",No star imports please :) -274,"@@ -0,0 +1,334 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.codeInsight.template.*; -+import com.intellij.openapi.editor.CaretModel; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.project.Project; -+import com.intellij.psi.PsiDocumentManager; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.util.PsiTreeUtil; -+import com.intellij.refactoring.rename.inplace.MyLookupExpression; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.descriptors.*; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.psi.*; -+import org.jetbrains.jet.lang.resolve.BindingContext; -+import org.jetbrains.jet.lang.resolve.name.Name; -+import org.jetbrains.jet.lang.types.JetType; -+import org.jetbrains.jet.lang.types.checker.JetTypeChecker; -+import org.jetbrains.jet.plugin.JetBundle; -+import org.jetbrains.jet.plugin.caches.resolve.KotlinCacheManagerUtil; -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; -+ -+import java.util.ArrayList; -+import java.util.Collection; -+import java.util.LinkedHashSet; -+import java.util.List; -+ -+public class SpecifySuperExplicitlyFix extends JetIntentionAction { -+ private PsiElement elementToReplace; -+ private final LinkedHashSet options;","It's better to use less concrete types like Set or Collection here. (The following code should be independent of concrete implementation of collection to make it easy to change it later if necessary). -",No star imports please :) -275,"@@ -0,0 +1,334 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.codeInsight.template.*; -+import com.intellij.openapi.editor.CaretModel; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.project.Project; -+import com.intellij.psi.PsiDocumentManager; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.util.PsiTreeUtil; -+import com.intellij.refactoring.rename.inplace.MyLookupExpression; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.descriptors.*; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.psi.*; -+import org.jetbrains.jet.lang.resolve.BindingContext; -+import org.jetbrains.jet.lang.resolve.name.Name; -+import org.jetbrains.jet.lang.types.JetType; -+import org.jetbrains.jet.lang.types.checker.JetTypeChecker; -+import org.jetbrains.jet.plugin.JetBundle; -+import org.jetbrains.jet.plugin.caches.resolve.KotlinCacheManagerUtil; -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; -+ -+import java.util.ArrayList; -+import java.util.Collection; -+import java.util.LinkedHashSet; -+import java.util.List; -+ -+public class SpecifySuperExplicitlyFix extends JetIntentionAction { -+ private PsiElement elementToReplace; -+ private final LinkedHashSet options; -+ -+ -+ public SpecifySuperExplicitlyFix(@NotNull JetSuperExpression element, @NotNull LinkedHashSet options) { -+ super(element); -+ elementToReplace = element; -+ this.options = options; -+ } -+ -+ @NotNull -+ @Override -+ public String getText() { -+ return JetBundle.message(""specify.super.explicitly""); -+ } -+ -+ @NotNull -+ @Override -+ public String getFamilyName() { -+ return JetBundle.message(""specify.super.explicitly.family""); -+ } -+ -+ @Override -+ public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { -+ return !options.isEmpty(); -+ } -+ -+ @Override -+ public void invoke(@NotNull Project project, Editor editor, PsiFile file) {","Don't override 'Deprecated' method. -",No star imports please :) -276,"@@ -0,0 +1,334 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.codeInsight.template.*; -+import com.intellij.openapi.editor.CaretModel; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.project.Project; -+import com.intellij.psi.PsiDocumentManager; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.util.PsiTreeUtil; -+import com.intellij.refactoring.rename.inplace.MyLookupExpression; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.descriptors.*; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.psi.*; -+import org.jetbrains.jet.lang.resolve.BindingContext; -+import org.jetbrains.jet.lang.resolve.name.Name; -+import org.jetbrains.jet.lang.types.JetType; -+import org.jetbrains.jet.lang.types.checker.JetTypeChecker; -+import org.jetbrains.jet.plugin.JetBundle; -+import org.jetbrains.jet.plugin.caches.resolve.KotlinCacheManagerUtil; -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; -+ -+import java.util.ArrayList; -+import java.util.Collection; -+import java.util.LinkedHashSet; -+import java.util.List; -+ -+public class SpecifySuperExplicitlyFix extends JetIntentionAction { -+ private PsiElement elementToReplace; -+ private final LinkedHashSet options; -+ -+ -+ public SpecifySuperExplicitlyFix(@NotNull JetSuperExpression element, @NotNull LinkedHashSet options) { -+ super(element); -+ elementToReplace = element; -+ this.options = options; -+ } -+ -+ @NotNull -+ @Override -+ public String getText() { -+ return JetBundle.message(""specify.super.explicitly""); -+ } -+ -+ @NotNull -+ @Override -+ public String getFamilyName() { -+ return JetBundle.message(""specify.super.explicitly.family""); -+ } -+ -+ @Override -+ public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { -+ return !options.isEmpty(); -+ } -+ -+ @Override -+ public void invoke(@NotNull Project project, Editor editor, PsiFile file) { -+ elementToReplace = elementToReplace.replace(JetPsiFactory.createExpression(project, options.iterator().next())); -+ buildAndShowTemplate(project, editor, file, elementToReplace, options); -+ } -+ -+ public static JetIntentionActionFactory createFactory() { -+ return new JetIntentionActionFactory() { -+ @Nullable -+ @Override -+ public IntentionAction createAction(Diagnostic diagnostic) {","I'd rather divide this method into several smaller ones with meaningful names. -",No star imports please :) -277,"@@ -0,0 +1,334 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.codeInsight.template.*; -+import com.intellij.openapi.editor.CaretModel; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.project.Project; -+import com.intellij.psi.PsiDocumentManager; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.util.PsiTreeUtil; -+import com.intellij.refactoring.rename.inplace.MyLookupExpression; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.descriptors.*; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.psi.*; -+import org.jetbrains.jet.lang.resolve.BindingContext; -+import org.jetbrains.jet.lang.resolve.name.Name; -+import org.jetbrains.jet.lang.types.JetType; -+import org.jetbrains.jet.lang.types.checker.JetTypeChecker; -+import org.jetbrains.jet.plugin.JetBundle; -+import org.jetbrains.jet.plugin.caches.resolve.KotlinCacheManagerUtil; -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; -+ -+import java.util.ArrayList; -+import java.util.Collection; -+import java.util.LinkedHashSet; -+import java.util.List; -+ -+public class SpecifySuperExplicitlyFix extends JetIntentionAction { -+ private PsiElement elementToReplace; -+ private final LinkedHashSet options; -+ -+ -+ public SpecifySuperExplicitlyFix(@NotNull JetSuperExpression element, @NotNull LinkedHashSet options) { -+ super(element); -+ elementToReplace = element; -+ this.options = options; -+ } -+ -+ @NotNull -+ @Override -+ public String getText() { -+ return JetBundle.message(""specify.super.explicitly""); -+ } -+ -+ @NotNull -+ @Override -+ public String getFamilyName() { -+ return JetBundle.message(""specify.super.explicitly.family""); -+ } -+ -+ @Override -+ public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { -+ return !options.isEmpty(); -+ } -+ -+ @Override -+ public void invoke(@NotNull Project project, Editor editor, PsiFile file) { -+ elementToReplace = elementToReplace.replace(JetPsiFactory.createExpression(project, options.iterator().next())); -+ buildAndShowTemplate(project, editor, file, elementToReplace, options); -+ } -+ -+ public static JetIntentionActionFactory createFactory() { -+ return new JetIntentionActionFactory() { -+ @Nullable -+ @Override -+ public IntentionAction createAction(Diagnostic diagnostic) { -+ JetSuperExpression superExp = QuickFixUtil.getParentElementOfType(diagnostic, JetSuperExpression.class); -+ if (superExp == null) { -+ return null; -+ } -+ -+ JetClass klass = QuickFixUtil.getParentElementOfType(diagnostic, JetClass.class); -+ if (klass == null) { -+ return null; -+ } -+ -+ JetDelegationSpecifierList superClasses = PsiTreeUtil.getChildOfType(klass, JetDelegationSpecifierList.class); -+ if (superClasses == null) { -+ return null; -+ } -+ -+ //Used for checking visibility -+ BindingContext contextClasses = KotlinCacheManagerUtil.getDeclarationsFromProject(superExp).getBindingContext(); -+ ClassDescriptor fromClass = contextClasses.get(BindingContext.CLASS, klass); -+ if (fromClass == null) { -+ return null; -+ } -+ -+ //Fetch class descriptors for all super classes -+ LinkedHashSet superClassDescs = new LinkedHashSet(); -+ for (JetDelegationSpecifier delSpec : superClasses.getDelegationSpecifiers()) { -+ JetSimpleNameExpression jetRef = PsiTreeUtil.findChildOfType(delSpec.getTypeReference(), JetSimpleNameExpression.class); -+ if (jetRef == null) { -+ continue; -+ } -+ ClassDescriptor classDesc = resolveToClass(jetRef, contextClasses); -+ if (classDesc != null) { -+ superClassDescs.add(classDesc); -+ } -+ } -+ if (superClassDescs.isEmpty()) { -+ return null; -+ } -+ -+ //Get the name of the member in question and other access information. The super expression -+ //MUST be a part of a dot qualified expression. -+ JetDotQualifiedExpression dotExp = QuickFixUtil.getParentElementOfType(diagnostic, JetDotQualifiedExpression.class); -+ if (dotExp == null) { -+ return null; -+ } -+ JetExpression nextExp = dotExp; -+ JetExpression currentExp = null; -+ -+ ArrayList memberNames = new ArrayList(); -+ //contains a null in the index where the memberName at that same index is of a property. -+ ArrayList argsForFunction = new ArrayList(); -+ while (nextExp != null && (nextExp instanceof JetDotQualifiedExpression || nextExp instanceof JetArrayAccessExpression)) { -+ currentExp = nextExp; -+ String memberName; -+ JetValueArgumentList valArgs; -+ -+ if (currentExp instanceof JetDotQualifiedExpression) { -+ JetCallExpression call = PsiTreeUtil.getChildOfType(currentExp, JetCallExpression.class); -+ if (call != null) { -+ JetSimpleNameExpression name = PsiTreeUtil.getChildOfType(call, JetSimpleNameExpression.class); -+ if (name == null) { -+ return null; -+ } -+ memberName = name.getText(); -+ valArgs = call.getValueArgumentList(); -+ } -+ else { -+ JetSimpleNameExpression name = PsiTreeUtil.getChildOfType(currentExp, JetSimpleNameExpression.class); -+ if (name == null) { -+ return null; -+ } -+ memberName = name.getText(); -+ valArgs = null; -+ } -+ } -+ else { -+ //array indexing not supported for now. -+ return null; -+ /** -+ memberName = ""get""; //array indexing is the same as get function call -+ -+ JetContainerNode indexNode = ((JetArrayAccessExpression) currentExp).getIndicesNode(); -+ JetConstantExpression constant = PsiTreeUtil.getChildOfType(indexNode, JetConstantExpression.class); -+ JetReferenceExpression refIndex = PsiTreeUtil.getChildOfType(indexNode, JetReferenceExpression.class); -+ if (constant == null && refIndex == null) { -+ return null; -+ } -+ if (constant != null) { -+ valArgs = JetPsiFactory.createCallArguments(diagnostic.getPsiFile() -+ .getProject(), ""("" + constant.getText() + "")""); -+ } -+ else { -+ valArgs = JetPsiFactory.createCallArguments(diagnostic.getPsiFile() -+ .getProject(), ""("" + refIndex.getText() + "")""); -+ }**/ -+ } -+ memberNames.add(memberName); -+ argsForFunction.add(valArgs); -+ nextExp = PsiTreeUtil.getParentOfType(currentExp, JetExpression.class); -+ } -+ if (memberNames.isEmpty()) { -+ return null; -+ } -+ -+ //Right now, code has unexpected behavior with chained calls e.g. super.foo().bar.baz() so we just return null. -+ if (memberNames.size() > 1) { -+ return null; -+ } -+ -+ -+ //Get the expected type of the expression if applicable (e.g. var a : Int = super.foo) -+ BindingContext contextExpressions = AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) diagnostic.getPsiFile()) -+ .getBindingContext(); -+ JetProperty assignment = PsiTreeUtil.getParentOfType(currentExp, JetProperty.class); -+ JetType expectedJetType = null; -+ if (assignment != null) { -+ expectedJetType = contextExpressions.get(BindingContext.TYPE, assignment.getTypeRef()); -+ } -+ //TODO with Expected Type, if it is part of a return statement, look at return type of the function. -+ -+ LinkedHashSet options = new LinkedHashSet(); -+ for (ClassDescriptor classDesc : superClassDescs) { -+ //ClassDescriptor currentClassDesc = classDesc; -+ -+ boolean failed = false; -+ JetType returnType; -+ //for (int i = 0; i < memberNames.size(); i++) { -+ //should be currentClassDesc and .get(i)'s -+ returnType = memberNameAndArgsFound(classDesc, fromClass, memberNames.get(0), -+ argsForFunction.get(0), contextExpressions); -+ /* -+ if (returnType == null) { -+ failed = true; -+ break; -+ } -+ //Update the class from which we see the next member. -+ fromClass = currentClassDesc; -+ TODO deal with generic types (especially in arrays) as the return type. -+ currentClassDesc = DescriptorUtils.getClassDescriptorForType(returnType); -+ }*/ -+ if (!failed && returnType != null && -+ (expectedJetType == null || JetTypeChecker.INSTANCE.isSubtypeOf(returnType, expectedJetType))) { -+ options.add(""super<"" + classDesc.getName().getIdentifier() + "">""); -+ } -+ } -+ return new SpecifySuperExplicitlyFix(superExp, options); -+ } -+ }; -+ } -+ -+ /*returns null if false or error occured*/ -+ private static JetType memberNameAndArgsFound(@NotNull ClassDescriptor classDesc, @NotNull ClassDescriptor fromClass,","Please annotate return type as Nullable if a method may return null. -The method name should explain what this method does (better using some verbs like 'do something') and what it returns ('memberNameAndArgsFound' returning JetType is unclear). -",No star imports please :) -278,"@@ -0,0 +1,334 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.codeInsight.template.*; -+import com.intellij.openapi.editor.CaretModel; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.project.Project; -+import com.intellij.psi.PsiDocumentManager; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.util.PsiTreeUtil; -+import com.intellij.refactoring.rename.inplace.MyLookupExpression; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.descriptors.*; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.psi.*; -+import org.jetbrains.jet.lang.resolve.BindingContext; -+import org.jetbrains.jet.lang.resolve.name.Name; -+import org.jetbrains.jet.lang.types.JetType; -+import org.jetbrains.jet.lang.types.checker.JetTypeChecker; -+import org.jetbrains.jet.plugin.JetBundle; -+import org.jetbrains.jet.plugin.caches.resolve.KotlinCacheManagerUtil; -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; -+ -+import java.util.ArrayList; -+import java.util.Collection; -+import java.util.LinkedHashSet; -+import java.util.List; -+ -+public class SpecifySuperExplicitlyFix extends JetIntentionAction { -+ private PsiElement elementToReplace; -+ private final LinkedHashSet options; -+ -+ -+ public SpecifySuperExplicitlyFix(@NotNull JetSuperExpression element, @NotNull LinkedHashSet options) { -+ super(element); -+ elementToReplace = element; -+ this.options = options; -+ } -+ -+ @NotNull -+ @Override -+ public String getText() { -+ return JetBundle.message(""specify.super.explicitly""); -+ } -+ -+ @NotNull -+ @Override -+ public String getFamilyName() { -+ return JetBundle.message(""specify.super.explicitly.family""); -+ } -+ -+ @Override -+ public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { -+ return !options.isEmpty(); -+ } -+ -+ @Override -+ public void invoke(@NotNull Project project, Editor editor, PsiFile file) { -+ elementToReplace = elementToReplace.replace(JetPsiFactory.createExpression(project, options.iterator().next())); -+ buildAndShowTemplate(project, editor, file, elementToReplace, options); -+ } -+ -+ public static JetIntentionActionFactory createFactory() { -+ return new JetIntentionActionFactory() { -+ @Nullable -+ @Override -+ public IntentionAction createAction(Diagnostic diagnostic) { -+ JetSuperExpression superExp = QuickFixUtil.getParentElementOfType(diagnostic, JetSuperExpression.class); -+ if (superExp == null) { -+ return null; -+ } -+ -+ JetClass klass = QuickFixUtil.getParentElementOfType(diagnostic, JetClass.class); -+ if (klass == null) { -+ return null; -+ } -+ -+ JetDelegationSpecifierList superClasses = PsiTreeUtil.getChildOfType(klass, JetDelegationSpecifierList.class); -+ if (superClasses == null) { -+ return null; -+ } -+ -+ //Used for checking visibility -+ BindingContext contextClasses = KotlinCacheManagerUtil.getDeclarationsFromProject(superExp).getBindingContext(); -+ ClassDescriptor fromClass = contextClasses.get(BindingContext.CLASS, klass); -+ if (fromClass == null) { -+ return null; -+ } -+ -+ //Fetch class descriptors for all super classes -+ LinkedHashSet superClassDescs = new LinkedHashSet(); -+ for (JetDelegationSpecifier delSpec : superClasses.getDelegationSpecifiers()) { -+ JetSimpleNameExpression jetRef = PsiTreeUtil.findChildOfType(delSpec.getTypeReference(), JetSimpleNameExpression.class); -+ if (jetRef == null) { -+ continue; -+ } -+ ClassDescriptor classDesc = resolveToClass(jetRef, contextClasses); -+ if (classDesc != null) { -+ superClassDescs.add(classDesc); -+ } -+ } -+ if (superClassDescs.isEmpty()) { -+ return null; -+ } -+ -+ //Get the name of the member in question and other access information. The super expression -+ //MUST be a part of a dot qualified expression. -+ JetDotQualifiedExpression dotExp = QuickFixUtil.getParentElementOfType(diagnostic, JetDotQualifiedExpression.class); -+ if (dotExp == null) { -+ return null; -+ } -+ JetExpression nextExp = dotExp; -+ JetExpression currentExp = null; -+ -+ ArrayList memberNames = new ArrayList(); -+ //contains a null in the index where the memberName at that same index is of a property. -+ ArrayList argsForFunction = new ArrayList(); -+ while (nextExp != null && (nextExp instanceof JetDotQualifiedExpression || nextExp instanceof JetArrayAccessExpression)) { -+ currentExp = nextExp; -+ String memberName; -+ JetValueArgumentList valArgs; -+ -+ if (currentExp instanceof JetDotQualifiedExpression) { -+ JetCallExpression call = PsiTreeUtil.getChildOfType(currentExp, JetCallExpression.class); -+ if (call != null) { -+ JetSimpleNameExpression name = PsiTreeUtil.getChildOfType(call, JetSimpleNameExpression.class); -+ if (name == null) { -+ return null; -+ } -+ memberName = name.getText(); -+ valArgs = call.getValueArgumentList(); -+ } -+ else { -+ JetSimpleNameExpression name = PsiTreeUtil.getChildOfType(currentExp, JetSimpleNameExpression.class); -+ if (name == null) { -+ return null; -+ } -+ memberName = name.getText(); -+ valArgs = null; -+ } -+ } -+ else { -+ //array indexing not supported for now. -+ return null; -+ /** -+ memberName = ""get""; //array indexing is the same as get function call -+ -+ JetContainerNode indexNode = ((JetArrayAccessExpression) currentExp).getIndicesNode(); -+ JetConstantExpression constant = PsiTreeUtil.getChildOfType(indexNode, JetConstantExpression.class); -+ JetReferenceExpression refIndex = PsiTreeUtil.getChildOfType(indexNode, JetReferenceExpression.class); -+ if (constant == null && refIndex == null) { -+ return null; -+ } -+ if (constant != null) { -+ valArgs = JetPsiFactory.createCallArguments(diagnostic.getPsiFile() -+ .getProject(), ""("" + constant.getText() + "")""); -+ } -+ else { -+ valArgs = JetPsiFactory.createCallArguments(diagnostic.getPsiFile() -+ .getProject(), ""("" + refIndex.getText() + "")""); -+ }**/ -+ } -+ memberNames.add(memberName); -+ argsForFunction.add(valArgs); -+ nextExp = PsiTreeUtil.getParentOfType(currentExp, JetExpression.class); -+ } -+ if (memberNames.isEmpty()) { -+ return null; -+ } -+ -+ //Right now, code has unexpected behavior with chained calls e.g. super.foo().bar.baz() so we just return null. -+ if (memberNames.size() > 1) { -+ return null; -+ } -+ -+ -+ //Get the expected type of the expression if applicable (e.g. var a : Int = super.foo) -+ BindingContext contextExpressions = AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) diagnostic.getPsiFile()) -+ .getBindingContext(); -+ JetProperty assignment = PsiTreeUtil.getParentOfType(currentExp, JetProperty.class); -+ JetType expectedJetType = null; -+ if (assignment != null) { -+ expectedJetType = contextExpressions.get(BindingContext.TYPE, assignment.getTypeRef()); -+ } -+ //TODO with Expected Type, if it is part of a return statement, look at return type of the function. -+ -+ LinkedHashSet options = new LinkedHashSet(); -+ for (ClassDescriptor classDesc : superClassDescs) { -+ //ClassDescriptor currentClassDesc = classDesc; -+ -+ boolean failed = false; -+ JetType returnType; -+ //for (int i = 0; i < memberNames.size(); i++) { -+ //should be currentClassDesc and .get(i)'s -+ returnType = memberNameAndArgsFound(classDesc, fromClass, memberNames.get(0), -+ argsForFunction.get(0), contextExpressions); -+ /* -+ if (returnType == null) { -+ failed = true; -+ break; -+ } -+ //Update the class from which we see the next member. -+ fromClass = currentClassDesc; -+ TODO deal with generic types (especially in arrays) as the return type. -+ currentClassDesc = DescriptorUtils.getClassDescriptorForType(returnType); -+ }*/ -+ if (!failed && returnType != null && -+ (expectedJetType == null || JetTypeChecker.INSTANCE.isSubtypeOf(returnType, expectedJetType))) { -+ options.add(""super<"" + classDesc.getName().getIdentifier() + "">""); -+ } -+ } -+ return new SpecifySuperExplicitlyFix(superExp, options); -+ } -+ }; -+ } -+ -+ /*returns null if false or error occured*/ -+ private static JetType memberNameAndArgsFound(@NotNull ClassDescriptor classDesc, @NotNull ClassDescriptor fromClass, -+ @NotNull String memberName, -+ @Nullable JetValueArgumentList valArgs, @NotNull BindingContext contextExpressions) { -+ if (valArgs == null) { -+ Collection varDescs = classDesc.getMemberScope(classDesc.getDefaultType().getArguments()) -+ .getProperties(Name.identifier(memberName)); -+ return memberNamePropFound(classDesc, fromClass, varDescs); -+ } -+ else { -+ Collection funDescs = classDesc.getMemberScope(classDesc.getDefaultType().getArguments()) -+ .getFunctions(Name.identifier(memberName)); -+ return memberNameFuncFound(fromClass, funDescs, valArgs, contextExpressions); -+ -+ } -+ } -+ -+ private static JetType memberNameFuncFound(@NotNull ClassDescriptor fromClass, -+ @NotNull Collection funDescs, -+ @NotNull JetValueArgumentList valArgs, @NotNull BindingContext contextExpressions) { -+ for (FunctionDescriptor fun : funDescs) { -+ if (fun.getModality() == Modality.ABSTRACT || !fun.getKind().isReal() || -+ !Visibilities.isVisible(fun, fromClass)) { -+ continue; -+ } -+ List valParams = fun.getValueParameters(); -+ List jValArgs = valArgs.getArguments(); -+ if (jValArgs.size() != valParams.size()) { -+ continue; -+ } -+ boolean argTypesMatch = true; -+ for (int j = 0; j < valParams.size(); j++) { -+ JetExpression expr = jValArgs.get(j).getArgumentExpression(); -+ JetType subtype = contextExpressions.get(BindingContext.EXPRESSION_TYPE, expr); -+ if (subtype == null || !JetTypeChecker.INSTANCE.isSubtypeOf(subtype, valParams.get(j).getType())) { -+ argTypesMatch = false; -+ break; -+ } -+ } -+ if (!argTypesMatch) { -+ continue; -+ } -+ return fun.getReturnType(); -+ } -+ return null; -+ } -+ -+ private static JetType memberNamePropFound(@NotNull ClassDescriptor classDesc, @NotNull ClassDescriptor fromClass, -+ @NotNull Collection varDescs) { -+ for (VariableDescriptor var : varDescs) { -+ if (classDesc.getKind() != ClassKind.TRAIT && Visibilities.isVisible(var, fromClass)) { -+ return var.getType(); -+ } -+ } -+ return null; -+ } -+ -+ /*Taken and modified from MapPlatformClassToKotlinFix*/","You shouldn't copy code. You may change this method in its class or/and move it to util instead. -",No star imports please :) -279,"@@ -0,0 +1,34 @@ -+# Class Literals as Annotation Arguments -+ -+Prior to M12 Kotlin annotation allowed parameters of type `java.lang.Class<...>` whose values could be of the form `javaClass<...>()`. -+Since M12 both these options are deprecated, and subject to deletion in further milestones. -+ -+## Annotation Parameters -+ -+Annotation parameters of type `java.lang.Class` are deprecated. -+ -+Annotation parameters of type `kotlin.reflect.KClass` are supported. -+ -+A quick-fix transforming one into the other is provided. -+ -+## Annotation Arguments -+ -+Arguments of the form `javaClass()` are deprecated. -+ -+Arguments of teh form `ClassName::class` are supported.","teh -> the -",I think the first sentence is superfluous. -280,"@@ -0,0 +1,34 @@ -+# Class Literals as Annotation Arguments -+ -+Prior to M12 Kotlin annotation allowed parameters of type `java.lang.Class<...>` whose values could be of the form `javaClass<...>()`. -+Since M12 both these options are deprecated, and subject to deletion in further milestones. -+ -+## Annotation Parameters -+ -+Annotation parameters of type `java.lang.Class` are deprecated. -+ -+Annotation parameters of type `kotlin.reflect.KClass` are supported. -+ -+A quick-fix transforming one into the other is provided. -+ -+## Annotation Arguments -+ -+Arguments of the form `javaClass()` are deprecated. -+ -+Arguments of teh form `ClassName::class` are supported. -+ -+A quick-fix transforming one into the other is provided. -+ -+## Loading Annotation Classes from Java -+ -+Java annotation `@interfaces` may declare methods of type `java.lang.Class`. And on the JVM this is the only representation we can compile our annotations to. These should be processed specially and mapped to `kotlin.reflect.KClass`. At the call sites for annotations delcared in Kotlin as well as in Java, when a property of type `KClass` is accessed, we have to map its value from `java.lang.Class` to `kotlin.reflect.KClass`. Same needs to happen when we access those properties through reflection.","delcared -> declared -",I would add a note that these arguments are deprecated. -281,"@@ -0,0 +1,34 @@ -+# Class Literals as Annotation Arguments -+ -+Prior to M12 Kotlin annotation allowed parameters of type `java.lang.Class<...>` whose values could be of the form `javaClass<...>()`. -+Since M12 both these options are deprecated, and subject to deletion in further milestones. -+ -+## Annotation Parameters -+ -+Annotation parameters of type `java.lang.Class` are deprecated. -+ -+Annotation parameters of type `kotlin.reflect.KClass` are supported. -+ -+A quick-fix transforming one into the other is provided. -+ -+## Annotation Arguments -+ -+Arguments of the form `javaClass()` are deprecated. -+ -+Arguments of teh form `ClassName::class` are supported. -+ -+A quick-fix transforming one into the other is provided. -+ -+## Loading Annotation Classes from Java -+ -+Java annotation `@interfaces` may declare methods of type `java.lang.Class`. And on the JVM this is the only representation we can compile our annotations to. These should be processed specially and mapped to `kotlin.reflect.KClass`. At the call sites for annotations delcared in Kotlin as well as in Java, when a property of type `KClass` is accessed, we have to map its value from `java.lang.Class` to `kotlin.reflect.KClass`. Same needs to happen when we access those properties through reflection. -+ -+> This is unprecedented in Kotlin: never before we mapped a Java class to another *real* class, all mappings we had before were fictitious, e.g. existed at compile time only. -+ -+Since it is likely to be rather common that the value of an annotation property will only be used to retrieve an instance of `java.lang.Class`, e.g. `annInstance.implClass.java`, to avoid runtime overhead, we should optimize such cases in the JVM back-end by skipping the steps of converting a `java.lamg.Class` to `KClass` and then back. -+","lamg -> lang -",Line is too long. [81/80] -282,"@@ -0,0 +1,34 @@ -+/* -+ * 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.idea.intentions -+ -+import com.intellij.codeInspection.CleanupLocalInspectionTool -+import com.intellij.codeInspection.ProblemHighlightType -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection -+import org.jetbrains.kotlin.psi.KtClassBody -+ -+class RemoveEmptyClassBodyInspection : IntentionBasedInspection(RemoveEmptyClassBodyIntention::class), CleanupLocalInspectionTool {","If you want your inspection to run as part of code cleanup, you need to specify cleanupTool=""true"" in its XML registration. -",This file needs to be renamed to removeEmptyClassBodyIntention. -283,"@@ -0,0 +1,34 @@ -+/* -+ * 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.effectsystem.adapters -+ -+import org.jetbrains.kotlin.effectsystem.structure.ConstantID -+import org.jetbrains.kotlin.effectsystem.structure.ESValueID -+import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue -+ -+class DataFlowValueID(val dfv: DataFlowValue) : ESValueID {",Not quite sure this wrapper is needed. Can `DataFlowValue` itself serve you here?,Maybe we should rename this class to `DataFlowValueAdapter`? -284,"@@ -0,0 +1,34 @@ -+/* -+ * 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.wrappers.symbols -+ -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter -+import org.jetbrains.kotlin.name.SpecialNames -+import javax.lang.model.element.TypeParameterElement -+import javax.lang.model.type.TypeVariable -+ -+class SymbolBasedTypeParameter(element: T, -+ javac: JavacWrapper) : SymbolBasedClassifier(element, javac), JavaTypeParameter { -+ -+ override val name -+ get() = SpecialNames.safeIdentifier(element.simpleName.toString())",`Name.identifier`,remove the default assignment? -285,"@@ -0,0 +1,34 @@ -+/* -+ * 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.wrappers.symbols -+ -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter -+import org.jetbrains.kotlin.name.SpecialNames -+import javax.lang.model.element.TypeParameterElement -+import javax.lang.model.type.TypeVariable -+ -+class SymbolBasedTypeParameter(element: T, -+ javac: JavacWrapper) : SymbolBasedClassifier(element, javac), JavaTypeParameter { -+ -+ override val name -+ get() = SpecialNames.safeIdentifier(element.simpleName.toString()) -+ -+ override val upperBounds -+ get() = listOf(SymbolBasedClassifierType((element.asType() as TypeVariable).upperBound, javac))",I think you should handle the case of `IntersectionType` here by expanding it into multiple bounds. `TypeVariable.getUpperBound`'s javadoc implies that this is possible here.,"Let's not call `toString()` on `element`. If the `asType()` returns `Object`, then `asType().toString()` will return `Object#toS" -286,"@@ -0,0 +1,342 @@ -+# Function Types in Kotlin on JVM -+ -+## Goals -+ -+* Get rid of 23 hardwired physical function classes. The problem with them is, -+reflection introduces a few kinds of functions but each of them should be invokable as a normal function as well, and so -+we get `{top-level, member, extension, member-extension, local, ...} * 23` = **a lot** of physical classes in the runtime. -+* Make extension functions coercible to normal functions (with an extra parameter). -+At the moment it's not possible to do `listOfStrings.map(String::length)` -+* Allow functions with more than 23 parameters, theoretically any number of parameters (in practice 255 on JVM). -+* At the same time, allow to implement Kotlin functions easily from Java: `new Function2() { ... }` and overriding `invoke` only would be the best. -+Enabling SAM conversions on Java 8 would also be terrific. -+ -+## Brief solution overview -+ -+* Treat extension functions almost like non-extension functions with one extra parameter, allowing to use them almost interchangeably. -+* Introduce a physical class `Function` and unlimited number of *fictitious* (synthetic) classes `Function0`, `Function1`, ... in the compiler front-end -+* On JVM, introduce `Function0`..`Function22`, which are optimized in a certain way, -+and `FunctionN` for functions with 23+ parameters. -+When passing a lambda to Kotlin from Java, one will need to implement one of these interfaces. -+* Also on JVM (under the hood) add abstract `FunctionImpl` which implements all of `Fun0`..`Fun22` and `FunN` -+(throwing exceptions), and which knows its arity. -+Kotlin lambdas are translated to subclasses of this abstract class, passing the correct arity to the super constructor. -+* Provide a way to get arity of an arbitrary `Function` object (pretty straightforward). -+* Hack `is/as Function5` on any numbered function in codegen (and probably `KClass.cast()` in reflection) to check against `Function` and its arity. -+ -+## Extension functions -+ -+Extension function type `T.(P) -> R` is now just a shorthand for `[kotlin.extension] Function2`. -+`kotlin.extension` is a **type annotation** defined in built-ins. -+So effectively functions and extension functions now have the same type, -+how can we make extension function expressions support extension function call syntax? -+ -+We introduce the following convention: expression `foo` of type `Foo` can be used as an extension function -+(i.e. `object.foo(arguments)`) if and only if there is a function `invokeExtension` -+with the corresponding parameters available on the type `Foo`. -+This function may be declared in class `Foo` or somewhere as an extension to `Foo`. -+ -+> Note that at the moment a less convenient convention is used: there must be a **member extension** -+> function `invoke` in the class which you want to be used as an extension function. -+> This means you can't add ""extension-function-ness"" to a foreign class, -+> since you'd need to declare a function with two receivers. -+> The new approach will solve this problem. -+ -+We declare `invokeExtension` to be available on all extension functions: -+ -+``` kotlin -+package kotlin -+ -+... -+fun (T.() -> R).invokeExtension(): R = this() -+fun (T.(P1) -> R).invokeExtension(p1: P1): R = this(p1) -+... -+``` -+ -+So now an expression type-checked to an ""extension function type"" can be used with the desired syntax. -+But, since a function type and a corresponding extension function type effectively have the same classifier (e.g. `Function7`), -+they are coercible to each other and therefore our `invokeExtension` will be applicable to the usual -+functions as well, which is something we don't want to happen! Example: -+ -+``` kotlin -+val lengthHacked: (String) -> Int = { it.length } -+ -+fun test() = """".lengthHacked() // <-- bad! The declared function accepts a single non-receiver argument -+ // and is not designed to be invoked as an extension -+``` -+ -+And here we introduce the following **restriction**: given a call `object.foo(arguments)`, -+if `foo` is resolved **exactly** to the built-in extension function `invokeExtension`, -+then the call *will not compile* unless the receiver type is annotated with `[extension]`. -+So `invokeExtension` will yield an error when used on a normal (not extension) function. -+ -+To make your class invokable as an extension you only need to declare `invokeExtension`. -+Declaring `invoke` (and maybe overriding it from the needed function class) will only make your class invokable *as a usual function*. -+Inheriting from a function type thus makes sense if you want your class to behave like a simple function. -+Inheriting from an extension function type however makes no sense and should be prohibited / frowned upon. -+In a broad sense, providing type annotations on supertypes (which is what inheriting from an extension function is) -+maybe should be diagnosed in the compiler (maybe not, more knowledge needed). -+ -+With this we'll get rid of classes `ExtensionFunction0`, `ExtensionFunction1`, ... -+and the rest of this article will deal only with usual functions. -+ -+## Function0, Function1, ... types -+ -+The arity of the functional trait that the type checker can create in theory **is not limited** to any number, -+but in practice should be limited to 255 on JVM. -+ -+These traits are named `kotlin.Function0`, `kotlin.Function1`, ..., `kotlin.Function42`, ... -+They are *fictitious*, which means they have no sources and no runtime representation. -+Type checker creates the corresponding descriptors on demand, IDE creates corresponding source files on demand as well. -+Each of them inherits from `kotlin.Function` (described below) and contains a single -+`fun invoke()` with the corresponding number of parameters and return type. -+ -+> TODO: investigate exactly what changes in IDE should be done and if they are possible at all. -+ -+On JVM function types are erased to the physical classes defined in package `kotlin.jvm.internal`: -+`Function0`, `Function1`, ..., `Function22` and `FunctionN` for 23+ parameters. -+ -+## Function trait -+ -+There's also an empty trait `kotlin.Function` for cases when e.g. you're storing functions with different/unknown arity -+in a collection to invoke them reflectively somewhere else. -+ -+``` kotlin -+package kotlin -+ -+trait Function -+``` -+ -+It's a physical trait, declared in platform-agnostic built-ins, and present in `kotlin-runtime.jar` for example. -+However its declaration is **empty** and should be empty because every physical JVM function class `Function0`, `Function1`, ... -+inherits from it (and adds `invoke()`), and we don't want to override anything besides `invoke()` when doing it from Java code. -+ -+## Functions with 0..22 parameters at runtime -+ -+There are 23 function traits in `kotlin.platform.jvm`: `Function0`, `Function1`, ..., `Function22`. -+Here's `Function1` declaration, for example: -+ -+``` kotlin -+package kotlin.platform.jvm -+ -+trait Function1 : kotlin.Function { -+ fun invoke(p1: P1): R -+} -+``` -+ -+These traits are supposed to be inherited from by Java classes when passing lambdas to Kotlin. -+ -+Package `kotlin.platform.jvm` is supposed to contain interfaces which help use Kotlin from Java. -+(And not from Kotlin, because normally you would use a function type there, -+most of the time even without mentioning built-in function classes: `(P1, P2, P3) -> R`.) -+ -+## Translation of Kotlin lambdas -+ -+There's also `FunctionImpl` abstract class at runtime which helps in implementing `arity` and vararg-invocation. -+It inherits from all the physical function classes, unfortunately (more on that later). -+ -+``` kotlin -+package kotlin.jvm.internal -+ -+abstract class FunctionImpl(override val arity: Int) : -+ Function, -+ Function0, Function1, ..., ..., Function22<...>, -+ FunctionN // See the next section on FunctionN -+{ -+ override fun invoke(): Any? { -+ // Default implementations of all ""invoke""s invoke ""invokeVararg"" -+ // This is needed for KFunctionImpl (see below) -+ assert(arity == 0) -+ return invokeVararg() -+ } -+ -+ override fun invoke(p1: Any?): Any? { -+ assert(arity == 1) -+ return invokeVararg(p1) -+ } -+ -+ ... -+ override fun invoke(p1: Any?, ..., p22: Any?) { ... } -+ -+ override fun invokeVararg(vararg p: Any?): Any? = throw UnsupportedOperationException() -+ -+ override fun toString() = ... // Some calculation involving generic runtime signatures -+} -+``` -+ -+> TODO: sadly, this class needs to be implemented in Java because supertypes need to be **raw** classes -+> for reflection to pick up correct generic signatures for inheritors -+ -+Each lambda is compiled to an anonymous class which inherits from `FunctionImpl` and implements the corresponding `invoke`: -+ -+``` kotlin -+{ (s: String): Int -> s.length } -+ -+// is translated to -+ -+object : FunctionImpl(2), Function2 {","Doesn't `Function2` have 3 type parameters (2 for parameter types and 1 for return type)? -",Is there an advantage to using `map` over `map(String::length)`? -287,"@@ -0,0 +1,35 @@ -+/* -+ * 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.wrappers.symbols -+ -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.load.java.structure.JavaClassifierType -+import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter -+import org.jetbrains.kotlin.name.SpecialNames -+import javax.lang.model.element.TypeParameterElement -+import javax.lang.model.type.TypeVariable -+ -+class JavacTypeParameter(element: T, -+ javac: Javac) : JavacClassifier(element, javac), JavaTypeParameter { -+ -+ override val name -+ get() = SpecialNames.safeIdentifier(element.simpleName.toString()) -+ -+ override val upperBounds: Collection -+ get() = listOf(JavacClassifierType((element.asType() as TypeVariable).upperBound, javac)) -+","In NB plugin, `equals` & `hashCode` are also implemented for this class. Should we have them here?","I don't think you need `asType()` here, since `TypeParameterElement` has `asType()`." -288,"@@ -0,0 +1,36 @@ -+/* -+ * 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.effectsystem.structure -+ -+/** -+ * An abstraction of effect-generating nature of some operation. -+ * -+ * [ESFunctor] roughly corresponds to some call, but it cares only -+ * about effects of this call, so instead of value arguments, its [apply] -+ * method takes just description of effects of each argument -+ * (represented by [EffectSchema]), and produces effects of the whole call -+ * (instead of some value, compared to usual calls). -+ * -+ * Implementors should never produce non-conservative effects. -+ * However, they are not obliged to produce most precise description -+ * of effects, though they are encouraged to do so. -+ */ -+ -+interface ESFunctor {",May be it's better to move this into `functors` package,Should it be `[ESFunctor]`? -289,"@@ -0,0 +1,36 @@ -+/* -+ * 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.wrappers.symbols -+ -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.load.java.structure.JavaWildcardType -+import javax.lang.model.type.TypeMirror -+import javax.lang.model.type.WildcardType -+ -+class JavacWildcardType(typeMirror: T, -+ javac: Javac) : JavacType(typeMirror, javac), JavaWildcardType { -+ -+ override val bound -+ get() = typeMirror.let { -+ val boundMirror = (it as WildcardType).extendsBound ?: it.superBound -+ -+ if (boundMirror != null) create(boundMirror, javac) else null","`boundMirror.let { create(it, javac) }`",missing new line -290,"@@ -0,0 +1,36 @@ -+/* -+ * 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.wrappers.symbols -+ -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.load.java.structure.JavaWildcardType -+import javax.lang.model.type.TypeMirror -+import javax.lang.model.type.WildcardType -+ -+class SymbolBasedWildcardType(typeMirror: T,",Looks like generic type parameter `T` is not needed here as well. This class should just inherit from `SymbolBasedType` and `typeMirror` should have the type `WildcardType`,missing new line. -291,"@@ -0,0 +1,38 @@ -+/* -+ * 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.wrappers.symbols -+ -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.load.java.structure.JavaAnnotation -+import org.jetbrains.kotlin.load.java.structure.JavaElement -+import org.jetbrains.kotlin.name.Name -+import javax.lang.model.element.AnnotationMirror -+import javax.lang.model.element.TypeElement -+ -+open class SymbolBasedAnnotation(val annotationMirror: AnnotationMirror, -+ val javac: JavacWrapper) : JavaElement, JavaAnnotation { -+ -+ override val arguments -+ get() = annotationMirror.elementValues -+ .map { SymbolBasedAnnotationArgument.create(it.value.value, Name.identifier(it.key.simpleName.toString()), javac) }","`.map { (key, value) -> ... }`",missing new line -292,"@@ -0,0 +1,39 @@ -+/* -+ * 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.javac -+ -+import com.sun.tools.javac.util.Options -+import java.util.regex.Pattern -+ -+object JavacOptionsMapper { -+ -+ fun map(options: Options, arguments: List) = arguments.forEach { options.putOption(it) }","Please don't use expression body syntax for `Unit`-returning functions, it's slightly confusing (I was figuring out what does this function return)",Add a brief description of -293,"@@ -0,0 +1,39 @@ -+/* -+ * 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.javac -+ -+import com.sun.tools.javac.util.Options -+import java.util.regex.Pattern -+ -+object JavacOptionsMapper { -+ -+ fun map(options: Options, arguments: List) = arguments.forEach { options.putOption(it) } -+ -+ private val optionPattern by lazy { Pattern.compile(""\\s+"") }",There's no need to make it lazy (it will be accessed anyway any time `JavacOptionsMapper.map` is called),Add a doc string about the -294,"@@ -0,0 +1,39 @@ -+/* -+ * 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.javac -+ -+import com.sun.tools.javac.util.Options -+import java.util.regex.Pattern -+ -+object JavacOptionsMapper { -+ -+ fun map(options: Options, arguments: List) = arguments.forEach { options.putOption(it) } -+ -+ private val optionPattern by lazy { Pattern.compile(""\\s+"") } -+ -+ private fun Options.putOption(option: String) = option -+ .split(optionPattern) -+ .filter { it.isNotEmpty() } -+ .let { arg -> -+ when(arg.size) { -+ 1 -> put(arg[0], arg[0]) -+ 2 -> put(arg[0], arg[1]) -+ else -> null","`else -> null` is not needed here, I think",missing new line at the end -295,"@@ -0,0 +1,39 @@ -+/* -+ * 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.wrappers.symbols -+ -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.load.java.structure.JavaAnnotationOwner -+import org.jetbrains.kotlin.load.java.structure.JavaClassifier -+import org.jetbrains.kotlin.name.FqName -+import javax.lang.model.element.Element -+ -+abstract class SymbolBasedClassifier(element: T, -+ javac: JavacWrapper) : SymbolBasedElement(element, javac), JavaClassifier, JavaAnnotationOwner { -+ -+ override val annotations -+ get() = element.annotationMirrors -+ .map { SymbolBasedAnnotation(it, javac) } -+ -+ override fun findAnnotation(fqName: FqName) = element.annotationMirrors -+ .find { it.toString() == ""@${fqName.asString()}"" }","Please avoid using `toString` in this way in production code. I don't see anything in `TypeMirror.toString`'s javadoc that would suggest that the returned string is equal to `@` + annotation type's FQ name, which means that it can change between releases. I think inspecting the type directly via `AnnotationMirror.getAnnotationType` would be more robust",missing a line break here. -296,"@@ -0,0 +1,39 @@ -+/* -+ * 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.wrappers.trees -+ -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.tree.JCTree -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.load.java.structure.JavaAnnotation -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.java.structure.JavaMember -+import org.jetbrains.kotlin.name.FqName -+ -+abstract class JCMember(tree: T, -+ treePath: TreePath, -+ override val containingClass: JavaClass, -+ javac: Javac) : JCElement(tree, treePath, javac), JavaMember { -+ -+ override val isDeprecatedInJavaDoc = false -+ -+ override val annotations -+ get() = emptyList() -+ -+ override fun findAnnotation(fqName: FqName) = annotations.firstOrNull { it.classId?.asSingleFqName() == fqName }","Again, what do you want to find in the empty list?",Would it make sense to have -297,"@@ -0,0 +1,4 @@ -+// ERROR: Too many arguments for public final fun get(index: kotlin.Int): kotlin.Int defined in kotlin.Array","I can't seem to fix the source of this error, so I declared it. -",Do we have a test case for -298,"@@ -0,0 +1,4 @@ -+// ERROR: Too many arguments for public final fun get(index: kotlin.Int): kotlin.Int defined in kotlin.Array -+fun foo(a: Array, i: Int) { -+ a[i, { }]","This wouldn't work unless the second argument was a function. Is it still possible to give multiple indices to this construct (i.e, `a[i, 2]`)? -",The problem with this is th -299,"@@ -0,0 +1,4 @@ -+// ERROR: Unresolved reference: !in","I don't understand this error. -",Why did you add this error? -300,"@@ -0,0 +1,4 @@ -+// IS_APPLICABLE: false -+fun foo(x: Foo?) { -+ x!!.get(1) -+}","Why not applicable here? `x!![1]` looks pretty okay -",Is this test case going to -301,"@@ -0,0 +1,40 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.project.Project; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.jet.lang.psi.JetClass; -+import org.jetbrains.jet.lang.psi.JetFile; -+import org.jetbrains.jet.lang.psi.JetPsiFactory; -+import org.jetbrains.jet.plugin.JetBundle;","A lot of not optimized imports. -When committing, check that you your code is green (no warnings). If you edit some code, assure that you don't introduce new warnings. -",Make sure the copyright hea -302,"@@ -0,0 +1,40 @@ -+/* -+ * 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.rmi.kotlinr -+ -+import org.jetbrains.kotlin.incremental.components.LookupTracker -+import org.jetbrains.kotlin.incremental.components.ScopeKind -+import org.jetbrains.kotlin.rmi.CompileService -+import org.jetbrains.kotlin.rmi.LoopbackNetworkInterface -+import org.jetbrains.kotlin.rmi.SOCKET_ANY_FREE_PORT -+import java.rmi.server.UnicastRemoteObject -+ -+ -+public class RemoteLookupTrackerServer(val base: LookupTracker, port: Int = SOCKET_ANY_FREE_PORT) : CompileService.RemoteLookupTracker { -+ -+ init { -+ UnicastRemoteObject.exportObject(this, port, LoopbackNetworkInterface.clientLoopbackSocketFactory, LoopbackNetworkInterface.serverLoopbackSocketFactory) -+ } -+ -+ override fun record(lookupContainingFile: String, lookupLine: Int?, lookupColumn: Int?, scopeFqName: String, scopeKind: ScopeKind, name: String) { -+ base.record(lookupContainingFile, lookupLine, lookupColumn, scopeFqName, scopeKind, name) -+ } -+ -+ private val _isDoNothing: Boolean = base == LookupTracker.DO_NOTHING","I think underscore is not needed here -",Why do we need a new class -303,"@@ -0,0 +1,40 @@ -+/* -+ * 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.components -+ -+import org.jetbrains.kotlin.descriptors.ClassDescriptor -+import org.jetbrains.kotlin.descriptors.ConstructorDescriptor -+import org.jetbrains.kotlin.descriptors.PropertyDescriptor -+import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor -+import org.jetbrains.kotlin.load.java.components.AbstractJavaResolverCache -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.java.structure.JavaElement -+import org.jetbrains.kotlin.load.java.structure.JavaField -+import org.jetbrains.kotlin.load.java.structure.JavaMethod -+import org.jetbrains.kotlin.resolve.lazy.ResolveSession -+ -+class JavacBasedJavaResolverCache(resolveSession: ResolveSession) : AbstractJavaResolverCache(resolveSession) {",May be we should name it like `StubJavaResolverCache`. The thing here is obviously not javac based.,Should this file be named ` -304,"@@ -0,0 +1,40 @@ -+/* -+ * 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.wrappers.symbols -+ -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.load.java.structure.JavaAnnotation -+import org.jetbrains.kotlin.load.java.structure.JavaAnnotationOwner -+import org.jetbrains.kotlin.load.java.structure.JavaClassifier -+import org.jetbrains.kotlin.name.FqName -+import javax.lang.model.element.Element -+ -+abstract class JavacClassifier(element: T, -+ javac: Javac) : JavacElement(element, javac), JavaClassifier, JavaAnnotationOwner { -+ -+ override val annotations: Collection -+ get() = element.annotationMirrors -+ .map { JavacAnnotation(it, javac) } -+ -+ override fun findAnnotation(fqName: FqName): JavaAnnotation? = element.annotationMirrors -+ .filter { it.toString() == fqName.asString() } -+ .firstOrNull() -+ ?.let { JavacAnnotation(it, javac) } -+ -+ override val isDeprecatedInJavaDoc = false",Why always false?,This file needs to be renamed to reflect the new API. -305,"@@ -0,0 +1,40 @@ -+package org.jetbrains.kotlin.idea.quickfix -+ -+import com.intellij.codeInsight.intention.IntentionAction -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.project.Project -+import org.jetbrains.kotlin.diagnostics.Diagnostic -+import org.jetbrains.kotlin.diagnostics.Errors -+import org.jetbrains.kotlin.psi.KtConstantExpression -+import org.jetbrains.kotlin.psi.KtFile -+import org.jetbrains.kotlin.psi.KtPsiFactory -+ -+class TooLongCharLiteralToStringFix( -+ element: KtConstantExpression -+) : KotlinQuickFixAction(element) { -+ override fun getText(): String = ""Convert too long character literal to string"" -+ -+ override fun invoke(project: Project, editor: Editor?, file: KtFile) { -+ val text = element.text -+ if (!(text.startsWith(""'"") && text.endsWith(""'"") && text.length >= 2)) { -+ return -+ } -+ -+ val newStringContent = text -+ .slice(1..text.length - 2) -+ .replace(""\\"", ""\\\\"")","For me it's suspicious. We can have a literal like `'Bye\n'` and expect to get `""Bye\n""` as result, so I'd not touch these back slashes. Please add a test for such case. -",Please rename the action to `ConvertTooLongCharacterT -306,"@@ -0,0 +1,40 @@ -+package org.jetbrains.kotlin.idea.quickfix -+ -+import com.intellij.codeInsight.intention.IntentionAction -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.project.Project -+import org.jetbrains.kotlin.diagnostics.Diagnostic -+import org.jetbrains.kotlin.diagnostics.Errors -+import org.jetbrains.kotlin.psi.KtConstantExpression -+import org.jetbrains.kotlin.psi.KtFile -+import org.jetbrains.kotlin.psi.KtPsiFactory -+ -+class TooLongCharLiteralToStringFix( -+ element: KtConstantExpression -+) : KotlinQuickFixAction(element) { -+ override fun getText(): String = ""Convert too long character literal to string"" -+ -+ override fun invoke(project: Project, editor: Editor?, file: KtFile) { -+ val text = element.text -+ if (!(text.startsWith(""'"") && text.endsWith(""'"") && text.length >= 2)) { -+ return -+ } -+ -+ val newStringContent = text -+ .slice(1..text.length - 2) -+ .replace(""\\"", ""\\\\"") -+ .replace(""\"""", ""\\\"""")","Changing double quote to escaped double quote is logical, I think it should be left as is. -",Please rename the action to `ConvertTooLongCharacterT -307,"@@ -0,0 +1,40 @@ -+package org.jetbrains.kotlin.idea.quickfix -+ -+import com.intellij.codeInsight.intention.IntentionAction -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.project.Project -+import org.jetbrains.kotlin.diagnostics.Diagnostic -+import org.jetbrains.kotlin.diagnostics.Errors -+import org.jetbrains.kotlin.psi.KtConstantExpression -+import org.jetbrains.kotlin.psi.KtFile -+import org.jetbrains.kotlin.psi.KtPsiFactory -+ -+class TooLongCharLiteralToStringFix( -+ element: KtConstantExpression -+) : KotlinQuickFixAction(element) { -+ override fun getText(): String = ""Convert too long character literal to string"" -+ -+ override fun invoke(project: Project, editor: Editor?, file: KtFile) { -+ val text = element.text -+ if (!(text.startsWith(""'"") && text.endsWith(""'"") && text.length >= 2)) { -+ return -+ } -+ -+ val newStringContent = text -+ .slice(1..text.length - 2) -+ .replace(""\\"", ""\\\\"") -+ .replace(""\"""", ""\\\"""") -+ val newElement = KtPsiFactory(element).createStringTemplate(newStringContent)","What happens if we have character literal like `'$x'` ? Should we get `""$x""` or `""\$x""`? I'd say the first case (without dollar escaping) is more logical, but I'd add a test for it. -",Please rename the action to `createStringTemplate`. -308,"@@ -0,0 +1,40 @@ -+package org.jetbrains.kotlin.idea.quickfix -+ -+import com.intellij.codeInsight.intention.IntentionAction -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.project.Project -+import org.jetbrains.kotlin.diagnostics.Diagnostic -+import org.jetbrains.kotlin.diagnostics.Errors -+import org.jetbrains.kotlin.psi.KtConstantExpression -+import org.jetbrains.kotlin.psi.KtFile -+import org.jetbrains.kotlin.psi.KtPsiFactory -+ -+class TooLongCharLiteralToStringFix( -+ element: KtConstantExpression -+) : KotlinQuickFixAction(element) { -+ override fun getText(): String = ""Convert too long character literal to string"" -+ -+ override fun invoke(project: Project, editor: Editor?, file: KtFile) { -+ val text = element.text -+ if (!(text.startsWith(""'"") && text.endsWith(""'"") && text.length >= 2)) { -+ return -+ } -+ -+ val newStringContent = text -+ .slice(1..text.length - 2) -+ .replace(""\\"", ""\\\\"") -+ .replace(""\"""", ""\\\"""") -+ val newElement = KtPsiFactory(element).createStringTemplate(newStringContent) -+ -+ element.replace(newElement) -+ } -+ -+ override fun getFamilyName(): String = ""Strings""","Usually `= text` is in use here. -",Please rename the action to `createStringTemplate`. -309,"@@ -0,0 +1,41 @@ -+/* -+ * Copyright 2010-2017 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.kotlin.wrappers.trees -+ -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.load.java.structure.JavaPackage -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.Name -+ -+class JCPackage(val name: String, val javac: Javac) : JavaPackage { -+ -+ override val fqName: FqName -+ get() = FqName(name)",Consider making it an initializer and remove getter,Maybe this should be renamed to `JavaPackageImpl`? -310,"@@ -0,0 +1,41 @@ -+/* -+ * Copyright 2010-2017 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.kotlin.wrappers.trees -+ -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.load.java.structure.JavaPackage -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.Name -+ -+class TreeBasedPackage(val name: String, val javac: JavacWrapper) : JavaPackage {","Similarly to `SymbolBasedPackage`, I think it can inherit from `SymbolBasedElement` and avoid overriding `equals`/`hashCode`/`toString`",Add a brief description of what this is -311,"@@ -0,0 +1,41 @@ -+/* -+ * Copyright 2010-2017 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.kotlin.wrappers.trees -+ -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.load.java.structure.JavaPackage -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.Name -+ -+class TreeBasedPackage(val name: String, val javac: JavacWrapper) : JavaPackage { -+ -+ override val fqName -+ get() = FqName(name) -+ -+ override val subPackages -+ get() = javac.findSubPackages(fqName) -+ -+ override fun getClasses(nameFilter: (Name) -> Boolean) = javac.findClassesFromPackage(fqName)","Shouldn't `TreeBasedPackage` contain only `TreeBasedClass`es, and `SymbolBasedPackage` -- only `SymbolBasedClass`es?",Could this be a `Provider` instead of a `Pre -312,"@@ -0,0 +1,42 @@ -+/* -+ * 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.components -+ -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.kotlin.KotlinBinaryClassCache -+import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass -+import org.jetbrains.kotlin.load.kotlin.VirtualFileFinder -+import org.jetbrains.kotlin.name.ClassId -+import org.jetbrains.kotlin.wrappers.trees.computeClassId -+ -+ -+abstract class JavacVirtualFileFinder : VirtualFileFinder() { -+ -+ override fun findKotlinClass(javaClass: JavaClass): KotlinJvmBinaryClass? { -+ var file = javaClass.computeClassId()?.let(this::findVirtualFileWithHeader) ?: return null -+ -+ if (javaClass.outerClass != null) { -+ // For nested classes we get a file of the containing class, to get the actual class file for A.B.C, -+ // we take the file for A, take its parent directory, then in this directory we look for A$B$C.class -+ file = file.parent!!.findChild(classFileName(javaClass) + "".class"").sure { ""Virtual file not found for $javaClass"" }","Again, it's better not to repeat the same code. Extract some protected function from `VirtualFileFinder`",Is there a reason why this isn't just `file = file.pa -313,"@@ -0,0 +1,42 @@ -+/* -+ * 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.components -+ -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.kotlin.KotlinBinaryClassCache -+import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass -+import org.jetbrains.kotlin.load.kotlin.VirtualFileFinder -+import org.jetbrains.kotlin.name.ClassId -+import org.jetbrains.kotlin.wrappers.trees.computeClassId -+ -+ -+abstract class JavacVirtualFileFinder : VirtualFileFinder() { -+ -+ override fun findKotlinClass(javaClass: JavaClass): KotlinJvmBinaryClass? { -+ var file = javaClass.computeClassId()?.let(this::findVirtualFileWithHeader) ?: return null -+ -+ if (javaClass.outerClass != null) { -+ // For nested classes we get a file of the containing class, to get the actual class file for A.B.C, -+ // we take the file for A, take its parent directory, then in this directory we look for A$B$C.class -+ file = file.parent!!.findChild(classFileName(javaClass) + "".class"").sure { ""Virtual file not found for $javaClass"" } -+ } -+ -+ return KotlinBinaryClassCache.getKotlinBinaryClass(file) -+ } -+ -+ inline fun T?.sure(message: () -> String): T = this ?: throw AssertionError(message())",This function already exists (anyway you will not need it after processing the previous comment),Is there a reason this isn't just `file = this.findVi -314,"@@ -0,0 +1,42 @@ -+/* -+ * 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.intentions -+ -+import com.intellij.codeInsight.intention.LowPriorityAction -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.KtClass -+import org.jetbrains.kotlin.psi.KtDeclaration -+import org.jetbrains.kotlin.psi.KtFunction -+import org.jetbrains.kotlin.psi.KtProperty -+import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType -+ -+class AddOpenModifierIntention : SelfTargetingIntention(KtDeclaration::class.java, ""Make open""), LowPriorityAction { -+ override fun isApplicableTo(element: KtDeclaration, caretOffset: Int): Boolean { -+ if (element.hasModifier(KtTokens.OPEN_KEYWORD) || element.hasModifier(KtTokens.PRIVATE_KEYWORD)) return false -+ when (element) { -+ is KtProperty -> if (element.isLocal) return false -+ is KtFunction -> if (element.isLocal) return false -+ } -+ val ktClass = element.getNonStrictParentOfType() ?: return false -+ return ktClass.hasModifier(KtTokens.OPEN_KEYWORD)","Things are not so easy here. First of all, there is `KtDeclaration.implicitModality()`, please use it. For example, interface functions with body are implicitly open and do not require explicit open modifier. Also, you need `containingClassOrObject` and not `getNonStrictParentOfType`, you are risking to miss e.g. companion object in the middle this way. Remember also that object / interface members should never have `open` added, as well as top-level guys. And at last, class can have `open` members if it's `open`, `abstract` or `sealed` itself, I'd not limit it to just open classes as described in an issue. ",This file needs to be renamed `AddOpenModifierIntenti -315,"@@ -0,0 +1,42 @@ -+/* -+ * 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.wrappers.symbols -+ -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.load.java.structure.JavaPackage -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.Name -+import javax.lang.model.element.PackageElement -+ -+class SymbolBasedPackage(val element: PackageElement, val javac: JavacWrapper) : JavaPackage {",Why doesn't it inherit from `SymbolBasedElement` to get `equals`/`hashCode`/`toString` for free?,Add a license header -316,"@@ -0,0 +1,43 @@ -+/* -+ * 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.idea.quickfix -+ -+import com.intellij.codeInsight.intention.IntentionAction -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.project.Project -+import org.jetbrains.kotlin.diagnostics.Diagnostic -+import org.jetbrains.kotlin.diagnostics.Errors -+import org.jetbrains.kotlin.psi.KtFile -+import org.jetbrains.kotlin.psi.KtLambdaExpression -+import org.jetbrains.kotlin.psi.KtPsiFactory -+ -+class AddRunToLambdaFix(element: KtLambdaExpression) : KotlinQuickFixAction(element) { -+ override fun getText() = ""Add 'run' before the lambda expression"" -+ override fun getFamilyName() = ""Add 'run' before the lambda expression""","`= getText()` -",Should this file be called `AddRunToLambdaExpression. -317,"@@ -0,0 +1,43 @@ -+/* -+ * 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.wrappers.symbols -+ -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.load.java.structure.JavaField -+import javax.lang.model.element.ElementKind -+import javax.lang.model.element.VariableElement -+ -+class SymbolBasedField(element: T, -+ javac: JavacWrapper) : SymbolBasedMember(element, javac), JavaField { -+ -+ override val isEnumEntry -+ get() = element.kind == ElementKind.ENUM_CONSTANT -+ -+ override val type -+ get() = SymbolBasedType.create(element.asType(), javac) -+ -+ override val initializerValue: Any? -+ get() = element.constantValue -+ -+ override val hasConstantNotNullInitializer -+ get() = element.constantValue?.let { -+ val typeMirror = type.typeMirror -+ -+ (typeMirror.kind.isPrimitive || typeMirror.toString() == ""java.lang.String"")","Please inspect the underlying element instead of `toString`. -",no need for the `?.` here. -318,"@@ -0,0 +1,43 @@ -+package test -+ -+public/*package*/ open class ExtendsAbstractListT { -+ public/*package*/ constructor ExtendsAbstractListT() -+} -+ -+public abstract class Mine : java.util.AbstractList { -+ public constructor Mine() -+ protected/*protected and package*/ final /*fake_override*/ var modCount: kotlin.Int -+ public abstract /*fake_override*/ val size: kotlin.Int -+ public open /*fake_override*/ fun add(/*0*/ T!): kotlin.Boolean -+ public open /*fake_override*/ fun add(/*0*/ kotlin.Int, /*1*/ T!): kotlin.Unit -+ public open /*fake_override*/ fun addAll(/*0*/ kotlin.Int, /*1*/ kotlin.collections.Collection): kotlin.Boolean -+ public open /*fake_override*/ fun addAll(/*0*/ kotlin.collections.Collection): kotlin.Boolean -+ public open /*fake_override*/ fun clear(): kotlin.Unit -+ public open /*fake_override*/ fun contains(/*0*/ T!): kotlin.Boolean -+ public open /*fake_override*/ fun containsAll(/*0*/ kotlin.collections.Collection): kotlin.Boolean -+ public open /*fake_override*/ fun forEach(/*0*/ java.util.function.Consumer!): kotlin.Unit","Do I understand correctly that `xxx2.txt` differs from `xxx.txt` only in members that come from Java 8 and this is caused by the fact that the original test was run against JDK 6, but the test with javac is run against JDK 8? - -I suggest just using JDK 8 then in both tests, to avoid complicating things too much.","The package name is `ExtendsAbstractListT`, so it sho" -319,"@@ -0,0 +1,44 @@ -+/* -+ * 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.wrappers.symbols -+ -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.load.java.structure.JavaPackage -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.Name -+import javax.lang.model.element.PackageElement -+ -+class JavacPackage(val element: PackageElement, val javac: Javac) : JavaPackage { -+ -+ override val fqName -+ get() = element.qualifiedName.let { FqName(it.toString()) }",I'd consider removing `let` from this and next getter. I suppose code without it will be easier to read,missing a line break here -320,"@@ -0,0 +1,44 @@ -+/* -+ * 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.wrappers.symbols -+ -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.load.java.structure.JavaPackage -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.Name -+import javax.lang.model.element.PackageElement -+ -+class JavacPackage(val element: PackageElement, val javac: Javac) : JavaPackage { -+ -+ override val fqName -+ get() = element.qualifiedName.let { FqName(it.toString()) } -+ -+ override val subPackages -+ get() = javac.findSubPackages(element.qualifiedName.toString().let(::FqName)) -+ -+ override fun getClasses(nameFilter: (Name) -> Boolean) = javac.findClassesFromPackage(fqName) -+ .filter { Name.isValidIdentifier(it.name.toString()) -+ && nameFilter(Name.identifier(it.name.toString())) -+ } -+ -+ override fun hashCode() = element.hashCode() -+ -+ override fun equals(other: Any?) = (other as? JavacPackage)?.element == element",Why do you need to override `equals` from `JavacElement` here?,Shouldn't this be implemented using `org.jetbrains.kotlin.util.PackageUtil`? -321,"@@ -0,0 +1,45 @@ -+/* -+ * 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.rmi.kotlinr","It seems this file should be placed in the appropriate subdirectory in order to get rid of warning about file location? -",Could you add a license header here? -322,"@@ -0,0 +1,45 @@ -+/* -+ * 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.rmi.kotlinr -+ -+import org.jetbrains.kotlin.rmi.RemoteOutputStream -+import java.io.OutputStream -+import java.rmi.server.UnicastRemoteObject -+ -+ -+class RemoteOutputStreamServer(val out: OutputStream) : RemoteOutputStream {","`: RemoteOutputStream by out` -",Is this file supposed to be called `RemoteOutputStreamServerTest.java`? -323,"@@ -0,0 +1,45 @@ -+/* -+ * 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.rmi.kotlinr -+ -+import org.jetbrains.kotlin.rmi.RemoteOutputStream -+import java.io.OutputStream -+import java.rmi.server.UnicastRemoteObject -+ -+ -+class RemoteOutputStreamServer(val out: OutputStream) : RemoteOutputStream { -+ -+ init { -+ UnicastRemoteObject.exportObject(this, 0) -+ } -+ -+ public fun disconnect() { -+ UnicastRemoteObject.unexportObject(this, true) -+ } -+ -+ override fun close() { -+ out.close() -+ } -+ -+ override fun write(data: ByteArray, start: Int, length: Int) {","`start` -> `offset` (as in the supertype) in order to get rid of corresponding warning. -",missing new line -324,"@@ -0,0 +1,46 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.plugin.intentions.JetSelfTargetingIntention -+import org.jetbrains.jet.lang.psi.JetQualifiedExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression -+import org.jetbrains.jet.lang.psi.JetCallExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetValueArgument -+import org.jetbrains.jet.lang.psi.JetArrayAccessExpression -+ -+ -+public class BracketToGetIntention : JetSelfTargetingIntention(""bracket.to.get"", javaClass()) { -+ override fun isApplicableTo(element: JetArrayAccessExpression): Boolean { -+ return element is JetArrayAccessExpression -+ } -+ -+ override fun applyTo(element: JetArrayAccessExpression, editor: Editor) { -+ val array = element.getArrayExpression()!! -+ val indices = element.getIndexExpressions() -+ -+ val arrayText = array.getText() -+ val indicesText = indices.map { it.getText() }.makeString("", "")","This line feels like a hack. It also doesn't preserve comments. Is there any way to get the contents of the indices without losing comments? -",Add a space before the `!!` -325,"@@ -0,0 +1,46 @@ -+/* -+ * 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.idea.editor.wordSelection -+ -+import com.intellij.codeInsight.editorActions.ExtendWordSelectionHandlerBase -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.util.TextRange -+import com.intellij.psi.PsiElement -+import org.jetbrains.kotlin.psi.KtTypeReference -+import org.jetbrains.kotlin.psi.psiUtil.endOffset -+import org.jetbrains.kotlin.psi.psiUtil.startOffset -+ -+class KotlinFunctionReturnTypeSelectioner : ExtendWordSelectionHandlerBase() { -+ -+ override fun canSelect(e: PsiElement?): Boolean { -+ return e is KtTypeReference -+ } -+ -+ override fun select(e: PsiElement?, editorText: CharSequence?, cursorOffset: Int, editor: Editor): List? { -+ e ?: return null -+ editorText ?: return null -+ val position = getColonPosition(e, editorText) -+ if (position < 0) return null -+ return listOf(TextRange(position, e.endOffset)) -+ } -+ -+ private fun getColonPosition(e: PsiElement, editorText: CharSequence): Int { -+ val colonIndex = editorText.filterIndexed { i, c -> i < e.startOffset }.indexOfLast { it == ':' }","Please do not use the text or regular expressions to perform the action. All the necessary information is available in the PSI; please do use it. -",This file needs to be renamed to `wordSelection.js`. -326,"@@ -0,0 +1,46 @@ -+/* -+ * 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.idea.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.KtBinaryExpression -+import org.jetbrains.kotlin.psi.KtForExpression -+import org.jetbrains.kotlin.psi.KtPsiFactory -+import org.jetbrains.kotlin.psi.createExpressionByPattern -+import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType -+ -+class ConvertRangeCheckToTwoComparisonsIntention : SelfTargetingOffsetIndependentIntention(KtBinaryExpression::class.java, ""Convert to comparisons"") { -+ override fun applyTo(element: KtBinaryExpression, editor: Editor?) { -+ if (element.operationToken != KtTokens.IN_KEYWORD) return -+ val rangeExpression = element.right as? KtBinaryExpression ?: return -+ val min = rangeExpression.left?.text ?: return -+ val arg = element.left?.text ?: return -+ val max: Any = rangeExpression.right?.text ?: return",Why do you need `Any` here?,This file needs to be renamed. -327,"@@ -0,0 +1,46 @@ -+/* -+ * 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.idea.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.KtBinaryExpression -+import org.jetbrains.kotlin.psi.KtForExpression -+import org.jetbrains.kotlin.psi.KtPsiFactory -+import org.jetbrains.kotlin.psi.createExpressionByPattern -+import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType -+ -+class ConvertRangeCheckToTwoComparisonsIntention : SelfTargetingOffsetIndependentIntention(KtBinaryExpression::class.java, ""Convert to comparisons"") { -+ override fun applyTo(element: KtBinaryExpression, editor: Editor?) { -+ if (element.operationToken != KtTokens.IN_KEYWORD) return -+ val rangeExpression = element.right as? KtBinaryExpression ?: return -+ val min = rangeExpression.left?.text ?: return -+ val arg = element.left?.text ?: return -+ val max: Any = rangeExpression.right?.text ?: return -+ val comparisonsExpression = KtPsiFactory(element).createExpressionByPattern(""$0 <= $1 && $1 <= $2"", min, arg, max) -+ element.replace(comparisonsExpression) -+ } -+ -+ override fun isApplicableTo(element: KtBinaryExpression): Boolean { -+ if (element.operationToken != KtTokens.IN_KEYWORD) return false -+ // ignore for-loop. for(x in 1..2) should not be convert to for(1<=x && x<=2) -+ if (element.getStrictParentOfType() != null) return false","I'd say this condition is too strict. E.g. your intention will not work for code like - -``` -for (element in list) { - if (element in 1..4) { ... } -} -```",This file needs to be renamed. -328,"@@ -0,0 +1,47 @@ -+/* -+ * 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.codegen.intrinsics -+ -+import org.jetbrains.kotlin.codegen.ExpressionCodegen -+import org.jetbrains.kotlin.codegen.StackValue -+import org.jetbrains.kotlin.descriptors.ConstructorDescriptor -+import org.jetbrains.kotlin.psi.KtCallableReferenceExpression -+import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall -+import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall -+import org.jetbrains.kotlin.resolve.jvm.AsmTypes -+import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver -+import org.jetbrains.org.objectweb.asm.Type -+ -+class KCallableNameProperty : IntrinsicPropertyGetter() { -+ override fun generate(resolvedCall: ResolvedCall<*>?, codegen: ExpressionCodegen, returnType: Type, receiver: StackValue): StackValue? { -+ val expressionReceiver = resolvedCall!!.dispatchReceiver as? ExpressionReceiver ?: return null -+ val expression = expressionReceiver.expression as? KtCallableReferenceExpression ?: return null -+ val callableReference = expression.callableReference -+ val descriptor = callableReference.getResolvedCall(codegen.bindingContext)?.resultingDescriptor ?: return null -+ -+ val name = if (descriptor is ConstructorDescriptor) {","`descriptor.name.asString()` -",Is this line necessary? -329,"@@ -0,0 +1,47 @@ -+/* -+ * 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.load.java -+ -+import org.jetbrains.kotlin.load.java.structure.impl.JavaPackageImpl -+import org.jetbrains.kotlin.name.ClassId -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.resolve.BindingTrace -+import org.jetbrains.kotlin.resolve.CodeAnalyzerInitializer -+import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade -+import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer -+ -+import javax.annotation.PostConstruct -+ -+class JavaClassFinderImpl : AbstractJavaClassFinder() { -+ -+ private lateinit var javaFacade: KotlinJavaPsiFacade -+ -+ @PostConstruct -+ fun initialize(trace: BindingTrace, codeAnalyzer: KotlinCodeAnalyzer) { -+ javaSearchScope = FilterOutKotlinSourceFilesScope(baseScope)",Please extract the first and the third line of this method into `AbstractJavaClassFinder.initialize` and call it here and in `JavacBasedClassFinder.initialize`,Shouldn't this be an abstract class instead of a class? -330,"@@ -0,0 +1,47 @@ -+/* -+ * 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.load.java -+ -+import org.jetbrains.kotlin.load.java.structure.impl.JavaPackageImpl -+import org.jetbrains.kotlin.name.ClassId -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.resolve.BindingTrace -+import org.jetbrains.kotlin.resolve.CodeAnalyzerInitializer -+import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade -+import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer -+ -+import javax.annotation.PostConstruct -+ -+class JavaClassFinderImpl : AbstractJavaClassFinder() { -+ -+ private lateinit var javaFacade: KotlinJavaPsiFacade -+ -+ @PostConstruct -+ fun initialize(trace: BindingTrace, codeAnalyzer: KotlinCodeAnalyzer) { -+ javaSearchScope = FilterOutKotlinSourceFilesScope(baseScope) -+ javaFacade = KotlinJavaPsiFacade.getInstance(proj) -+ CodeAnalyzerInitializer.getInstance(proj).initialize(trace, codeAnalyzer.moduleDescriptor, codeAnalyzer) -+ } -+ -+ -+ override fun findClass(classId: ClassId) = javaFacade.findClass(classId, javaSearchScope)",Please do not omit return types at least where inspections are reported (there's an inspection about platform type here).,Why not using the `@PostConstruct` annotation? -331,"@@ -0,0 +1,47 @@ -+/* -+ * 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.intentions -+ -+import com.intellij.codeInsight.intention.LowPriorityAction -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.kotlin.idea.inspections.UnusedSymbolInspection -+import org.jetbrains.kotlin.idea.util.addAnnotation -+import org.jetbrains.kotlin.idea.util.findAnnotation -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.psi.KtNamedFunction -+import org.jetbrains.kotlin.psi.KtObjectDeclaration -+ -+class AddJvmStaticIntention : SelfTargetingIntention( -+ KtNamedFunction::class.java, -+ ""Add '@JvmStatic' annotation"" -+), LowPriorityAction { -+ -+ private val annotationFqName = FqName(""kotlin.jvm.JvmStatic"") -+ -+ override fun isApplicableTo(element: KtNamedFunction, caretOffset: Int): Boolean { -+ if (element.findAnnotation(annotationFqName) != null) return false -+ if (!UnusedSymbolInspection.isEntryPoint(element)) return false",See `KotlinRunLineMarkerContributor` for the correct way to check that a function is `main`.,This file needs to be updated with the new version number. -332,"@@ -0,0 +1,47 @@ -+/* -+ * 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.intentions -+ -+import com.intellij.codeInsight.intention.LowPriorityAction -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.kotlin.idea.inspections.UnusedSymbolInspection -+import org.jetbrains.kotlin.idea.util.addAnnotation -+import org.jetbrains.kotlin.idea.util.findAnnotation -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.psi.KtNamedFunction -+import org.jetbrains.kotlin.psi.KtObjectDeclaration -+ -+class AddJvmStaticIntention : SelfTargetingIntention( -+ KtNamedFunction::class.java, -+ ""Add '@JvmStatic' annotation"" -+), LowPriorityAction { -+ -+ private val annotationFqName = FqName(""kotlin.jvm.JvmStatic"") -+ -+ override fun isApplicableTo(element: KtNamedFunction, caretOffset: Int): Boolean { -+ if (element.findAnnotation(annotationFqName) != null) return false -+ if (!UnusedSymbolInspection.isEntryPoint(element)) return false -+ element.parent.parent.run {",Please use `KtDeclaration.containingClassOrObject`.,This file needs to be updated with the new version number. -333,"@@ -0,0 +1,48 @@ -+/* -+ * 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.rmi -+ -+import java.io.IOException -+import java.io.Serializable -+import java.net.InetAddress -+import java.net.ServerSocket -+import java.net.Socket -+import java.rmi.server.RMIClientSocketFactory -+import java.rmi.server.RMIServerSocketFactory -+ -+ -+// TODO switch to InetAddress.getLoopbackAddress on java 7+ -+val loopbackAddrName by lazy { if (java.net.InetAddress.getLocalHost() is java.net.Inet6Address) ""::1"" else ""127.0.0.1"" }","`java.net.InetAddress.getLocalHost()` may crash with IOException (actually, UnknownHostException) on some machines due to strange network configuration. Notice that it is not a wrong machine configuration but Java's limitation. In some cases it couldn't be fixed on some corporate machines. I faced it few times in different companies. It is possible at least on Linux and Solaris machines -",remove this file? -334,"@@ -0,0 +1,48 @@ -+/* -+ * 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.wrappers.trees -+ -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.code.Flags -+import com.sun.tools.javac.tree.JCTree -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.load.java.structure.JavaAnnotation -+import org.jetbrains.kotlin.load.java.structure.JavaType -+import org.jetbrains.kotlin.load.java.structure.JavaValueParameter -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.Name -+ -+class JCValueParameter(tree: T, -+ treePath: TreePath, -+ javac: Javac) : JCElement(tree, treePath, javac), JavaValueParameter { -+ -+ override val annotations: Collection -+ get() = emptyList()",Value parameter in Java can have annotations,"I don't really like this package name, I find this package name very mislead" -335,"@@ -0,0 +1,49 @@ -+/* -+ * 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.idea.editor.wordSelection -+ -+import com.intellij.codeInsight.editorActions.ExtendWordSelectionHandlerBase -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.util.TextRange -+import com.intellij.psi.PsiElement -+import org.jetbrains.kotlin.psi.KtClass -+import org.jetbrains.kotlin.psi.KtSuperTypeList -+import org.jetbrains.kotlin.psi.psiUtil.endOffset -+import org.jetbrains.kotlin.psi.psiUtil.startOffset -+ -+class KotlinSuperTypeSelectioner : ExtendWordSelectionHandlerBase() { -+ override fun canSelect(e: PsiElement?): Boolean { -+ return e is KtSuperTypeList -+ } -+ -+ override fun select(e: PsiElement?, editorText: CharSequence?, cursorOffset: Int, editor: Editor): List? { -+ e ?: return null","Those parameters are actually non-null. You don't need the null checks here and in the other selectioner. -",Why not annotate this as `@NonNullApi` instead of `@NonNull`? -336,"@@ -0,0 +1,49 @@ -+/* -+ * 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.idea.editor.wordSelection -+ -+import com.intellij.codeInsight.editorActions.ExtendWordSelectionHandlerBase -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.util.TextRange -+import com.intellij.psi.PsiElement -+import org.jetbrains.kotlin.psi.KtClass -+import org.jetbrains.kotlin.psi.KtSuperTypeList -+import org.jetbrains.kotlin.psi.psiUtil.endOffset -+import org.jetbrains.kotlin.psi.psiUtil.startOffset -+ -+class KotlinSuperTypeSelectioner : ExtendWordSelectionHandlerBase() { -+ override fun canSelect(e: PsiElement?): Boolean { -+ return e is KtSuperTypeList -+ } -+ -+ override fun select(e: PsiElement?, editorText: CharSequence?, cursorOffset: Int, editor: Editor): List? { -+ e ?: return null -+ editorText ?: return null -+ val colonPosition = getColonPosition(e) -+ if (colonPosition < 0) return null -+ return listOf(TextRange(colonPosition, e.endOffset)) -+ } -+ -+ private fun getColonPosition(e: PsiElement): Int { -+ var parent = e.parent","You can use the `PsiElement.getParentOfType()` extension function to do this with less code. -",seems like this is a duplicate of the base class? -337,"@@ -0,0 +1,49 @@ -+/* -+ * 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.wrappers.trees -+ -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.tree.JCTree -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.SpecialNames -+ -+class TreeBasedTypeParameter(tree: T, -+ treePath: TreePath, -+ javac: JavacWrapper) : TreeBasedElement(tree, treePath, javac), JavaTypeParameter { -+ -+ override val name -+ get() = SpecialNames.safeIdentifier(tree.name.toString())",`Name.identifier`,"I don't think we need `treePath` here, since we a" -338,"@@ -0,0 +1,49 @@ -+/* -+ * 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.wrappers.trees -+ -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.tree.JCTree -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.SpecialNames -+ -+class TreeBasedTypeParameter(tree: T, -+ treePath: TreePath, -+ javac: JavacWrapper) : TreeBasedElement(tree, treePath, javac), JavaTypeParameter { -+ -+ override val name -+ get() = SpecialNames.safeIdentifier(tree.name.toString()) -+ -+ override val annotations by lazy { tree.annotations().map { TreeBasedAnnotation(it, treePath, javac) } } -+ -+ override fun findAnnotation(fqName: FqName) = annotations.firstOrNull { it.classId?.asSingleFqName() == fqName } -+ -+ override val isDeprecatedInJavaDoc -+ get() = findAnnotation(FqName(""java.lang.Deprecated"")) != null",You should return `false` here and in other implementations of `isDeprecatedInJavaDoc`. The call site looks for the annotation itself if needed,I wonder if we should use `org.jetbrains.kotlin.j -339,"@@ -0,0 +1,5 @@ -+// ERROR: Unresolved reference: array","I don't understand this error. -",This error shouldn't be reported. -340,"@@ -0,0 +1,5 @@ -+ -+ -+ This intention detects 'Math.max' calls that can be safely replaced with 'coerceAtLeast'","This intention replaces 'Math.max' calls with safe 'coerceAtLeast' ... or something like. Inspection detects, but inspection does some change. -",CoerceAtLeast calls should be wrapped in the `i18 -341,"@@ -0,0 +1,5 @@ -+ -+ -+Reports unnecessary java usage.","This is not clear. A better description would be ""Use of Java API that has a Kotlin equivalent"" or something like that. -",The `html` tag should be removed. -342,"@@ -0,0 +1,5 @@ -+ -+ -+This inspection remove an empty class body","reports and offers to remove -",I think it would be better to use `` instea -343,"@@ -0,0 +1,5 @@ -+ -+ -+This inspection reports unused equals expression.",expression**s**,I think it's better to say: This inspection repor -344,"@@ -0,0 +1,5 @@ -+ -+ -+This intention detects 'Math.max' calls that can be safely replaced with 'coerceAtLeast'","inspection -",CoerceAtLeast calls should be wrapped in the `i18 -345,"@@ -0,0 +1,5 @@ -+ -+ -+This intention detects 'Math.min' calls that can be safely replaced with 'coerceAtMost'","inspection -",Couple of things: 1. The name of this file is a b -346,"@@ -0,0 +1,5 @@ -+ -+ -+This intention detects an empty class body.","removes -",It's `` instead of `` -347,"@@ -0,0 +1,5 @@ -+ -+ -+This intention makes types explicit in a lambda expression.","A little elaboration won't hurt: `types of parameters, receiver and return type` -",typo: `in a lambda expression` -348,"@@ -0,0 +1,5 @@ -+ -+ -+This intention makes types implicit in a lambda expression","Ditto -",There's a typo in this sentence. -349,"@@ -0,0 +1,5 @@ -+ -+ -+This intention take a qualified call to any function ""get"" which has some arguments and converts it to square brackets.","""takes"" -",There's no `` in this HTML file. -350,"@@ -0,0 +1,5 @@ -+fun box(): String { -+ val sub = Box(-1) -+ println(sub.value == 1L)","replace 'println' with if check -",Don't use `println`. Use `assert` instead. -351,"@@ -0,0 +1,5 @@ -+if (foo()) { -+ bar() -+} else { -+ baz() -+}","The branches aren't swapped in the after-template -",I'm pretty sure this file will need a license hea -352,"@@ -0,0 +1,5 @@ -+package org.junit -+ -+@Deprecated(""Use 'Ignore' from kotlin.test package"", replaceWith = ReplaceWith(""Ignore"", imports = ""kotlin.test.Ignore"")) -+@Suppress(""HEADER_WITHOUT_IMPLEMENTATION"") -+header annotation class Ignore",I'm working on not needing this...,Why not `import static org.junit.Ignore.*`? -353,"@@ -0,0 +1,50 @@ -+/* -+ * 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.components -+ -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.load.java.AbstractJavaClassFinder -+import org.jetbrains.kotlin.name.ClassId -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.resolve.BindingTrace -+import org.jetbrains.kotlin.resolve.CodeAnalyzerInitializer -+import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer -+import javax.annotation.PostConstruct -+ -+class JavacBasedClassFinder : AbstractJavaClassFinder() { -+ -+ private lateinit var javac: JavacWrapper -+ -+ @PostConstruct -+ fun initialize(trace: BindingTrace, codeAnalyzer: KotlinCodeAnalyzer) { -+ javaSearchScope = FilterOutKotlinSourceFilesScope(baseScope) -+ javac = JavacWrapper.getInstance(proj) -+ CodeAnalyzerInitializer.getInstance(proj).initialize(trace, codeAnalyzer.moduleDescriptor, codeAnalyzer) -+ } -+ -+ override fun findClass(classId: ClassId) = javac.findClass(classId.asSingleFqName(), javaSearchScope)","Note that `ClassId.asSingleFqName` is an operation that loses some information, namely where package name in the `FqName` ends and where the class name starts. For example, `FqName` ""a.b.c"" might mean class c nested in class b in package a, or it might mean class c in package a.b. - -Please consider either using `ClassId` when possible, or at least destructuring it into package FQ name and relative class name and using them, to avoid problems related to resolution of nested classes.",Why not `private static final JavacWrapper -354,"@@ -0,0 +1,50 @@ -+/* -+ * 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.components -+ -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.load.java.AbstractJavaClassFinder -+import org.jetbrains.kotlin.name.ClassId -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.resolve.BindingTrace -+import org.jetbrains.kotlin.resolve.CodeAnalyzerInitializer -+import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer -+import javax.annotation.PostConstruct -+ -+class JavacBasedClassFinder : AbstractJavaClassFinder() { -+ -+ private lateinit var javac: JavacWrapper -+ -+ @PostConstruct -+ fun initialize(trace: BindingTrace, codeAnalyzer: KotlinCodeAnalyzer) { -+ javaSearchScope = FilterOutKotlinSourceFilesScope(baseScope) -+ javac = JavacWrapper.getInstance(proj) -+ CodeAnalyzerInitializer.getInstance(proj).initialize(trace, codeAnalyzer.moduleDescriptor, codeAnalyzer) -+ } -+ -+ override fun findClass(classId: ClassId) = javac.findClass(classId.asSingleFqName(), javaSearchScope) -+ -+ override fun findPackage(fqName: FqName) = javac.findPackage(fqName, javaSearchScope) -+ -+ override fun knownClassNamesInPackage(packageFqName: FqName): Set = javac.findClassesFromPackage(packageFqName) -+ .mapNotNullTo(hashSetOf()) { -+ it.fqName?.let { -+ if (it.isRoot) it.asString() else it.shortName().asString()","Multiple `it`s in nested lambdas are dangerous and confusing, please rename at least one of them",What do you think about moving all of this -355,"@@ -0,0 +1,50 @@ -+/* -+ * 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.inspections -+ -+import com.intellij.codeInspection.* -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiElementVisitor -+import org.jetbrains.kotlin.psi.* -+ -+class RemoveRedundantBackticksInspection : AbstractKotlinInspection() { -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { -+ return object : KtVisitorVoid() { -+ override fun visitCallExpression(expression: KtCallExpression) {","Why is this limited to call expressions? Backticks can be used around any occurrence of identifier in Kotlin code, and the inspection should detect those in any context.",How about `RemoveRedundantBackticksInspecti -356,"@@ -0,0 +1,50 @@ -+/* -+ * 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.inspections -+ -+import com.intellij.codeInspection.* -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiElementVisitor -+import org.jetbrains.kotlin.psi.* -+ -+class RemoveRedundantBackticksInspection : AbstractKotlinInspection() { -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { -+ return object : KtVisitorVoid() { -+ override fun visitCallExpression(expression: KtCallExpression) { -+ super.visitCallExpression(expression) -+ val calleeExpression = expression.calleeExpression ?: return -+ if (calleeExpression.text.contains(""^`.+`$"".toRegex())) {","This detects any backticks, not just redundant backticks. Backticks are redundant only if they enclose a valid identifier (not a keyword and not containing any invalid characters).",This file needs to be renamed. -357,"@@ -0,0 +1,51 @@ -+/* -+ * Copyright 2010-2017 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.kotlin.components -+ -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.load.java.AbstractJavaClassFinder -+import org.jetbrains.kotlin.name.ClassId -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.resolve.BindingTrace -+import org.jetbrains.kotlin.resolve.CodeAnalyzerInitializer -+import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer -+import javax.annotation.PostConstruct -+ -+class JavacBasedClassFinder : AbstractJavaClassFinder() { -+ -+ private lateinit var javac: JavacWrapper -+ -+ @PostConstruct -+ fun initialize(trace: BindingTrace, codeAnalyzer: KotlinCodeAnalyzer) { -+ javaSearchScope = FilterOutKotlinSourceFilesScope(baseScope) -+ javac = JavacWrapper.getInstance(proj) -+ CodeAnalyzerInitializer.getInstance(proj).initialize(trace, codeAnalyzer.moduleDescriptor, codeAnalyzer) -+ } -+ -+ override fun findClass(classId: ClassId) = javac.findClass(classId.asSingleFqName(), javaSearchScope) -+ -+ override fun findPackage(fqName: FqName) = javac.findPackage(fqName, javaSearchScope) -+ -+ override fun knownClassNamesInPackage(packageFqName: FqName) = javac.findClassesFromPackage(packageFqName) -+ .mapNotNull {","Here you can use `mapNotNullTo` without `toSet` at the end, it may be a bit faster",What do you think about moving all of this -358,"@@ -0,0 +1,51 @@ -+/* -+ * Copyright 2010-2017 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.kotlin.idea.quickfix -+ -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.project.Project -+import com.intellij.psi.util.PsiTreeUtil -+import org.jetbrains.kotlin.diagnostics.Diagnostic -+import org.jetbrains.kotlin.psi.* -+import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType -+ -+class RemoveUselessIsCheckFixForWhen(element: KtWhenConditionIsPattern) : KotlinQuickFixAction(element) { -+ override fun getFamilyName() = ""Remove useless is check"" -+ -+ override fun getText(): String = familyName -+ -+ override fun invoke(project: Project, editor: Editor?, file: KtFile) { -+ val condition = element ?: return -+ val whenEntry = condition.parent as KtWhenEntry -+ val whenExpression = whenEntry.parent as KtWhenExpression -+ -+ if (condition.isNegated) { -+ condition.parent.delete() -+ } else { -+ whenExpression.entries.forEach { it.delete() }","You should not delete all entries here, but only subsequent ones. E.g. - -``` -val something: Base = ... -when (something) { - is Derived -> forDerived() - is Base /* always true */ -> forBase() - is Any /* unreachable */ -> forAny() - is SomethingWrong /* also unreachable */ forWrong() - else -> forElse() -} -``` - -Here `is Base` branch must be left intact.",This file needs to be named `RemoveUselessI -359,"@@ -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 kotlin.collections","Why not `package kotlin`? -",Could you add a license header here? -360,"@@ -0,0 +1,52 @@ -+/* -+ * 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.idea.intentions -+ -+import com.intellij.openapi.editor.Editor -+import com.intellij.refactoring.rename.RenameProcessor -+import org.jetbrains.kotlin.idea.core.replaced -+import org.jetbrains.kotlin.psi.* -+import org.jetbrains.kotlin.psi.psiUtil.endOffset -+import org.jetbrains.kotlin.psi.psiUtil.visibilityModifier -+ -+class ValToObjectIntention : SelfTargetingIntention(KtProperty::class.java, ""Convert to object declaration"") { -+ -+ override fun isApplicableTo(element: KtProperty, caretOffset: Int): Boolean { -+ if (element.isVar) return false -+ if (!element.isTopLevel) return false -+ if (element.initializer !is KtObjectLiteralExpression) return false -+ if (element.getter != null) return false -+ -+ return true -+ } -+ -+ override fun applyTo(element: KtProperty, editor: Editor?) { -+ val modifier = element.visibilityModifier()","You're losing all annotations on the original property. (I think that it would be best not to offer the intention if the property has any, because the semantics of annotations on a `val` and an `object` is significantly different.) -",Why do we need to add this override? I don' -361,"@@ -0,0 +1,52 @@ -+/* -+ * 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.idea.intentions -+ -+import com.intellij.openapi.editor.Editor -+import com.intellij.refactoring.rename.RenameProcessor -+import org.jetbrains.kotlin.idea.core.replaced -+import org.jetbrains.kotlin.psi.* -+import org.jetbrains.kotlin.psi.psiUtil.endOffset -+import org.jetbrains.kotlin.psi.psiUtil.visibilityModifier -+ -+class ValToObjectIntention : SelfTargetingIntention(KtProperty::class.java, ""Convert to object declaration"") { -+ -+ override fun isApplicableTo(element: KtProperty, caretOffset: Int): Boolean { -+ if (element.isVar) return false -+ if (!element.isTopLevel) return false -+ if (element.initializer !is KtObjectLiteralExpression) return false -+ if (element.getter != null) return false -+ -+ return true -+ } -+ -+ override fun applyTo(element: KtProperty, editor: Editor?) { -+ val modifier = element.visibilityModifier() -+ val name = element.name ?: return -+ val o = element.initializer as? KtObjectLiteralExpression ?: return -+ val od = o.objectDeclaration -+ val superTypeList = od.getSuperTypeList() ?: return","I think you should check the supertype list in `isApplicableTo` as well, so that you don't end up with an intention which is enabled and does nothing. -",This file needs to be renamed. -362,"@@ -0,0 +1,52 @@ -+/* -+ * 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.idea.intentions -+ -+import com.intellij.openapi.editor.Editor -+import com.intellij.refactoring.rename.RenameProcessor -+import org.jetbrains.kotlin.idea.core.replaced -+import org.jetbrains.kotlin.psi.* -+import org.jetbrains.kotlin.psi.psiUtil.endOffset -+import org.jetbrains.kotlin.psi.psiUtil.visibilityModifier -+ -+class ValToObjectIntention : SelfTargetingIntention(KtProperty::class.java, ""Convert to object declaration"") { -+ -+ override fun isApplicableTo(element: KtProperty, caretOffset: Int): Boolean { -+ if (element.isVar) return false -+ if (!element.isTopLevel) return false -+ if (element.initializer !is KtObjectLiteralExpression) return false -+ if (element.getter != null) return false -+ -+ return true -+ } -+ -+ override fun applyTo(element: KtProperty, editor: Editor?) { -+ val modifier = element.visibilityModifier() -+ val name = element.name ?: return -+ val o = element.initializer as? KtObjectLiteralExpression ?: return -+ val od = o.objectDeclaration -+ val superTypeList = od.getSuperTypeList() ?: return -+ val body = od.getBody() ?: return -+ -+ val prefix = modifier?.text?.plus("" "") ?: """" -+ val replacementText = ""${prefix}object $name: ${superTypeList.text} ${body.text}"" -+ val replaced = element.replaced(KtPsiFactory(element).createDeclarationByPattern(replacementText)) -+ -+ RenameProcessor(element.project, replaced, name.capitalize(), false, false).doRun()","I think that automatically changing the name without user input is not a very good idea. It's better to trigger a rename refactoring where the user inputs the name, initialized with the capitalized version of the old name. -",This file needs to be renamed. -363,"@@ -0,0 +1,52 @@ -+/* -+ * 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.idea.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.idea.core.replaced -+import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection -+import org.jetbrains.kotlin.psi.KtCallExpression -+import org.jetbrains.kotlin.psi.KtDotQualifiedExpression -+import org.jetbrains.kotlin.psi.KtPsiFactory -+import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType -+import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall -+import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe -+ -+class ReplaceMathMaxWithCoerceAtLeastInspection : IntentionBasedInspection(ReplaceMathMaxWithCoerceAtLeastIntention::class) -+ -+class ReplaceMathMaxWithCoerceAtLeastIntention() : SelfTargetingOffsetIndependentIntention(","I think abstract class should be extracted from this intention and the next one. Too many similar code inside -",Should this class be public? -364,"@@ -0,0 +1,52 @@ -+/* -+ * 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.idea.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.idea.core.replaced -+import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection -+import org.jetbrains.kotlin.psi.KtCallExpression -+import org.jetbrains.kotlin.psi.KtDotQualifiedExpression -+import org.jetbrains.kotlin.psi.KtPsiFactory -+import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType -+import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall -+import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe -+ -+class ReplaceMathMaxWithCoerceAtLeastInspection : IntentionBasedInspection(ReplaceMathMaxWithCoerceAtLeastIntention::class) -+ -+class ReplaceMathMaxWithCoerceAtLeastIntention() : SelfTargetingOffsetIndependentIntention( -+ KtCallExpression::class.java, ""Replace Math.max with coerceAtLeast"") { -+ -+ override fun applyTo(element: KtCallExpression, editor: Editor?) { -+ val target = element.getStrictParentOfType() ?: element -+ val valueArguments = element.valueArguments -+ val newExpression = KtPsiFactory(element).createExpression(""${valueArguments[0].text}.coerceAtLeast(${valueArguments[1].text})"") -+ target.replaced(newExpression) -+ } -+ -+ override fun isApplicableTo(element: KtCallExpression) = isMaxMethod(element) -+ -+ private fun isMaxMethod(element: KtCallExpression) = -+ element.calleeExpression?.text == ""max"" && element.valueArguments.size == 2 && element.isMethodCall(""java.lang.Math.max"") -+ -+ private fun KtCallExpression.isMethodCall(fqMethodName: String): Boolean {","You have the same method in `ReplaceMathMinWithCoerceAtMostIntention`. It would make more sense to pull it out in a Utils class. -",This file needs to be renamed. -365,"@@ -0,0 +1,52 @@ -+/* -+ * 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.wrappers.symbols -+ -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.load.java.structure.JavaAnnotationArgument -+import org.jetbrains.kotlin.load.java.structure.JavaArrayAnnotationArgument -+import org.jetbrains.kotlin.load.java.structure.JavaElement -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.Name -+import javax.lang.model.element.AnnotationMirror -+import javax.lang.model.element.AnnotationValue -+import javax.lang.model.element.VariableElement -+import javax.lang.model.type.TypeMirror -+ -+open class SymbolBasedAnnotationArgument(private val fqName: FqName,","Annotation argument has no FQ name, a `Name` should be enough",missing new line -366,"@@ -0,0 +1,53 @@ -+/* -+ * 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.wrappers.symbols -+ -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.load.java.structure.JavaAnnotation -+import org.jetbrains.kotlin.load.java.structure.JavaAnnotationOwner -+import org.jetbrains.kotlin.load.java.structure.JavaType -+import org.jetbrains.kotlin.name.FqName -+import javax.lang.model.type.TypeKind -+import javax.lang.model.type.TypeMirror -+ -+open class JavacType(val typeMirror: T, -+ val javac: Javac) : JavaType, JavaAnnotationOwner { -+ -+ companion object { -+ fun create(t: TM, javac: Javac) = when { -+ t.kind.isPrimitive || t.toString() == ""void"" -> JavacPrimitiveType(t, javac)",Why the second part is needed? Looks like `TypeMirror` for `void` also should be primitive? You can also consider extracting this condition as `if` and continue with `when (t.kind)`.,Add a doc string explaining what `T` means? -367,"@@ -0,0 +1,53 @@ -+/* -+ * 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.wrappers.symbols -+ -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.load.java.structure.JavaAnnotation -+import org.jetbrains.kotlin.load.java.structure.JavaAnnotationOwner -+import org.jetbrains.kotlin.load.java.structure.JavaType -+import org.jetbrains.kotlin.name.FqName -+import javax.lang.model.type.TypeKind -+import javax.lang.model.type.TypeMirror -+ -+open class JavacType(val typeMirror: T, -+ val javac: Javac) : JavaType, JavaAnnotationOwner { -+ -+ companion object { -+ fun create(t: TM, javac: Javac) = when { -+ t.kind.isPrimitive || t.toString() == ""void"" -> JavacPrimitiveType(t, javac) -+ t.kind == TypeKind.DECLARED || t.kind == TypeKind.TYPEVAR -> JavacClassifierType(t, javac) -+ t.kind == TypeKind.WILDCARD -> JavacWildcardType(t, javac) -+ t.kind == TypeKind.ARRAY -> JavacArrayType(t, javac) -+ else -> throw UnsupportedOperationException(""Unsupported type: $t"") -+ } -+ } -+ -+ override val annotations: Collection = emptyList() -+ -+ override val isDeprecatedInJavaDoc -+ get() = false -+ -+ override fun findAnnotation(fqName: FqName) = null",`annotations` and `findAnnotation` are implemented in a different way in NB plugin,this should be `org.jetbrains.kotlin.javac. -368,"@@ -0,0 +1,53 @@ -+/* -+ * 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.wrappers.trees -+ -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.tree.JCTree -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.java.structure.JavaConstructor -+import org.jetbrains.kotlin.name.Name -+ -+class JCConstructor(tree: T, -+ treePath: TreePath, -+ containingClass: JavaClass, -+ javac: Javac) : JCMember(tree, treePath, containingClass, javac), JavaConstructor { -+ -+ override val name -+ get() = Name.identifier(tree.name.toString()) -+ -+ override val isAbstract -+ get() = tree.modifiers.isAbstract",Constructor never can be abstract,This file is missing a license header. -369,"@@ -0,0 +1,53 @@ -+/* -+ * 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.wrappers.trees -+ -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.tree.JCTree -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.java.structure.JavaConstructor -+import org.jetbrains.kotlin.name.Name -+ -+class JCConstructor(tree: T, -+ treePath: TreePath, -+ containingClass: JavaClass, -+ javac: Javac) : JCMember(tree, treePath, containingClass, javac), JavaConstructor { -+ -+ override val name -+ get() = Name.identifier(tree.name.toString()) -+ -+ override val isAbstract -+ get() = tree.modifiers.isAbstract -+ -+ override val isStatic -+ get() = tree.modifiers.isStatic",Constructor never can be static,This file is missing a license header. -370,"@@ -0,0 +1,53 @@ -+/* -+ * 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.wrappers.trees -+ -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.tree.JCTree -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.java.structure.JavaConstructor -+import org.jetbrains.kotlin.name.Name -+ -+class JCConstructor(tree: T, -+ treePath: TreePath, -+ containingClass: JavaClass, -+ javac: Javac) : JCMember(tree, treePath, containingClass, javac), JavaConstructor { -+ -+ override val name -+ get() = Name.identifier(tree.name.toString()) -+ -+ override val isAbstract -+ get() = tree.modifiers.isAbstract -+ -+ override val isStatic -+ get() = tree.modifiers.isStatic -+ -+ override val isFinal -+ get() = tree.modifiers.isFinal",Also it never can be overridable. Not sure should it be considered as `final` or not.,This file is missing a license header. -371,"@@ -0,0 +1,54 @@ -+/* -+ * 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.wrappers.trees -+ -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.code.Flags -+import com.sun.tools.javac.tree.JCTree -+import org.jetbrains.kotlin.descriptors.Visibilities -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.java.structure.JavaField -+import org.jetbrains.kotlin.load.java.structure.JavaType -+import org.jetbrains.kotlin.name.Name -+ -+class JCField(tree: T, -+ treePath: TreePath, -+ containingClass: JavaClass, -+ javac: Javac) : JCMember(tree, treePath, containingClass, javac), JavaField { -+ -+ override val name -+ get() = Name.identifier(tree.name.toString()) -+ -+ override val isAbstract -+ get() = tree.modifiers.isAbstract -+ -+ override val isStatic -+ get() = if (containingClass.isInterface) true else tree.modifiers.isStatic",`containingClass.isInterface || tree.modifiers.isStatic`,I don't think this is the right place -372,"@@ -0,0 +1,54 @@ -+package test -+ -+public final annotation class AByte : kotlin.Annotation { -+ public constructor AByte(/*0*/ kotlin.Byte) -+ public final val value: kotlin.Byte -+} -+ -+public final annotation class AChar : kotlin.Annotation { -+ public constructor AChar(/*0*/ kotlin.Char) -+ public final val value: kotlin.Char -+} -+ -+public final annotation class ADouble : kotlin.Annotation { -+ public constructor ADouble(/*0*/ kotlin.Double) -+ public final val value: kotlin.Double -+} -+ -+public final annotation class AFloat : kotlin.Annotation { -+ public constructor AFloat(/*0*/ kotlin.Float) -+ public final val value: kotlin.Float -+} -+ -+public final annotation class AInt : kotlin.Annotation { -+ public constructor AInt(/*0*/ kotlin.Int) -+ public final val value: kotlin.Int -+} -+ -+public final annotation class ALong : kotlin.Annotation { -+ public constructor ALong(/*0*/ kotlin.Long) -+ public final val value: kotlin.Long -+} -+ -+public final annotation class AString : kotlin.Annotation { -+ public constructor AString(/*0*/ kotlin.String) -+ public final val value: kotlin.String -+} -+ -+@test.AString(value = ""Test"") @test.AChar(value = \u0063 ('c')) @test.AInt(value = 10) @test.AByte(value = 11.toByte()) @test.ALong(value = 12.toLong()) @test.ADouble(value = 1.2.toDouble()) @test.AFloat(value = 1.3.toFloat()) public open class AnnotationTrait {",Ditto (`@test.AByte(value = 11.toByte())` vs `@test.AByte(value = 11)`),If this annotation only exists in the -373,"@@ -0,0 +1,55 @@ -+/* -+ * 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.idea.quickfix -+ -+import com.intellij.codeInsight.intention.IntentionAction -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiFile -+import org.jetbrains.kotlin.diagnostics.Diagnostic -+import org.jetbrains.kotlin.diagnostics.Errors -+import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinValVar -+import org.jetbrains.kotlin.psi.KtFile -+import org.jetbrains.kotlin.psi.KtNameReferenceExpression -+import org.jetbrains.kotlin.psi.KtParameter -+import org.jetbrains.kotlin.psi.KtPsiFactory -+import org.jetbrains.kotlin.psi.psiUtil.getAssignmentByLHS -+import org.jetbrains.kotlin.psi.psiUtil.getPrimaryConstructorParameterWithSameName -+ -+class MakeConstructorParameterPropertyFix(element: KtParameter, private val kotlinValVar: KotlinValVar) : KotlinQuickFixAction(element) { -+ override fun getFamilyName() = ""Make primary constructor parameter a property"" -+ override fun getText() = ""Make primary constructor parameter '${element.name}' a property""","In the case when we're updating an outer class, it'd be better to show the name of that class in the inspection text. -",Please add a license to the top of all -374,"@@ -0,0 +1,55 @@ -+/* -+ * 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.load.java -+ -+import com.intellij.openapi.project.Project -+import com.intellij.openapi.vfs.VirtualFile -+import com.intellij.psi.search.DelegatingGlobalSearchScope -+import com.intellij.psi.search.GlobalSearchScope -+import org.jetbrains.kotlin.idea.KotlinFileType -+import javax.inject.Inject -+ -+abstract class AbstractJavaClassFinder : JavaClassFinder { -+ -+ protected lateinit var proj: Project",Please rename to `project`,Shouldn't this be an abstract class in -375,"@@ -0,0 +1,55 @@ -+/* -+ * 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.wrappers.symbols -+ -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.load.java.structure.JavaAnnotationOwner -+import org.jetbrains.kotlin.load.java.structure.JavaType -+import org.jetbrains.kotlin.name.FqName -+import javax.lang.model.type.TypeKind -+import javax.lang.model.type.TypeMirror -+ -+open class SymbolBasedType(val typeMirror: T, -+ val javac: JavacWrapper) : JavaType, JavaAnnotationOwner { -+ -+ companion object { -+ fun create(t: TM, javac: JavacWrapper) = when { -+ t.kind.isPrimitive || t.toString() == ""void"" -> SymbolBasedPrimitiveType(t, javac)",`t.kind.isPrimitive || t.kind == TypeKind.VOID -> ...`,Add a doc string explaining what the e -376,"@@ -0,0 +1,55 @@ -+/* -+ * 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.wrappers.trees -+ -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.tree.JCTree -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.load.java.structure.JavaAnnotationOwner -+import org.jetbrains.kotlin.load.java.structure.JavaType -+import org.jetbrains.kotlin.name.FqName -+ -+abstract class JCType(val tree: T, -+ val treePath: TreePath, -+ val javac: JavacWrapper) : JavaType, JavaAnnotationOwner { -+ -+ companion object { -+ fun create(tree: Type, treePath: TreePath, javac: JavacWrapper) = when (tree) { -+ is JCTree.JCPrimitiveTypeTree -> JCPrimitiveType(tree, TreePath(treePath, tree), javac) -+ is JCTree.JCArrayTypeTree -> JCArrayType(tree, TreePath(treePath, tree), javac) -+ is JCTree.JCWildcard -> JCWildcardType(tree, TreePath(treePath, tree), javac) -+ is JCTree.JCTypeApply -> JCClassifierTypeWithTypeArgument(tree, TreePath(treePath, tree), javac) -+ is JCTree.JCExpression -> JCClassifierType(tree, TreePath(treePath, tree), javac) -+ else -> throw UnsupportedOperationException(""Unsupported type: $tree"") -+ } -+ } -+ -+ override val annotations -+ get() = emptyList()",Are you sure this list should be empty? In `JavaTypeImpl` it's not so,Please annotate `@Restricted(NoExterna -377,"@@ -0,0 +1,55 @@ -+package test -+ -+public final annotation class AByte : kotlin.Annotation { -+ public constructor AByte(/*0*/ kotlin.Byte) -+ public final val value: kotlin.Byte -+} -+ -+public final annotation class AChar : kotlin.Annotation { -+ public constructor AChar(/*0*/ kotlin.Char) -+ public final val value: kotlin.Char -+} -+ -+public final annotation class ADouble : kotlin.Annotation { -+ public constructor ADouble(/*0*/ kotlin.Double) -+ public final val value: kotlin.Double -+} -+ -+public final annotation class AFloat : kotlin.Annotation { -+ public constructor AFloat(/*0*/ kotlin.Float) -+ public final val value: kotlin.Float -+} -+ -+public final annotation class AInt : kotlin.Annotation { -+ public constructor AInt(/*0*/ kotlin.Int) -+ public final val value: kotlin.Int -+} -+ -+public final annotation class ALong : kotlin.Annotation { -+ public constructor ALong(/*0*/ kotlin.Long) -+ public final val value: kotlin.Long -+} -+ -+public final annotation class AString : kotlin.Annotation { -+ public constructor AString(/*0*/ kotlin.String) -+ public final val value: kotlin.String -+} -+ -+@test.AString(value = ""Test"") @test.AChar(value = \u0063 ('c')) @test.AInt(value = 10) @test.AByte(value = 11.toByte()) @test.ALong(value = 12.toLong()) @test.ADouble(value = 1.2.toDouble()) @test.AFloat(value = 1.3.toFloat()) public open class AnnotationClass {","Why is there `@test.AByte(value = 11.toByte())`, but only `@test.AByte(value = 11)` in the main test data, is worth investigating, I think. Loading annotation arguments with different types than what is done now might break some invariants in the compiler",Would it make sense to have a single a -378,"@@ -0,0 +1,56 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetIfExpression -+import org.jetbrains.jet.lang.psi.JetWhileExpression -+import org.jetbrains.jet.lang.psi.JetForExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetDoWhileExpression -+import org.jetbrains.jet.lang.psi.JetExpressionImpl -+import org.jetbrains.jet.lang.psi.psiUtil.findBlockInExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.JetNodeTypes -+ -+public class AddBracesIntention : JetSelfTargetingIntention(""add.braces"", javaClass()) { -+ -+ override fun isApplicableTo(element: JetExpressionImpl): Boolean { -+ val conditionText = when (element) { -+ is JetIfExpression -> ""if"" -+ is JetWhileExpression -> ""while"" -+ is JetDoWhileExpression -> ""do...while"" -+ is JetForExpression -> ""for"" -+ else -> return false -+ } -+ val jetBlockElement = element.findBlockInExpression(element)","Obviously, won't work for `else` -",Please rename this file to `RemoveBrac -379,"@@ -0,0 +1,56 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetIfExpression -+import org.jetbrains.jet.lang.psi.JetWhileExpression -+import org.jetbrains.jet.lang.psi.JetForExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetDoWhileExpression -+import org.jetbrains.jet.lang.psi.JetExpressionImpl -+import org.jetbrains.jet.lang.psi.psiUtil.findBlockInExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.JetNodeTypes -+ -+public class AddBracesIntention : JetSelfTargetingIntention(""add.braces"", javaClass()) { -+ -+ override fun isApplicableTo(element: JetExpressionImpl): Boolean { -+ val conditionText = when (element) { -+ is JetIfExpression -> ""if"" -+ is JetWhileExpression -> ""while"" -+ is JetDoWhileExpression -> ""do...while"" -+ is JetForExpression -> ""for"" -+ else -> return false -+ } -+ val jetBlockElement = element.findBlockInExpression(element) -+ if (jetBlockElement != null) return false -+ -+ setText(""Add braces to '$conditionText' statement"") -+ return true -+ } -+ -+ override fun applyTo(element: JetExpressionImpl, editor: Editor) { -+ val bodyElement = when (element) {","""bodyNode"" would be a better name -",Please rename the file to `RemoveBrace -380,"@@ -0,0 +1,56 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetIfExpression -+import org.jetbrains.jet.lang.psi.JetWhileExpression -+import org.jetbrains.jet.lang.psi.JetForExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetDoWhileExpression -+import org.jetbrains.jet.lang.psi.JetExpressionImpl -+import org.jetbrains.jet.lang.psi.psiUtil.findBlockInExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.JetNodeTypes -+ -+public class AddBracesIntention : JetSelfTargetingIntention(""add.braces"", javaClass()) { -+ -+ override fun isApplicableTo(element: JetExpressionImpl): Boolean { -+ val conditionText = when (element) { -+ is JetIfExpression -> ""if"" -+ is JetWhileExpression -> ""while"" -+ is JetDoWhileExpression -> ""do...while"" -+ is JetForExpression -> ""for"" -+ else -> return false -+ } -+ val jetBlockElement = element.findBlockInExpression(element) -+ if (jetBlockElement != null) return false -+ -+ setText(""Add braces to '$conditionText' statement"") -+ return true -+ } -+ -+ override fun applyTo(element: JetExpressionImpl, editor: Editor) { -+ val bodyElement = when (element) { -+ is JetIfExpression -> element.getNode().findChildByType(JetNodeTypes.THEN) -+ else -> element.getNode().findChildByType(JetNodeTypes.BODY) -+ } -+ val bodyText = bodyElement?.getText() -+ val newElement = bodyElement?.getPsi()?.getPrevSibling()?.replace(JetPsiFactory.createExpression(element.getProject(), ""{\n $bodyText \n}""))","You are replace element before expression with block, and then add whitespace. Why not replace expression with block directly? Also, this works incorrectly for `if (true)println()` -",Please rename the file to `RemoveBrace -381,"@@ -0,0 +1,56 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetIfExpression -+import org.jetbrains.jet.lang.psi.JetWhileExpression -+import org.jetbrains.jet.lang.psi.JetForExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetDoWhileExpression -+import org.jetbrains.jet.lang.psi.JetExpressionImpl -+import org.jetbrains.jet.lang.psi.psiUtil.findBlockInExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.JetNodeTypes -+ -+public class AddBracesIntention : JetSelfTargetingIntention(""add.braces"", javaClass()) { -+ -+ override fun isApplicableTo(element: JetExpressionImpl): Boolean { -+ val conditionText = when (element) { -+ is JetIfExpression -> ""if"" -+ is JetWhileExpression -> ""while"" -+ is JetDoWhileExpression -> ""do...while"" -+ is JetForExpression -> ""for"" -+ else -> return false -+ } -+ val jetBlockElement = element.findBlockInExpression(element) -+ if (jetBlockElement != null) return false -+ -+ setText(""Add braces to '$conditionText' statement"") -+ return true -+ } -+ -+ override fun applyTo(element: JetExpressionImpl, editor: Editor) { -+ val bodyElement = when (element) { -+ is JetIfExpression -> element.getNode().findChildByType(JetNodeTypes.THEN) -+ else -> element.getNode().findChildByType(JetNodeTypes.BODY) -+ } -+ val bodyText = bodyElement?.getText() -+ val newElement = bodyElement?.getPsi()?.getPrevSibling()?.replace(JetPsiFactory.createExpression(element.getProject(), ""{\n $bodyText \n}"")) -+ newElement?.getParent()?.addBefore(JetPsiFactory.createWhiteSpace(element.getProject()), newElement) -+ bodyElement?.getPsi()?.delete()","Am I right that this sequence of safe calls is only because bodyElement can be null? Shouldn't it be checked in `isApplicable`? Otherwise there can be case when intention is available i UI, but will have no effect, which is confusing. -Side note: if some condition is to hard to check in isApplicable, it's a good idea to show error message. -",Please rename the file to `RemoveBrace -382,"@@ -0,0 +1,57 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetBlockExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetWhileExpression -+import org.jetbrains.jet.lang.psi.JetIfExpression -+import org.jetbrains.jet.lang.psi.JetDoWhileExpression -+import org.jetbrains.jet.lang.psi.JetForExpression -+import org.jetbrains.jet.lang.psi.JetExpressionImpl -+import org.jetbrains.jet.lang.psi.psiUtil.findBlockInExpression -+ -+ -+public class RemoveBracesIntention : JetSelfTargetingIntention(""remove.braces"", javaClass()) { -+ -+ override fun isApplicableTo(element: JetExpressionImpl): Boolean { -+ val conditionText = when (element) { -+ is JetIfExpression -> ""if"" -+ is JetWhileExpression -> ""while"" -+ is JetDoWhileExpression -> ""do...while"" -+ is JetForExpression -> ""for"" -+ else -> return false -+ }","Duplicate code. -",Please add a license to the top of all -383,"@@ -0,0 +1,57 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetBlockExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetWhileExpression -+import org.jetbrains.jet.lang.psi.JetIfExpression -+import org.jetbrains.jet.lang.psi.JetDoWhileExpression -+import org.jetbrains.jet.lang.psi.JetForExpression -+import org.jetbrains.jet.lang.psi.JetExpressionImpl -+import org.jetbrains.jet.lang.psi.psiUtil.findBlockInExpression -+ -+ -+public class RemoveBracesIntention : JetSelfTargetingIntention(""remove.braces"", javaClass()) { -+ -+ override fun isApplicableTo(element: JetExpressionImpl): Boolean { -+ val conditionText = when (element) { -+ is JetIfExpression -> ""if"" -+ is JetWhileExpression -> ""while"" -+ is JetDoWhileExpression -> ""do...while"" -+ is JetForExpression -> ""for"" -+ else -> return false -+ } -+ val jetBlockElement = element.findBlockInExpression(element) -+ if (jetBlockElement == null) return false -+ -+ if (jetBlockElement.getStatements().size == 1) { -+ setText(""Remove braces from '$conditionText' statement"") -+ return true -+ } -+ return false -+ } -+ -+ override fun applyTo(element: JetExpressionImpl, editor: Editor) { -+ val jetBlockElement = element.findBlockInExpression(element) -+ val newElement = jetBlockElement?.replace(JetPsiFactory.createExpression(element.getProject(), jetBlockElement?.getStatements()?.first?.getText()))","Safe call is redundant: we already checked for null in `isApplicable`. -",Please rename this file to `RemoveBrac -384,"@@ -0,0 +1,57 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetBlockExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetWhileExpression -+import org.jetbrains.jet.lang.psi.JetIfExpression -+import org.jetbrains.jet.lang.psi.JetDoWhileExpression -+import org.jetbrains.jet.lang.psi.JetForExpression -+import org.jetbrains.jet.lang.psi.JetExpressionImpl -+import org.jetbrains.jet.lang.psi.psiUtil.findBlockInExpression -+ -+ -+public class RemoveBracesIntention : JetSelfTargetingIntention(""remove.braces"", javaClass()) { -+ -+ override fun isApplicableTo(element: JetExpressionImpl): Boolean { -+ val conditionText = when (element) { -+ is JetIfExpression -> ""if"" -+ is JetWhileExpression -> ""while"" -+ is JetDoWhileExpression -> ""do...while"" -+ is JetForExpression -> ""for"" -+ else -> return false -+ } -+ val jetBlockElement = element.findBlockInExpression(element) -+ if (jetBlockElement == null) return false -+ -+ if (jetBlockElement.getStatements().size == 1) { -+ setText(""Remove braces from '$conditionText' statement"") -+ return true -+ } -+ return false -+ } -+ -+ override fun applyTo(element: JetExpressionImpl, editor: Editor) { -+ val jetBlockElement = element.findBlockInExpression(element) -+ val newElement = jetBlockElement?.replace(JetPsiFactory.createExpression(element.getProject(), jetBlockElement?.getStatements()?.first?.getText())) -+ if (element is JetDoWhileExpression) { -+ newElement?.getParent()?.addAfter(JetPsiFactory.createNewLine(element.getProject()), newElement) -+ }","Redundant safe calls again -",Please rename this file to `RemoveBracesForExpression`. -385,"@@ -0,0 +1,58 @@ -+/* -+ * 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.rmi -+ -+import java.rmi.Remote -+import java.rmi.RemoteException -+ -+public interface CompileService : Remote { -+ -+ public enum class OutputFormat : java.io.Serializable { -+ PLAIN, -+ XML -+ } -+ -+ public interface RemoteIncrementalCache : Remote { -+ throws(RemoteException::class)","Do we really need all those `throws` annotations? -",Is this an output format or format specified by the use -386,"@@ -0,0 +1,58 @@ -+/* -+ * 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.quickfix -+ -+import com.intellij.codeInsight.intention.IntentionAction -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiNameIdentifierOwner -+import org.jetbrains.kotlin.diagnostics.Diagnostic -+import org.jetbrains.kotlin.idea.core.deleteElementAndCleanParent -+import org.jetbrains.kotlin.psi.KtDeclaration -+import org.jetbrains.kotlin.psi.KtFile -+import org.jetbrains.kotlin.psi.KtProperty -+import org.jetbrains.kotlin.psi.KtPsiFactory -+import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType -+ -+/**",Please don't add `@author` tags to the code,Make sure the copyright header is formatted -387,"@@ -0,0 +1,58 @@ -+/* -+ * 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.quickfix -+ -+import com.intellij.codeInsight.intention.IntentionAction -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiNameIdentifierOwner -+import org.jetbrains.kotlin.diagnostics.Diagnostic -+import org.jetbrains.kotlin.idea.core.deleteElementAndCleanParent -+import org.jetbrains.kotlin.psi.KtDeclaration -+import org.jetbrains.kotlin.psi.KtFile -+import org.jetbrains.kotlin.psi.KtProperty -+import org.jetbrains.kotlin.psi.KtPsiFactory -+import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType -+ -+/** -+ * @author Andrius Semionovas -+ * @since 2017-07-31 -+ */ -+class ReplaceInitializerWithGetterFix(element: KtProperty): KotlinQuickFixAction(element) {",We already have `ConvertPropertyInitializerToGetterIntention` which is offered as an intention action in this context; you should be able to reuse it directly.,Is there a reason to create a new action here instead o -388,"@@ -0,0 +1,58 @@ -+/* -+ * 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.wrappers.symbols -+ -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.load.java.structure.JavaMember -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.Name -+import javax.lang.model.element.Element -+import javax.lang.model.element.TypeElement -+ -+abstract class SymbolBasedMember(element: T, -+ javac: JavacWrapper) : SymbolBasedElement(element, javac), JavaMember { -+ -+ override val containingClass -+ get() = SymbolBasedClass((element.enclosingElement as TypeElement), javac) -+ -+ override val annotations -+ get() = element.annotationMirrors -+ .map { SymbolBasedAnnotation(it, javac) } -+ -+ override fun findAnnotation(fqName: FqName) = element.annotationMirrors -+ .find { it.toString() == ""@${fqName.asString()}"" }","Please deduplicate this with `SymbolBasedClassifier.findAnnotation`, `SymbolBasedValueParameter.findAnnotation`, `SymbolBasedType.findAnnotation`",missing new line -389,"@@ -0,0 +1,59 @@ -+/* -+ * 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.quickfix -+ -+import com.intellij.codeInsight.intention.IntentionAction -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.project.Project -+import org.jetbrains.kotlin.diagnostics.Diagnostic -+import org.jetbrains.kotlin.diagnostics.Errors -+import org.jetbrains.kotlin.psi.KtAnnotationEntry -+import org.jetbrains.kotlin.psi.KtCallableDeclaration -+import org.jetbrains.kotlin.psi.KtFile -+import org.jetbrains.kotlin.psi.psiUtil.getParentOfType -+ -+class MoveReceiverAnnotationFix(element: KtAnnotationEntry) : KotlinQuickFixAction(element) { -+ -+ override fun getFamilyName() = ""Move annotation to receiver type"" -+ override fun getText() = familyName -+ -+ override fun invoke(project: Project, editor: Editor?, file: KtFile) { -+ val element = element ?: return -+ -+ val declaration = element.getParentOfType(true) ?: return -+ val receiverTypeRef = declaration.receiverTypeReference ?: return -+ -+ receiverTypeRef.addAnnotationEntry(element) -+ element.delete() -+ } -+ -+ companion object Factory : KotlinSingleIntentionActionFactory() { -+ override fun createAction(diagnostic: Diagnostic): IntentionAction? { -+ val diag = Errors.INAPPLICABLE_RECEIVER_TARGET.cast(diagnostic) -+ val entry = diag.psiElement as? KtAnnotationEntry ?: return null -+ -+ val declaration = entry.getParentOfType(true) ?: return null -+ if (declaration.receiverTypeReference == null) return null -+ -+ return MoveReceiverAnnotationFix(entry) -+ } -+ } -+} -+ -+fun String.foo() {",Looks like not-deleted trash. I'll remove it.,This file needs to be renamed to `RemoveReceiverAnnotat -390,"@@ -0,0 +1,59 @@ -+/* -+ * 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.wrappers.trees -+ -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.tree.JCTree -+import org.jetbrains.kotlin.descriptors.Visibilities -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.java.structure.JavaMethod -+import org.jetbrains.kotlin.name.Name -+ -+class JCMethod(tree: T, -+ treePath: TreePath, -+ containingClass: JavaClass, -+ javac: JavacWrapper) : JCMember(tree, treePath, containingClass, javac), JavaMethod { -+ -+ override val name -+ get() = Name.identifier(tree.name.toString()) -+ -+ override val isAbstract -+ get() = tree.modifiers.isAbstract",What about interface members? (not sure it's important),This file is missing a license header. -391,"@@ -0,0 +1,6 @@ -+// ""Add 'run' before the lambda expression"" ""true"" -+// ERROR: Unresolved reference: run","You can add WITH_RUNTIME directive so that the `run` function will be resolved correctly. -",The error should be resolved before the lambda expressi -392,"@@ -0,0 +1,6 @@ -+// ""Remove useless is check"" ""false"" -+fun foo(a: String) { -+ when (1) { -+ is Int -> { }","Well, it's an exceptional case but here we can also do something :). If a condition in when branch is definitely true, we can replace the condition with `else` and delete all subsequent branches because they are unreachable anyway. If the condition is definitely false (add test for this case), we can delete this when branch.",Not sure what the purpose of this test is here. -393,"@@ -0,0 +1,6 @@ -+// WITH_RUNTIME -+// IS_APPLICABLE: true -+ -+fun Int.foo() { -+ +1","This transformation does not look correct for me. I would expect `this + 1` as a result here, -",I think this file can be removed. -394,"@@ -0,0 +1,6 @@ -+//ERROR: Unresolved reference: SortedMap -+fun a(b: SortedMap) { -+ for ((index, c) in b.withIndices()) {","I'm not sure what's happening here because `SortedMap` is not an iterable/stream/array, so it doesn't have `withIndices` extension and the intention should not be applicable on it as well as on `Map` -",nit: this should probably have a `.withIndices()` inste -395,"@@ -0,0 +1,6 @@ -+public class Foo { -+ private native final void nativeMethod()","Please avoid irrelevant syntax errors in testdata. Java does require semicolons :) -",Could you make this `@nativeApi` please? -396,"@@ -0,0 +1,60 @@ -+/* -+ * 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.wrappers.trees -+ -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.tree.JCTree -+import org.jetbrains.kotlin.descriptors.Visibilities -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.java.structure.JavaMethod -+import org.jetbrains.kotlin.load.java.structure.JavaType -+import org.jetbrains.kotlin.name.Name -+ -+class JCMethod(tree: T, -+ treePath: TreePath, -+ containingClass: JavaClass, -+ javac: Javac) : JCMember(tree, treePath, containingClass, javac), JavaMethod { -+ -+ override val name -+ get() = Name.identifier(tree.name.toString())",This can be extracted into `JCMember`,This file is missing a license header. -397,"@@ -0,0 +1,60 @@ -+/* -+ * 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.wrappers.trees -+ -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.tree.JCTree -+import org.jetbrains.kotlin.descriptors.Visibilities -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.java.structure.JavaMethod -+import org.jetbrains.kotlin.load.java.structure.JavaType -+import org.jetbrains.kotlin.name.Name -+ -+class JCMethod(tree: T, -+ treePath: TreePath, -+ containingClass: JavaClass, -+ javac: Javac) : JCMember(tree, treePath, containingClass, javac), JavaMethod { -+ -+ override val name -+ get() = Name.identifier(tree.name.toString()) -+ -+ override val isAbstract -+ get() = tree.modifiers.isAbstract","Non-static methods in interface are `abstract` by default. However in Java 1.8+ they are not abstract if `default` modifier exists. Here we have complex logic, so be accurate, please.",I am not sure this is a good package name. `org.jetbrai -398,"@@ -0,0 +1,60 @@ -+/* -+ * 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.wrappers.trees -+ -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.tree.JCTree -+import org.jetbrains.kotlin.descriptors.Visibilities -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.java.structure.JavaMethod -+import org.jetbrains.kotlin.load.java.structure.JavaType -+import org.jetbrains.kotlin.name.Name -+ -+class JCMethod(tree: T, -+ treePath: TreePath, -+ containingClass: JavaClass, -+ javac: Javac) : JCMember(tree, treePath, containingClass, javac), JavaMethod { -+ -+ override val name -+ get() = Name.identifier(tree.name.toString()) -+ -+ override val isAbstract -+ get() = tree.modifiers.isAbstract -+ -+ override val isStatic -+ get() = tree.modifiers.isStatic -+ -+ override val isFinal -+ get() = tree.modifiers.isFinal",I think interface methods are never `final`,This file is missing a license header. -399,"@@ -0,0 +1,60 @@ -+/* -+ * 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.wrappers.trees -+ -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.tree.JCTree -+import org.jetbrains.kotlin.descriptors.Visibilities -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.java.structure.JavaMethod -+import org.jetbrains.kotlin.load.java.structure.JavaType -+import org.jetbrains.kotlin.name.Name -+ -+class JCMethod(tree: T, -+ treePath: TreePath, -+ containingClass: JavaClass, -+ javac: Javac) : JCMember(tree, treePath, containingClass, javac), JavaMethod { -+ -+ override val name -+ get() = Name.identifier(tree.name.toString()) -+ -+ override val isAbstract -+ get() = tree.modifiers.isAbstract -+ -+ override val isStatic -+ get() = tree.modifiers.isStatic -+ -+ override val isFinal -+ get() = tree.modifiers.isFinal -+ -+ override val visibility",This can be extracted into `JCMember`,This file is missing a license header. -400,"@@ -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.idea.intentions -+ -+import com.intellij.codeInsight.intention.LowPriorityAction -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.kotlin.idea.project.ProjectStructureUtil -+import org.jetbrains.kotlin.idea.util.addAnnotation -+import org.jetbrains.kotlin.idea.util.findAnnotation -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.psi.* -+ -+private val annotationFqName = FqName(""kotlin.jvm.JvmOverloads"") -+ -+class AddJvmOverloadsIntention : SelfTargetingIntention( -+ KtParameterList::class.java, ""Add '@JvmOverloads' annotation""","I think that all intentions that modify the declaration of a function need to be available on the function name. Showing this only on the parameter list is confusing -","No star imports, please." -401,"@@ -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.idea.intentions -+ -+import com.intellij.codeInsight.intention.LowPriorityAction -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.kotlin.idea.project.ProjectStructureUtil -+import org.jetbrains.kotlin.idea.util.addAnnotation -+import org.jetbrains.kotlin.idea.util.findAnnotation -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.psi.* -+ -+private val annotationFqName = FqName(""kotlin.jvm.JvmOverloads"") -+ -+class AddJvmOverloadsIntention : SelfTargetingIntention( -+ KtParameterList::class.java, ""Add '@JvmOverloads' annotation"" -+), LowPriorityAction { -+ -+ override fun isApplicableTo(element: KtParameterList, caretOffset: Int): Boolean { -+ val parent = element.parent as? KtModifierListOwner ?: return false -+ val target = when (parent) { -+ is KtNamedFunction -> ""function '${parent.name}'"" -+ is KtPrimaryConstructor -> ""primary constructor"" -+ is KtSecondaryConstructor -> ""secondary constructor"" -+ else -> return false -+ } -+ text = ""Add '@JvmOverloads' annotation to $target"" -+ -+ return !ProjectStructureUtil.isJsKotlinModule(element.getContainingKtFile())","If a constructor has one parameter with a default value, adding @JvmOverloads won't modify the resulting bytecode in any way, so the intention shouldn't be displayed. -",This file needs to be re -402,"@@ -0,0 +1,61 @@ -+/* -+ * 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.inspections -+ -+import com.intellij.codeInspection.LocalQuickFix -+import com.intellij.codeInspection.ProblemDescriptor -+import com.intellij.codeInspection.ProblemsHolder -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiElementVisitor -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.psi.KtVisitorVoid -+import org.jetbrains.kotlin.psi.KtWhenExpression -+import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression -+ -+class WhenWithOnlyElseInspection : AbstractKotlinInspection() { -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { -+ return object : KtVisitorVoid() { -+ override fun visitWhenExpression(expression: KtWhenExpression) { -+ super.visitWhenExpression(expression)",You don't actually need the `super` call here.,I don't like the name of -403,"@@ -0,0 +1,61 @@ -+/* -+ * 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.inspections -+ -+import com.intellij.codeInspection.LocalQuickFix -+import com.intellij.codeInspection.ProblemDescriptor -+import com.intellij.codeInspection.ProblemsHolder -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiElementVisitor -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.psi.KtVisitorVoid -+import org.jetbrains.kotlin.psi.KtWhenExpression -+import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression -+ -+class WhenWithOnlyElseInspection : AbstractKotlinInspection() { -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { -+ return object : KtVisitorVoid() { -+ override fun visitWhenExpression(expression: KtWhenExpression) { -+ super.visitWhenExpression(expression) -+ -+ val singleEntry = expression.entries.singleOrNull() -+ if (singleEntry?.isElse != true) return -+ -+ val usedAsExpression = expression.isUsedAsExpression(expression.analyze()) -+ -+ holder.registerProblem(expression, -+ ""'when' has only 'else' branch and can be simplified"", -+ SimplifyFix(usedAsExpression) -+ ) -+ } -+ } -+ } -+ -+ private class SimplifyFix( -+ private val isUsedAsExpression: Boolean -+ ) : LocalQuickFix { -+ override fun getFamilyName() = name -+ -+ override fun getName() = ""Simplify expression"" -+ -+ override fun applyFix(project: Project, descriptor: ProblemDescriptor) { -+ val whenExpression = descriptor.psiElement as? KtWhenExpression ?: return",Please don't forget `FileModificationService.getInstance().preparePsiElementForWrite()`,Please annotate `Abstrac -404,"@@ -0,0 +1,61 @@ -+/* -+ * 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.wrappers.symbols -+ -+import org.jetbrains.kotlin.descriptors.Visibilities -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.load.java.JavaVisibilities -+import org.jetbrains.kotlin.name.ClassId -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.Name -+import javax.lang.model.element.* -+ -+val Element.isAbstract",Please mark such declarations as `internal` (those that are only used from this module). Also in the other `utils.kt`,This file needs to be re -405,"@@ -0,0 +1,61 @@ -+/* -+ * 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.wrappers.symbols -+ -+import org.jetbrains.kotlin.descriptors.Visibilities -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.load.java.JavaVisibilities -+import org.jetbrains.kotlin.name.ClassId -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.Name -+import javax.lang.model.element.* -+ -+val Element.isAbstract -+ get() = modifiers.contains(Modifier.ABSTRACT) -+ -+val Element.isStatic -+ get() = modifiers.contains(Modifier.STATIC) -+ -+val Element.isFinal -+ get() = modifiers.contains(Modifier.FINAL) -+ -+fun Element.getVisibility() = when { -+ Modifier.PUBLIC in modifiers -> Visibilities.PUBLIC -+ Modifier.PRIVATE in modifiers -> Visibilities.PRIVATE -+ Modifier.PROTECTED in modifiers -> { -+ if (Modifier.STATIC in modifiers) { -+ JavaVisibilities.PROTECTED_STATIC_VISIBILITY -+ } -+ else { -+ JavaVisibilities.PROTECTED_AND_PACKAGE -+ } -+ } -+ else -> JavaVisibilities.PACKAGE_VISIBILITY -+} -+ -+fun TypeElement.computeClassId(): ClassId? { -+ if (enclosingElement.kind != ElementKind.PACKAGE) { -+ val parentClassId = (enclosingElement as TypeElement).computeClassId() ?: return null -+ return parentClassId.createNestedClassId(Name.identifier(simpleName.toString())) -+ } -+ -+ return ClassId.topLevel(FqName(qualifiedName.toString())) -+} -+ -+fun ExecutableElement.valueParameters(javac: JavacWrapper) = parameters.mapIndexed { index, it -> -+ SymbolBasedValueParameter(it, it.simpleName.toString(), (index == parameters.size - 1) && isVarArgs, javac)",`index == parameters.lastIndex`,This file needs to be re -406,"@@ -0,0 +1,63 @@ -+/* -+ * 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.idea.intentions.copyConcatenatedStringToClipboard -+ -+import org.jetbrains.kotlin.psi.* -+import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType -+import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType -+ -+class ConcatenatedStringGenerator { -+ fun create(element: KtBinaryExpression): String { -+ val binaryExpression = getBinaryParentExpression(element) -+ val stringBuilder = StringBuilder() -+ create(binaryExpression, stringBuilder) -+ return stringBuilder.toString() -+ } -+ -+ private fun getBinaryParentExpression(element: KtBinaryExpression): KtBinaryExpression { -+ var binaryExpression = element.getStrictParentOfType() ?: return element","There is `getTopmostParentOfTypes`, I think it should work here -",Please annotate with `@F -407,"@@ -0,0 +1,63 @@ -+/* -+ * 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.idea.intentions.copyConcatenatedStringToClipboard -+ -+import org.jetbrains.kotlin.psi.* -+import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType -+import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType -+ -+class ConcatenatedStringGenerator { -+ fun create(element: KtBinaryExpression): String { -+ val binaryExpression = getBinaryParentExpression(element) -+ val stringBuilder = StringBuilder() -+ create(binaryExpression, stringBuilder) -+ return stringBuilder.toString() -+ } -+ -+ private fun getBinaryParentExpression(element: KtBinaryExpression): KtBinaryExpression { -+ var binaryExpression = element.getStrictParentOfType() ?: return element -+ while (binaryExpression != null) { -+ binaryExpression = binaryExpression.getStrictParentOfType() ?: return element -+ } -+ return element -+ } -+ -+ private fun create(element: KtBinaryExpression, sb: StringBuilder) {","I'd declare it as something like `private fun KtBinaryExpression.appendTo(sb: StringBuilder)`. And the same for the next function. -",This file needs to be na -408,"@@ -0,0 +1,63 @@ -+/* -+ * 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.inspections -+ -+import com.intellij.codeInspection.IntentionWrapper -+import com.intellij.codeInspection.ProblemHighlightType -+import com.intellij.codeInspection.ProblemsHolder -+import com.intellij.psi.PsiElementVisitor -+import org.jetbrains.kotlin.descriptors.ClassDescriptor -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.idea.intentions.AddNamesToCallArgumentsIntention -+import org.jetbrains.kotlin.psi.KtCallExpression -+import org.jetbrains.kotlin.psi.KtNameReferenceExpression -+import org.jetbrains.kotlin.psi.KtVisitorVoid -+import org.jetbrains.kotlin.psi.psiUtil.referenceExpression -+import org.jetbrains.kotlin.resolve.BindingContext -+import org.jetbrains.kotlin.resolve.DataClassDescriptorResolver -+import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall -+import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode -+ -+class CopyWithoutNamedArgumentsInspection : AbstractKotlinInspection() { -+ -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { -+ return object : KtVisitorVoid() { -+ override fun visitCallExpression(expression: KtCallExpression) { -+ super.visitCallExpression(expression) -+ -+ val reference = expression.referenceExpression() as? KtNameReferenceExpression ?: return -+ if (reference.getReferencedNameAsName() != DataClassDescriptorResolver.COPY_METHOD_NAME) return -+ if (expression.valueArguments.none { !it.isNamed() }) return",`.all { it.isNamed() }` is easier to read.,Isn't this the same as ` -409,"@@ -0,0 +1,64 @@ -+# Enums -+ -+Goals: -+* Better syntax for passing constructor parameters when defining enum constants -+* Resolve issues with annotation syntax for enum constants -+ -+## Example -+ -+Simple enum: -+``` kotlin -+enum class Foo { -+ A -+ B -+ C { -+ override fun foo() { ... } -+ } -+ -+ open fun foo() {} -+} -+``` -+ -+Enum with constructor: -+``` kotlin -+enum class Foo(val s: String) { -+ A(""a"") -+ B(""b"") -+ C(""c"") { -+ override fun foo() { ... } -+ } -+ -+ open fun foo() {} -+} -+``` -+ -+Issues -+* Enum literals syntax clash with annotation syntax -+ * Option 1.1: Forbid short annotation syntax in enums. **downside**: cannot annotate functions/properties/classes in this enum -+ * Option 1.2: Add a separator between enum constants and members, and forbid short annotation syntax only on enum entriesc themselves. **downside**: separator is not intuitive, hard to think of when doign this for the first time (the error message will be rather clear and instructive, though)","Spelling: doign -> doing -",I'm not totally sure how -410,"@@ -0,0 +1,64 @@ -+# Enums -+ -+Goals: -+* Better syntax for passing constructor parameters when defining enum constants -+* Resolve issues with annotation syntax for enum constants -+ -+## Example -+ -+Simple enum: -+``` kotlin -+enum class Foo { -+ A -+ B -+ C { -+ override fun foo() { ... } -+ } -+ -+ open fun foo() {} -+} -+``` -+ -+Enum with constructor: -+``` kotlin -+enum class Foo(val s: String) { -+ A(""a"") -+ B(""b"") -+ C(""c"") { -+ override fun foo() { ... } -+ } -+ -+ open fun foo() {} -+} -+``` -+ -+Issues -+* Enum literals syntax clash with annotation syntax -+ * Option 1.1: Forbid short annotation syntax in enums. **downside**: cannot annotate functions/properties/classes in this enum -+ * Option 1.2: Add a separator between enum constants and members, and forbid short annotation syntax only on enum entriesc themselves. **downside**: separator is not intuitive, hard to think of when doing this for the first time (the error message will be rather clear and instructive, though) -+ * Option 1.3: prefix each entry with a soft-keyword, e.g. `entry`. **downside**: verbosity -+* How do we specify other supertypes for a constant (if any) -+ * Option 2.1: Leave unsupported, use cases are very few, and Java does not support it -+ * Option 2.2: `A(""s""): OtherType` -+ -+Example for option 1.2: -+ -+``` kotlin -+enum class Foo(val s: String) { -+ A(""a"") // semicolon CAN NOT be used here! -+ B(""b"") -+ C(""c"") { -+ override fun foo() { ... } -+ }; // semicolon is MANDATORY here, if a member follows -+ -+ // if no semicolon was provided, `open` is another enum entry -+ open fun foo() {} -+} -+``` -+ -+Notes: -+* No overhead in the most common case of no members at all: `enum class E {A B C}","Missing backtick? -",I'm not sure what the be -411,"@@ -0,0 +1,64 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.openapi.vfs.LocalFileSystem; -+import com.intellij.openapi.vfs.VirtualFile; -+import com.intellij.psi.PsiDocumentManager; -+import com.intellij.testFramework.PsiTestUtil; -+import org.jetbrains.jet.JetTestCaseBuilder; -+ -+import java.util.Arrays; -+import java.util.List; -+ -+public class FinalJavaSupertypeTest extends JetQuickFixMultiFileTest { -+ @Override -+ protected void setUp() throws Exception { -+ super.setUp(); -+ -+ String path = getTestDataPath(); -+ VirtualFile virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByPath(path); -+ if (virtualFile != null) { -+ virtualFile.getChildren(); -+ virtualFile.refresh(false, true); -+ }","This piece of code occurs at least three times in the code base, it probably means that we should create a utility method for it. -",Shouldn't we have a sepa -412,"@@ -0,0 +1,64 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.openapi.vfs.LocalFileSystem; -+import com.intellij.openapi.vfs.VirtualFile; -+import com.intellij.psi.PsiDocumentManager; -+import com.intellij.testFramework.PsiTestUtil; -+import org.jetbrains.jet.JetTestCaseBuilder; -+ -+import java.util.Arrays; -+import java.util.List; -+ -+public class FinalJavaSupertypeTest extends JetQuickFixMultiFileTest { -+ @Override -+ protected void setUp() throws Exception { -+ super.setUp(); -+ -+ String path = getTestDataPath(); -+ VirtualFile virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByPath(path); -+ if (virtualFile != null) { -+ virtualFile.getChildren(); -+ virtualFile.refresh(false, true); -+ } -+ } -+ -+ public void testFinalJavaSupertype() throws Exception { -+ String path = getTestDataPath() + ""/../javaCode/""; -+ final VirtualFile rootDir = PsiTestUtil.createTestProjectStructure(myProject, myModule, path, myFilesToDelete, false); -+ addSourceContentToRoots(myModule, rootDir); -+ PsiDocumentManager.getInstance(myProject).commitAllDocuments(); -+ doTest(); -+ } -+ -+ @Override -+ protected String getCheckFileName() { -+ assert false;","It's a lot better to explicitly throw an exception here + provide a comprehensible message that tells me why this behavior is not legitimate -",This file has nothing to -413,"@@ -0,0 +1,64 @@ -+/* -+ * 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.idea.inspections -+ -+import com.intellij.codeInspection.* -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiElementVisitor -+import org.jetbrains.kotlin.psi.* -+ -+class UnnecessaryJavaUsageInspection : AbstractKotlinInspection(), CleanupLocalInspectionTool { -+ -+ val patterns = mapOf( -+ ""System.out.println($0)"" to ""println($0)"", -+ ""System.out.print($0)"" to ""print($0)"", -+ ""Collections.sort($0)"" to ""$0.sort()"" -+ ) -+ -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor { -+ return object : KtVisitorVoid() { -+ override fun visitQualifiedExpression(expression: KtQualifiedExpression) { -+ super.visitQualifiedExpression(expression) -+ -+ val selectorExpression = expression.selectorExpression ?: return -+ if (selectorExpression !is KtCallExpression) return -+ if (selectorExpression.valueArguments.size != 1) return -+ val value = selectorExpression.valueArguments[0].text -+ val pattern = expression.text.replace(value, ""$0"")","This is not good enough. You need to resolve the call to make sure that it points to the correct method, and not to a method of a different class that also happens to be called `Collections`. -",Remove this file. -414,"@@ -0,0 +1,64 @@ -+/* -+ * 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.idea.inspections -+ -+import com.intellij.codeInspection.* -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiElementVisitor -+import org.jetbrains.kotlin.psi.* -+ -+class UnnecessaryJavaUsageInspection : AbstractKotlinInspection(), CleanupLocalInspectionTool { -+ -+ val patterns = mapOf( -+ ""System.out.println($0)"" to ""println($0)"", -+ ""System.out.print($0)"" to ""print($0)"", -+ ""Collections.sort($0)"" to ""$0.sort()"" -+ ) -+ -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor { -+ return object : KtVisitorVoid() { -+ override fun visitQualifiedExpression(expression: KtQualifiedExpression) { -+ super.visitQualifiedExpression(expression) -+ -+ val selectorExpression = expression.selectorExpression ?: return -+ if (selectorExpression !is KtCallExpression) return -+ if (selectorExpression.valueArguments.size != 1) return -+ val value = selectorExpression.valueArguments[0].text -+ val pattern = expression.text.replace(value, ""$0"") -+ if (!patterns.containsKey(pattern)) return -+ -+ holder.registerProblem(expression, -+ ""Unnecessary java usage"", -+ ProblemHighlightType.LIKE_UNUSED_SYMBOL,","LIKE_UNUSED_SYMBOL highlighting is applied to code fragments that can be removed entirely. In this case, the quick fix is not removing the code, but is replacing it with different code. -",Remove this file. -415,"@@ -0,0 +1,64 @@ -+/* -+ * 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.intentions -+ -+import com.intellij.codeInsight.intention.LowPriorityAction -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.util.TextRange -+import org.jetbrains.kotlin.builtins.KotlinBuiltIns -+import org.jetbrains.kotlin.idea.core.moveCaret -+import org.jetbrains.kotlin.idea.core.replaced -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.psi.KtDotQualifiedExpression -+import org.jetbrains.kotlin.psi.KtPsiFactory -+import org.jetbrains.kotlin.psi.createExpressionByPattern -+import org.jetbrains.kotlin.psi.psiUtil.startOffset -+import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull -+ -+class SwapStringEqualsIgnoreCaseIntention : SelfTargetingRangeIntention(KtDotQualifiedExpression::class.java, ""Flip 'equals'""), LowPriorityAction { -+ -+ override fun applicabilityRange(element: KtDotQualifiedExpression): TextRange? { -+ val descriptor = element.getCallableDescriptor() ?: return null -+ -+ val fqName: FqName = descriptor.fqNameOrNull() ?: return null -+ if (fqName.asString() != ""kotlin.text.equals"") return null -+ -+ val valueParameters = descriptor.valueParameters.takeIf { it.size == 2 } ?: return null -+ if (!KotlinBuiltIns.isStringOrNullableString(valueParameters[0].type)) return null -+ if (!KotlinBuiltIns.isBoolean(valueParameters[1].type)) return null -+ -+ return element.callExpression?.calleeExpression?.textRange -+ } -+ -+ override fun applyTo(element: KtDotQualifiedExpression, editor: Editor?) { -+ val callExpression = element.callExpression ?: return -+ val offset = (editor?.caretModel?.offset ?: 0) - (callExpression.calleeExpression?.startOffset ?: 0) -+ val receiverExpression = element.receiverExpression -+ val valueArguments = callExpression.valueArguments.takeIf { it.size == 2 } ?: return -+ val newElement = KtPsiFactory(element).createExpressionByPattern( -+ ""$0.equals($1, $2)"", -+ valueArguments[0].text,",It's better to use here expressions and not their text,Shouldn't we have some s -416,"@@ -0,0 +1,65 @@ -+/* -+ * 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.intentions -+ -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.util.TextRange -+import com.intellij.psi.PsiWhiteSpace -+import org.jetbrains.kotlin.lexer.KtTokens.* -+import org.jetbrains.kotlin.psi.KtClass -+import org.jetbrains.kotlin.psi.psiUtil.endOffset -+import org.jetbrains.kotlin.psi.psiUtil.startOffset -+ -+class ConvertClassToSealedClassIntention : SelfTargetingRangeIntention(KtClass::class.java, ""Convert to sealed class"") { -+ -+ override fun applicabilityRange(element: KtClass): TextRange? { -+ if (element.modifierList == null) return null -+ if (!element.hasModifier(OPEN_KEYWORD) && !element.hasModifier(ABSTRACT_KEYWORD)) return null -+ -+ val constructors = listOfNotNull(element.primaryConstructor) + element.secondaryConstructors -+ if (constructors.isEmpty()) return null -+ if (constructors.any { !it.hasModifier(PRIVATE_KEYWORD) }) return null",Please use `none` instead of `any` with a negative condition.,This file needs to be renamed. -417,"@@ -0,0 +1,65 @@ -+/* -+ * 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.intentions -+ -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.util.TextRange -+import com.intellij.psi.PsiWhiteSpace -+import org.jetbrains.kotlin.lexer.KtTokens.* -+import org.jetbrains.kotlin.psi.KtClass -+import org.jetbrains.kotlin.psi.psiUtil.endOffset -+import org.jetbrains.kotlin.psi.psiUtil.startOffset -+ -+class ConvertClassToSealedClassIntention : SelfTargetingRangeIntention(KtClass::class.java, ""Convert to sealed class"") { -+ -+ override fun applicabilityRange(element: KtClass): TextRange? { -+ if (element.modifierList == null) return null -+ if (!element.hasModifier(OPEN_KEYWORD) && !element.hasModifier(ABSTRACT_KEYWORD)) return null -+ -+ val constructors = listOfNotNull(element.primaryConstructor) + element.secondaryConstructors -+ if (constructors.isEmpty()) return null -+ if (constructors.any { !it.hasModifier(PRIVATE_KEYWORD) }) return null -+ -+ val nameIdentifier = element.nameIdentifier ?: return null -+ return TextRange(element.startOffset, nameIdentifier.endOffset) -+ } -+ -+ override fun applyTo(element: KtClass, editor: Editor?) { -+ val newElement = element.copy() as KtClass",It doesn't seem necessary to create a copy; you should be able to apply all the changes to the original `KtClass` directly.,This file needs to be renamed. -418,"@@ -0,0 +1,65 @@ -+/* -+ * 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.intentions -+ -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.util.TextRange -+import com.intellij.psi.PsiWhiteSpace -+import org.jetbrains.kotlin.lexer.KtTokens.* -+import org.jetbrains.kotlin.psi.KtClass -+import org.jetbrains.kotlin.psi.psiUtil.endOffset -+import org.jetbrains.kotlin.psi.psiUtil.startOffset -+ -+class ConvertClassToSealedClassIntention : SelfTargetingRangeIntention(KtClass::class.java, ""Convert to sealed class"") { -+ -+ override fun applicabilityRange(element: KtClass): TextRange? { -+ if (element.modifierList == null) return null -+ if (!element.hasModifier(OPEN_KEYWORD) && !element.hasModifier(ABSTRACT_KEYWORD)) return null -+ -+ val constructors = listOfNotNull(element.primaryConstructor) + element.secondaryConstructors -+ if (constructors.isEmpty()) return null -+ if (constructors.any { !it.hasModifier(PRIVATE_KEYWORD) }) return null -+ -+ val nameIdentifier = element.nameIdentifier ?: return null -+ return TextRange(element.startOffset, nameIdentifier.endOffset) -+ } -+ -+ override fun applyTo(element: KtClass, editor: Editor?) { -+ val newElement = element.copy() as KtClass -+ -+ newElement.modifierList?.run { -+ getModifier(OPEN_KEYWORD)?.delete() -+ getModifier(ABSTRACT_KEYWORD)?.delete() -+ newElement.addModifier(SEALED_KEYWORD)",It's better to move this line out of the `run` block.,This file needs to be renamed. -419,"@@ -0,0 +1,65 @@ -+/* -+ * 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.intentions -+ -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.util.TextRange -+import com.intellij.psi.PsiWhiteSpace -+import org.jetbrains.kotlin.lexer.KtTokens.* -+import org.jetbrains.kotlin.psi.KtClass -+import org.jetbrains.kotlin.psi.psiUtil.endOffset -+import org.jetbrains.kotlin.psi.psiUtil.startOffset -+ -+class ConvertClassToSealedClassIntention : SelfTargetingRangeIntention(KtClass::class.java, ""Convert to sealed class"") { -+ -+ override fun applicabilityRange(element: KtClass): TextRange? { -+ if (element.modifierList == null) return null -+ if (!element.hasModifier(OPEN_KEYWORD) && !element.hasModifier(ABSTRACT_KEYWORD)) return null -+ -+ val constructors = listOfNotNull(element.primaryConstructor) + element.secondaryConstructors -+ if (constructors.isEmpty()) return null -+ if (constructors.any { !it.hasModifier(PRIVATE_KEYWORD) }) return null -+ -+ val nameIdentifier = element.nameIdentifier ?: return null -+ return TextRange(element.startOffset, nameIdentifier.endOffset) -+ } -+ -+ override fun applyTo(element: KtClass, editor: Editor?) { -+ val newElement = element.copy() as KtClass -+ -+ newElement.modifierList?.run { -+ getModifier(OPEN_KEYWORD)?.delete() -+ getModifier(ABSTRACT_KEYWORD)?.delete() -+ newElement.addModifier(SEALED_KEYWORD) -+ } -+ -+ newElement.primaryConstructor?.run { -+ modifierList?.getModifier(PRIVATE_KEYWORD)?.delete() -+ getConstructorKeyword()?.delete()",The `constructor` keyword can only be deleted if there are no annotations or other modifiers on the constructor. Please add a test for the case with annotations.,This file needs to be renamed. -420,"@@ -0,0 +1,65 @@ -+/* -+ * 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.intentions -+ -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.util.TextRange -+import com.intellij.psi.PsiWhiteSpace -+import org.jetbrains.kotlin.lexer.KtTokens.* -+import org.jetbrains.kotlin.psi.KtClass -+import org.jetbrains.kotlin.psi.psiUtil.endOffset -+import org.jetbrains.kotlin.psi.psiUtil.startOffset -+ -+class ConvertClassToSealedClassIntention : SelfTargetingRangeIntention(KtClass::class.java, ""Convert to sealed class"") { -+ -+ override fun applicabilityRange(element: KtClass): TextRange? { -+ if (element.modifierList == null) return null -+ if (!element.hasModifier(OPEN_KEYWORD) && !element.hasModifier(ABSTRACT_KEYWORD)) return null -+ -+ val constructors = listOfNotNull(element.primaryConstructor) + element.secondaryConstructors -+ if (constructors.isEmpty()) return null -+ if (constructors.any { !it.hasModifier(PRIVATE_KEYWORD) }) return null -+ -+ val nameIdentifier = element.nameIdentifier ?: return null -+ return TextRange(element.startOffset, nameIdentifier.endOffset) -+ } -+ -+ override fun applyTo(element: KtClass, editor: Editor?) { -+ val newElement = element.copy() as KtClass -+ -+ newElement.modifierList?.run { -+ getModifier(OPEN_KEYWORD)?.delete() -+ getModifier(ABSTRACT_KEYWORD)?.delete() -+ newElement.addModifier(SEALED_KEYWORD) -+ } -+ -+ newElement.primaryConstructor?.run { -+ modifierList?.getModifier(PRIVATE_KEYWORD)?.delete() -+ getConstructorKeyword()?.delete() -+ if (newElement.secondaryConstructors.isEmpty() && valueParameters.isEmpty()) valueParameterList?.delete() -+ (newElement.nameIdentifier?.prevSibling as? PsiWhiteSpace)?.delete()",It should never be necessary to do that manually; the formatter should take care of whitespaces.,This file needs to be renamed. -421,"@@ -0,0 +1,65 @@ -+/* -+ * 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.javac -+ -+import com.sun.tools.javac.util.Context -+import com.sun.tools.javac.util.Log -+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity -+import org.jetbrains.kotlin.cli.common.messages.GroupingMessageCollector -+import org.jetbrains.kotlin.cli.common.messages.MessageCollector -+import java.io.PrintWriter -+import java.io.Writer -+ -+class JavacLogger(context: Context, -+ errorWriter: PrintWriter, -+ warningWriter: PrintWriter, -+ infoWriter: PrintWriter) : Log(context, errorWriter, warningWriter, infoWriter) { -+ init { -+ context.put(Log.outKey, infoWriter) -+ } -+ -+ override fun printLines(kind: WriterKind, message: String, vararg args: Any?) {} -+ -+ companion object { -+ fun preRegister(context: Context, messageCollector: MessageCollector) { -+ context.put(Log.logKey, Context.Factory { -+ JavacLogger(it, -+ PrintWriter(MessageCollectorAdapter(messageCollector, CompilerMessageSeverity.ERROR)), -+ PrintWriter(MessageCollectorAdapter(messageCollector, CompilerMessageSeverity.WARNING)), -+ PrintWriter(MessageCollectorAdapter(messageCollector, CompilerMessageSeverity.INFO))) -+ }) -+ } -+ } -+ -+} -+ -+private class MessageCollectorAdapter(private val messageCollector: MessageCollector, -+ private val severity: CompilerMessageSeverity) : Writer() { -+ -+ override fun write(buffer: CharArray, offset: Int, length: Int) { -+ if (length > 1) {",Why? A comment would be helpful here,This is a good example of how -422,"@@ -0,0 +1,66 @@ -+/* -+ * 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.components -+ -+import com.sun.tools.javac.tree.JCTree -+import org.jetbrains.kotlin.descriptors.PropertyDescriptor -+import org.jetbrains.kotlin.load.java.components.JavaPropertyInitializerEvaluator -+import org.jetbrains.kotlin.load.java.structure.JavaField -+import org.jetbrains.kotlin.resolve.constants.ConstantValueFactory -+import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns -+import org.jetbrains.kotlin.wrappers.symbols.JavacField -+import org.jetbrains.kotlin.wrappers.trees.JCClassifierType -+import org.jetbrains.kotlin.wrappers.trees.JCField -+import org.jetbrains.kotlin.wrappers.trees.JCPrimitiveType -+ -+class JavacBasedPropertyInitializerEvaluator : JavaPropertyInitializerEvaluator { -+ -+ override fun getInitializerConstant(field: JavaField, descriptor: PropertyDescriptor) = when (field) { -+ is JavacField<*> -> field.constant(descriptor) -+ is JCField<*> -> field.constant(descriptor) -+ else -> null -+ } -+ -+ override fun isNotNullCompileTimeConstant(field: JavaField) = when(field) { -+ is JavacField<*> -> field.isCompileTimeConstant() -+ is JCField<*> -> field.isCompileTimeConstant() -+ else -> false -+ } -+ -+ private fun JavacField<*>.constant(descriptor: PropertyDescriptor) = value?.let { -+ ConstantValueFactory(descriptor.builtIns).createConstantValue(it) -+ } -+ -+ private fun JCField<*>.constant(descriptor: PropertyDescriptor) = value?.let { -+ if (isCompileTimeConstant() && it is JCTree.JCLiteral) { -+ ConstantValueFactory(descriptor.builtIns).createConstantValue(it.value) -+ } else null -+ } -+ -+ private fun JavacField<*>.isCompileTimeConstant() = value?.let { -+ val typeMirror = type.typeMirror -+ -+ (typeMirror.kind.isPrimitive || typeMirror.toString() == ""java.lang.String"")","It would be better to avoid `toString()` call here, if possible. Does this `typeMirror` have something like `name` or `fqName`?",This file needs to be renamed -423,"@@ -0,0 +1,68 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.project.Project; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.impl.source.tree.LeafPsiElement; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.plugin.JetBundle; -+ -+public class RemoveSpreadFix extends JetIntentionAction{ -+ private final LeafPsiElement spreadSign; -+ -+ public RemoveSpreadFix(@NotNull LeafPsiElement element) { -+ super(element); -+ spreadSign = element; -+ } -+ -+ @NotNull -+ @Override -+ public String getText() { -+ return JetBundle.message(""remove.spread.sign""); -+ } -+ -+ @NotNull -+ @Override -+ public String getFamilyName() { -+ return JetBundle.message(""remove.spread.sign""); -+ } -+ -+ @Override -+ public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { -+ spreadSign.delete(); -+ } -+ -+ public static JetIntentionActionFactory createFactory() { -+ return new JetIntentionActionFactory() { -+ @Override -+ public JetIntentionAction createAction(Diagnostic diagnostic) { -+ PsiElement element = diagnostic.getPsiElement(); -+ if (!(element instanceof LeafPsiElement)) return null;","Almost right, but here's the way to do it without constant: - -``` -if (leaf instanceof LeafPsiElement && ((LeafPsiElement)leaf).getElementType() == JetTokens.MUL) { -} -``` -",Maybe we should call this clas -424,"@@ -0,0 +1,68 @@ -+/* -+ * 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.effectsystem.functors -+ -+import org.jetbrains.kotlin.effectsystem.impls.or -+import org.jetbrains.kotlin.effectsystem.factories.lift -+import org.jetbrains.kotlin.effectsystem.structure.* -+ -+/** -+ * Applies [operation] to [first] and [second] if both not-null, otherwise returns null -+ */ -+internal fun applyIfBothNotNull(first: F?, second: S?, operation: (F, S) -> R): R? = -+ if (first == null || second == null) null else operation(first, second) -+ -+/** -+ * If both [first] and [second] are null, then return null -+ * If only one of [first] and [second] is null, then return other one -+ * Otherwise, return result of [operation] -+ */ -+internal fun applyWithDefault(first: F?, second: S?, operation: (F, S) -> R): R? = when { -+ first == null && second == null -> null -+ first == null -> second -+ second == null -> first -+ else -> operation(first, second) -+} -+ -+internal fun foldConditionsWithOr(list: List): ESBooleanExpression? = -+ if (list.isEmpty()) -+ null -+ else -+ list.map { it.condition }.reduce { acc, condition -> acc.or(condition) } -+ -+/** -+ * Places all clauses that equal to `firstModel` into first list, and all clauses that equal to `secondModel` into second list -+ */ -+internal fun List.strictPartition(firstModel: ESEffect, secondModel: ESEffect): Pair, List> {","May be it's better to return here just lists of conditions, not lists of clauses. Then you can accept list of conditions in `foldConditionsWithOr`.","If the list is empty, then `nu" -425,"@@ -0,0 +1,68 @@ -+/* -+ * 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.inspections -+ -+import com.intellij.codeInspection.* -+import com.intellij.openapi.project.Project -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.idea.core.replaced -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.KtParenthesizedExpression -+import org.jetbrains.kotlin.psi.KtPrefixExpression -+import org.jetbrains.kotlin.psi.KtVisitorVoid -+import org.jetbrains.kotlin.resolve.calls.callUtil.getType -+import org.jetbrains.kotlin.types.typeUtil.isBoolean -+ -+class DoubleNegationInspection : AbstractKotlinInspection(), CleanupLocalInspectionTool { -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession) = -+ object : KtVisitorVoid() { -+ override fun visitPrefixExpression(expression: KtPrefixExpression) { -+ if (expression.operationToken != KtTokens.EXCL || expression.baseExpression?.getType(expression.analyze())?.isBoolean() != true) { -+ return -+ } -+ var parent = expression.parent -+ while (parent is KtParenthesizedExpression) { -+ parent = parent.parent -+ } -+ if (parent is KtPrefixExpression && parent.operationToken == KtTokens.EXCL) { -+ holder.registerProblem(expression, -+ ""Redundant double negation"", -+ ProblemHighlightType.WEAK_WARNING,","For future: use here `GENERIC_ERROR_OR_WARNING` if you want to get highlight type depending on inspection severity level (by default, from plugin.xml, or configured by user). Explicitly given `WEAK_WARNING` enforces this severiry level making it unconfigurable by user (will fix myself).",This file needs to be renamed. -426,"@@ -0,0 +1,68 @@ -+/* -+ * 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.inspections -+ -+import com.intellij.codeInspection.CleanupLocalInspectionTool -+import com.intellij.codeInspection.LocalInspectionToolSession -+import com.intellij.codeInspection.ProblemHighlightType -+import com.intellij.codeInspection.ProblemsHolder -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.* -+import java.util.* -+ -+class SuspiciousEqualsCombination : AbstractKotlinInspection(), CleanupLocalInspectionTool { -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession) = -+ object : KtVisitorVoid() { -+ override fun visitBinaryExpression(expression: KtBinaryExpression) { -+ if (expression.parent is KtBinaryExpression) return -+ val (first, second) = expression.parseBinary() -+ val eqeq = first.map { it.text } -+ val eqeqeq = second.map { it.text } -+ if (eqeq.fold(false) { acc, it -> acc || eqeqeq.contains(it) }) { -+ holder.registerProblem(expression, ""Suspicious combination of == and ==="", -+ ProblemHighlightType.GENERIC_ERROR_OR_WARNING) -+ } -+ } -+ } -+ -+ private fun KtBinaryExpression.parseBinary(pair: Pair, MutableList>","I think the intent of this code will be much clearer if you used an explicit class instead of a Pair: - -``` -data class ComparisonOperands(val eqEqOperands: MutableList, val eqEqEqOperands: MutableList)",Please rename `eqeq` to someth -427,"@@ -0,0 +1,68 @@ -+/* -+ * 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.inspections -+ -+import com.intellij.codeInspection.CleanupLocalInspectionTool -+import com.intellij.codeInspection.LocalInspectionToolSession -+import com.intellij.codeInspection.ProblemHighlightType -+import com.intellij.codeInspection.ProblemsHolder -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.* -+import java.util.* -+ -+class SuspiciousEqualsCombination : AbstractKotlinInspection(), CleanupLocalInspectionTool { -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession) = -+ object : KtVisitorVoid() { -+ override fun visitBinaryExpression(expression: KtBinaryExpression) { -+ if (expression.parent is KtBinaryExpression) return -+ val (first, second) = expression.parseBinary() -+ val eqeq = first.map { it.text } -+ val eqeqeq = second.map { it.text } -+ if (eqeq.fold(false) { acc, it -> acc || eqeqeq.contains(it) }) { -+ holder.registerProblem(expression, ""Suspicious combination of == and ==="", -+ ProblemHighlightType.GENERIC_ERROR_OR_WARNING) -+ } -+ } -+ } -+ -+ private fun KtBinaryExpression.parseBinary(pair: Pair, MutableList> -+ = Pair(LinkedList(), LinkedList())): Pair, MutableList> {",Please don't use `LinkedList` for anything ever. :),Please rename `eqeq` to someth -428,"@@ -0,0 +1,68 @@ -+/* -+ * 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.inspections -+ -+import com.intellij.codeInspection.CleanupLocalInspectionTool -+import com.intellij.codeInspection.LocalInspectionToolSession -+import com.intellij.codeInspection.ProblemHighlightType -+import com.intellij.codeInspection.ProblemsHolder -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.* -+import java.util.* -+ -+class SuspiciousEqualsCombination : AbstractKotlinInspection(), CleanupLocalInspectionTool { -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession) = -+ object : KtVisitorVoid() { -+ override fun visitBinaryExpression(expression: KtBinaryExpression) { -+ if (expression.parent is KtBinaryExpression) return -+ val (first, second) = expression.parseBinary() -+ val eqeq = first.map { it.text } -+ val eqeqeq = second.map { it.text } -+ if (eqeq.fold(false) { acc, it -> acc || eqeqeq.contains(it) }) { -+ holder.registerProblem(expression, ""Suspicious combination of == and ==="", -+ ProblemHighlightType.GENERIC_ERROR_OR_WARNING) -+ } -+ } -+ } -+ -+ private fun KtBinaryExpression.parseBinary(pair: Pair, MutableList> -+ = Pair(LinkedList(), LinkedList())): Pair, MutableList> { -+ when (operationToken) { -+ KtTokens.EQEQ, KtTokens.EXCLEQ -> { -+ left?.let(pair.first::add)","I'd check that the operands are `KtNameReferenceExpression`'s, to make the behavior more predictable.",Please rename `eqeq` to someth -429,"@@ -0,0 +1,69 @@ -+/* -+ * 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.idea.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.idea.core.replaced -+import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection -+import org.jetbrains.kotlin.js.descriptorUtils.getJetTypeFqName -+import org.jetbrains.kotlin.psi.KtConstantExpression -+import org.jetbrains.kotlin.psi.KtDotQualifiedExpression -+import org.jetbrains.kotlin.psi.KtStringTemplateExpression -+import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall -+import org.jetbrains.kotlin.resolve.calls.callUtil.getType -+import java.util.* -+ -+class RemoveRedundantCallsOfConversionMethodsInspection : IntentionBasedInspection(RemoveRedundantCallsOfConversionMethodsIntention::class)","I think these redundant calls should be highlighted as unused symbols. -",Why do we need a class for thi -430,"@@ -0,0 +1,69 @@ -+/* -+ * 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.idea.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.idea.core.replaced -+import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection -+import org.jetbrains.kotlin.js.descriptorUtils.getJetTypeFqName -+import org.jetbrains.kotlin.psi.KtConstantExpression -+import org.jetbrains.kotlin.psi.KtDotQualifiedExpression -+import org.jetbrains.kotlin.psi.KtStringTemplateExpression -+import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall -+import org.jetbrains.kotlin.resolve.calls.callUtil.getType -+import java.util.* -+ -+class RemoveRedundantCallsOfConversionMethodsInspection : IntentionBasedInspection(RemoveRedundantCallsOfConversionMethodsIntention::class) -+ -+class RemoveRedundantCallsOfConversionMethodsIntention : SelfTargetingOffsetIndependentIntention(KtDotQualifiedExpression::class.java, ""Remove redundant calls of the conversion method"") { -+ -+ private val targetClassMap = mapOf(""toList()"" to List::class.qualifiedName, -+ ""toSet()"" to Set::class.qualifiedName, -+ ""toMap()"" to Map::class.qualifiedName, -+ ""toMutableList()"" to ""kotlin.collections.MutableList"", -+ ""toMutableSet()"" to ""kotlin.collections.MutableSet"", -+ ""toMutableMap()"" to ""kotlin.collections.MutableMap"", -+ ""toSortedSet()"" to SortedSet::class.qualifiedName, -+ ""toSortedMap()"" to SortedMap::class.qualifiedName, -+ ""toString()"" to String::class.qualifiedName, -+ ""toDouble()"" to Double::class.qualifiedName, -+ ""toFloat()"" to Float::class.qualifiedName, -+ ""toLong()"" to Long::class.qualifiedName, -+ ""toInt()"" to Int::class.qualifiedName, -+ ""toChar()"" to Char::class.qualifiedName, -+ ""toShort()"" to Short::class.qualifiedName, -+ ""toByte()"" to Byte::class.qualifiedName) -+ -+ -+ override fun applyTo(element: KtDotQualifiedExpression, editor: Editor?) { -+ element.replaced(element.receiverExpression) -+ -+ mutableMapOf(1 to 1).toMutableMap()","What is it? Looks like it's not needed here :) -",This file should be removed. -431,"@@ -0,0 +1,69 @@ -+/* -+ * 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.idea.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.idea.core.replaced -+import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection -+import org.jetbrains.kotlin.js.descriptorUtils.getJetTypeFqName -+import org.jetbrains.kotlin.psi.KtConstantExpression -+import org.jetbrains.kotlin.psi.KtDotQualifiedExpression -+import org.jetbrains.kotlin.psi.KtStringTemplateExpression -+import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall -+import org.jetbrains.kotlin.resolve.calls.callUtil.getType -+import java.util.* -+ -+class RemoveRedundantCallsOfConversionMethodsInspection : IntentionBasedInspection(RemoveRedundantCallsOfConversionMethodsIntention::class) -+ -+class RemoveRedundantCallsOfConversionMethodsIntention : SelfTargetingOffsetIndependentIntention(KtDotQualifiedExpression::class.java, ""Remove redundant calls of the conversion method"") { -+ -+ private val targetClassMap = mapOf(""toList()"" to List::class.qualifiedName, -+ ""toSet()"" to Set::class.qualifiedName, -+ ""toMap()"" to Map::class.qualifiedName, -+ ""toMutableList()"" to ""kotlin.collections.MutableList"", -+ ""toMutableSet()"" to ""kotlin.collections.MutableSet"", -+ ""toMutableMap()"" to ""kotlin.collections.MutableMap"", -+ ""toSortedSet()"" to SortedSet::class.qualifiedName, -+ ""toSortedMap()"" to SortedMap::class.qualifiedName, -+ ""toString()"" to String::class.qualifiedName, -+ ""toDouble()"" to Double::class.qualifiedName, -+ ""toFloat()"" to Float::class.qualifiedName, -+ ""toLong()"" to Long::class.qualifiedName, -+ ""toInt()"" to Int::class.qualifiedName, -+ ""toChar()"" to Char::class.qualifiedName, -+ ""toShort()"" to Short::class.qualifiedName, -+ ""toByte()"" to Byte::class.qualifiedName) -+ -+ -+ override fun applyTo(element: KtDotQualifiedExpression, editor: Editor?) { -+ element.replaced(element.receiverExpression) -+ -+ mutableMapOf(1 to 1).toMutableMap() -+ } -+ -+ override fun isApplicableTo(element: KtDotQualifiedExpression): Boolean {","Looks like we can apply this intention for all qualified expressions, not only unsafe ones. -",This file should be removed. -432,"@@ -0,0 +1,69 @@ -+/* -+ * 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.idea.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.idea.core.replaced -+import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection -+import org.jetbrains.kotlin.js.descriptorUtils.getJetTypeFqName -+import org.jetbrains.kotlin.psi.KtConstantExpression -+import org.jetbrains.kotlin.psi.KtDotQualifiedExpression -+import org.jetbrains.kotlin.psi.KtStringTemplateExpression -+import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall -+import org.jetbrains.kotlin.resolve.calls.callUtil.getType -+import java.util.* -+ -+class RemoveRedundantCallsOfConversionMethodsInspection : IntentionBasedInspection(RemoveRedundantCallsOfConversionMethodsIntention::class) -+ -+class RemoveRedundantCallsOfConversionMethodsIntention : SelfTargetingOffsetIndependentIntention(KtDotQualifiedExpression::class.java, ""Remove redundant calls of the conversion method"") { -+ -+ private val targetClassMap = mapOf(""toList()"" to List::class.qualifiedName, -+ ""toSet()"" to Set::class.qualifiedName, -+ ""toMap()"" to Map::class.qualifiedName, -+ ""toMutableList()"" to ""kotlin.collections.MutableList"", -+ ""toMutableSet()"" to ""kotlin.collections.MutableSet"", -+ ""toMutableMap()"" to ""kotlin.collections.MutableMap"", -+ ""toSortedSet()"" to SortedSet::class.qualifiedName, -+ ""toSortedMap()"" to SortedMap::class.qualifiedName, -+ ""toString()"" to String::class.qualifiedName, -+ ""toDouble()"" to Double::class.qualifiedName, -+ ""toFloat()"" to Float::class.qualifiedName, -+ ""toLong()"" to Long::class.qualifiedName, -+ ""toInt()"" to Int::class.qualifiedName, -+ ""toChar()"" to Char::class.qualifiedName, -+ ""toShort()"" to Short::class.qualifiedName, -+ ""toByte()"" to Byte::class.qualifiedName) -+ -+ -+ override fun applyTo(element: KtDotQualifiedExpression, editor: Editor?) { -+ element.replaced(element.receiverExpression) -+ -+ mutableMapOf(1 to 1).toMutableMap() -+ } -+ -+ override fun isApplicableTo(element: KtDotQualifiedExpression): Boolean { -+ val selectorExpressionText = element.selectorExpression?.text -+ val qualifiedName = targetClassMap[selectorExpressionText] ?: return false -+ val receiverExpression = element.receiverExpression -+ return when (receiverExpression) { -+ is KtStringTemplateExpression -> String::class.qualifiedName -+ is KtConstantExpression -> receiverExpression.getType(receiverExpression.analyze())?.getJetTypeFqName(false) -+ else -> receiverExpression.getResolvedCall(receiverExpression.analyze())?.candidateDescriptor?.returnType?.getJetTypeFqName(false) -+ } == qualifiedName","I'm not sure here what will be happened if somebody defines custom `toType()` function. Probably it's not too important, because it's expected that `toType()` has result of `Type` anyway. -",This file should be removed. -433,"@@ -0,0 +1,69 @@ -+/* -+ * 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.idea.quickfix -+ -+import com.intellij.codeInsight.intention.IntentionAction -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.project.Project -+import org.jetbrains.kotlin.builtins.getReturnTypeFromFunctionType -+import org.jetbrains.kotlin.builtins.isExtensionFunctionType -+import org.jetbrains.kotlin.diagnostics.Diagnostic -+import org.jetbrains.kotlin.diagnostics.Errors -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.idea.core.ShortenReferences -+import org.jetbrains.kotlin.idea.core.replaced -+import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers -+import org.jetbrains.kotlin.psi.KtFile -+import org.jetbrains.kotlin.psi.KtPsiFactory -+import org.jetbrains.kotlin.psi.KtTypeReference -+import org.jetbrains.kotlin.renderer.DescriptorRenderer -+import org.jetbrains.kotlin.resolve.BindingContext -+import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode -+import org.jetbrains.kotlin.types.KotlinType -+ -+class ConvertExtensionToFunctionTypeFix(element: KtTypeReference, type: KotlinType) : KotlinQuickFixAction(element) { -+ -+ private val targetTypeStringShort = type.renderType(IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES) -+ private val targetTypeStringLong = type.renderType(IdeDescriptorRenderers.SOURCE_CODE) -+ -+ override fun getText() = ""Convert supertype to '$targetTypeStringShort'"" -+ override fun getFamilyName() = ""Convert extension function type to regular function type.""","No period here please -",Please add the license heade -434,"@@ -0,0 +1,69 @@ -+/* -+ * 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.idea.quickfix -+ -+import com.intellij.codeInsight.intention.IntentionAction -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.project.Project -+import org.jetbrains.kotlin.builtins.getReturnTypeFromFunctionType -+import org.jetbrains.kotlin.builtins.isExtensionFunctionType -+import org.jetbrains.kotlin.diagnostics.Diagnostic -+import org.jetbrains.kotlin.diagnostics.Errors -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.idea.core.ShortenReferences -+import org.jetbrains.kotlin.idea.core.replaced -+import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers -+import org.jetbrains.kotlin.psi.KtFile -+import org.jetbrains.kotlin.psi.KtPsiFactory -+import org.jetbrains.kotlin.psi.KtTypeReference -+import org.jetbrains.kotlin.renderer.DescriptorRenderer -+import org.jetbrains.kotlin.resolve.BindingContext -+import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode -+import org.jetbrains.kotlin.types.KotlinType -+ -+class ConvertExtensionToFunctionTypeFix(element: KtTypeReference, type: KotlinType) : KotlinQuickFixAction(element) { -+ -+ private val targetTypeStringShort = type.renderType(IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES) -+ private val targetTypeStringLong = type.renderType(IdeDescriptorRenderers.SOURCE_CODE) -+ -+ override fun getText() = ""Convert supertype to '$targetTypeStringShort'"" -+ override fun getFamilyName() = ""Convert extension function type to regular function type."" -+ -+ override fun invoke(project: Project, editor: Editor?, file: KtFile) { -+ val replaced = element.replaced(KtPsiFactory(project).createType(targetTypeStringLong)) -+ ShortenReferences.DEFAULT.process(replaced) -+ } -+ -+ private fun KotlinType.renderType(renderer: DescriptorRenderer) = buildString { -+ append('(') -+ arguments.dropLast(1).map { renderer.renderType(it.type) }.joinTo(this@buildString, "", "")","I'd add a test for more than one argument, and/or for type with type parameters -",Please add the license heade -435,"@@ -0,0 +1,69 @@ -+/* -+ * 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.inspections -+ -+import com.intellij.codeInspection.CleanupLocalInspectionTool -+import com.intellij.codeInspection.LocalInspectionToolSession -+import com.intellij.codeInspection.ProblemHighlightType -+import com.intellij.codeInspection.ProblemsHolder -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.* -+ -+class SuspiciousEqualsCombination : AbstractKotlinInspection(), CleanupLocalInspectionTool { -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession) = -+ object : KtVisitorVoid() { -+ override fun visitBinaryExpression(expression: KtBinaryExpression) { -+ if (expression.parent is KtBinaryExpression) return -+ val operands = expression.parseBinary() -+ val eqeq = operands.eqEqOperands.map { it.text } -+ val eqeqeq = operands.eqEqEqOperands.map { it.text } -+ if (eqeq.fold(false) { acc, it -> acc || eqeqeq.contains(it) }) {",This can actually be expressed as `eqeq.intersect(eqeqeq).isNotEmpty()`,Add a doxygen header -436,"@@ -0,0 +1,7 @@ -+// ""Replace initializer with getter"" ""true"" -+ -+fun String.foo() = ""bar"" -+ -+interface A { -+ val name = ""The quick brown fox jumps over the lazy dog"".foo()",Neither the existing intention action nor your suggested quickfix handle `var` properties correctly. They should create a stub for the setter with no implementation.,missing new line -437,"@@ -0,0 +1,7 @@ -+// ERROR: Unresolved reference: listOf -+fun a() { -+ val b = listOf(1,2,3,4,5)","You should use `// WITH_RUNTIME` directive in this and all other tests where you use standard library functions to avoid errors -",This is an example of a chan -438,"@@ -0,0 +1,7 @@ -+// IS_APPLICABLE: false -+fun foo() { -+ if (true) { -+ println(""test"") -+ println(""test2"") -+ } -+}","Typo in file name. -",I think you can drop the `is -439,"@@ -0,0 +1,7 @@ -+class KotlinClass(): JavaClass({}) {","Please make function literal here non-trivial. -",Can this be deleted? I don't -440,"@@ -0,0 +1,70 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.psi.JetFile -+import org.jetbrains.jet.lang.resolve.BindingContext -+import org.jetbrains.jet.lang.types.ErrorUtils -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+ -+public class MakeTypeImplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.implicit.in.lambda"", javaClass()) { -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ val params = element.getValueParameters() -+ val hasDeclaredParamsType = params.any { it.getTypeReference() != null } -+ val hasDeclaredReturnType = element.hasDeclaredReturnType() -+ val hasDeclaredReceiverType = element.getFunctionLiteral().getReceiverTypeRef() != null -+ if (hasDeclaredParamsType || hasDeclaredReturnType || hasDeclaredReceiverType) return true -+ -+ return false -+ } -+ -+ override fun applyTo(element: JetFunctionLiteralExpression, editor: Editor) { -+ val paramList = element.getFunctionLiteral().getValueParameterList()","Ditto (`element.getFunctionLiteral()` deserves to be extracted into a variable) -",Please annotate `@since` wit -441,"@@ -0,0 +1,70 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.psi.JetFile -+import org.jetbrains.jet.lang.resolve.BindingContext -+import org.jetbrains.jet.lang.types.ErrorUtils -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+ -+public class MakeTypeImplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.implicit.in.lambda"", javaClass()) { -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ val params = element.getValueParameters() -+ val hasDeclaredParamsType = params.any { it.getTypeReference() != null } -+ val hasDeclaredReturnType = element.hasDeclaredReturnType() -+ val hasDeclaredReceiverType = element.getFunctionLiteral().getReceiverTypeRef() != null -+ if (hasDeclaredParamsType || hasDeclaredReturnType || hasDeclaredReceiverType) return true -+ -+ return false -+ } -+ -+ override fun applyTo(element: JetFunctionLiteralExpression, editor: Editor) { -+ val paramList = element.getFunctionLiteral().getValueParameterList() -+ val params = paramList?.getParameters() -+ -+ if (element.hasDeclaredReturnType()) { -+ val childAfterParamList = paramList?.getNextSibling() -+ val arrow = element.getFunctionLiteral().getArrowNode()?.getPsi() -+ val childBeforeArrow = arrow?.getPrevSibling() -+ element.getFunctionLiteral().deleteChildRange(childAfterParamList, childBeforeArrow) -+ val whiteSpaceBeforeArrow = JetPsiFactory.createWhiteSpace(element.getProject()) -+ element.getFunctionLiteral().addBefore(whiteSpaceBeforeArrow, arrow) -+ } -+ -+ val hasDeclaredReceiverType = element.getFunctionLiteral().getReceiverTypeRef() != null -+ if (hasDeclaredReceiverType) { -+ val childAfterBrace = element.getFunctionLiteral().getOpenBraceNode().getPsi()?.getNextSibling() -+ val childBeforeParamList = paramList?.getPrevSibling() -+ element.getFunctionLiteral().deleteChildRange(childAfterBrace, childBeforeParamList) -+ } -+ -+ if (params != null && params!!.size() == 1 && params[0].getNameIdentifier() != null) {","There's a warning about a useless `!!` here -",Please rename your file to ` -442,"@@ -0,0 +1,70 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.psi.JetFile -+import org.jetbrains.jet.lang.resolve.BindingContext -+import org.jetbrains.jet.lang.types.ErrorUtils -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+ -+public class MakeTypeImplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.implicit.in.lambda"", javaClass()) { -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ val params = element.getValueParameters() -+ val hasDeclaredParamsType = params.any { it.getTypeReference() != null } -+ val hasDeclaredReturnType = element.hasDeclaredReturnType() -+ val hasDeclaredReceiverType = element.getFunctionLiteral().getReceiverTypeRef() != null -+ if (hasDeclaredParamsType || hasDeclaredReturnType || hasDeclaredReceiverType) return true -+ -+ return false -+ } -+ -+ override fun applyTo(element: JetFunctionLiteralExpression, editor: Editor) { -+ val paramList = element.getFunctionLiteral().getValueParameterList() -+ val params = paramList?.getParameters() -+ -+ if (element.hasDeclaredReturnType()) { -+ val childAfterParamList = paramList?.getNextSibling() -+ val arrow = element.getFunctionLiteral().getArrowNode()?.getPsi() -+ val childBeforeArrow = arrow?.getPrevSibling() -+ element.getFunctionLiteral().deleteChildRange(childAfterParamList, childBeforeArrow) -+ val whiteSpaceBeforeArrow = JetPsiFactory.createWhiteSpace(element.getProject()) -+ element.getFunctionLiteral().addBefore(whiteSpaceBeforeArrow, arrow) -+ } -+ -+ val hasDeclaredReceiverType = element.getFunctionLiteral().getReceiverTypeRef() != null -+ if (hasDeclaredReceiverType) { -+ val childAfterBrace = element.getFunctionLiteral().getOpenBraceNode().getPsi()?.getNextSibling() -+ val childBeforeParamList = paramList?.getPrevSibling() -+ element.getFunctionLiteral().deleteChildRange(childAfterBrace, childBeforeParamList) -+ } -+ -+ if (params != null && params!!.size() == 1 && params[0].getNameIdentifier() != null) { -+ paramList!!.replace(params[0].getNameIdentifier()!!) -+ } -+ else { -+ params?.forEach{","Missing a space before `{` -",Please rename your file to ` -443,"@@ -0,0 +1,70 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetForExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression -+import org.jetbrains.jet.lang.psi.JetPsiUtil -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import com.intellij.find.FindManager -+import com.intellij.find.impl.FindManagerImpl -+import com.intellij.usageView.UsageInfo -+import org.jetbrains.jet.plugin.findUsages.KotlinPropertyFindUsagesOptions -+import org.jetbrains.jet.lang.resolve.BindingContext -+import org.jetbrains.jet.lang.psi.JetCallExpression -+import org.jetbrains.jet.lang.resolve.DescriptorUtils -+ -+public class RemoveForLoopIndicesIntention : JetSelfTargetingIntention( -+ ""remove.for.loop.indices"", javaClass()) { -+ override fun applyTo(element: JetForExpression, editor: Editor) { -+ val parameter = element.getMultiParameter()!! -+ val range = element.getLoopRange() as JetDotQualifiedExpression -+ val parameters = parameter.getEntries() -+ if (parameters.size() == 2) { -+ parameter.replace(parameters[1]) -+ } -+ else { -+ JetPsiUtil.deleteElementWithDelimiters(parameters[0]) -+ } -+ -+ range.replace(range.getReceiverExpression()) -+ } -+ -+ override fun isApplicableTo(element: JetForExpression): Boolean { -+ val multiParameter = element.getMultiParameter() ?: return false -+ val range = element.getLoopRange() as? JetDotQualifiedExpression ?: return false -+ val selector = range.getSelectorExpression() as? JetCallExpression ?: return false -+ -+ if (!selector.textMatches(""withIndices()"")) return false","This is a nice optimization, but I'd check if `selector` is a call expression with a callee named `withIndices`. People can have different weird code style settings, for example ones requiring spaces before parentheses; it would be a pity if this intention wouldn't work in that case (`withIndices ()`) -",Please rename the file to `R -444,"@@ -0,0 +1,70 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetForExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression -+import org.jetbrains.jet.lang.psi.JetPsiUtil -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import com.intellij.find.FindManager -+import com.intellij.find.impl.FindManagerImpl -+import com.intellij.usageView.UsageInfo -+import org.jetbrains.jet.plugin.findUsages.KotlinPropertyFindUsagesOptions -+import org.jetbrains.jet.lang.resolve.BindingContext -+import org.jetbrains.jet.lang.psi.JetCallExpression -+import org.jetbrains.jet.lang.resolve.DescriptorUtils -+ -+public class RemoveForLoopIndicesIntention : JetSelfTargetingIntention( -+ ""remove.for.loop.indices"", javaClass()) { -+ override fun applyTo(element: JetForExpression, editor: Editor) { -+ val parameter = element.getMultiParameter()!! -+ val range = element.getLoopRange() as JetDotQualifiedExpression -+ val parameters = parameter.getEntries() -+ if (parameters.size() == 2) { -+ parameter.replace(parameters[1]) -+ } -+ else { -+ JetPsiUtil.deleteElementWithDelimiters(parameters[0]) -+ } -+ -+ range.replace(range.getReceiverExpression()) -+ } -+ -+ override fun isApplicableTo(element: JetForExpression): Boolean { -+ val multiParameter = element.getMultiParameter() ?: return false -+ val range = element.getLoopRange() as? JetDotQualifiedExpression ?: return false -+ val selector = range.getSelectorExpression() as? JetCallExpression ?: return false -+ -+ if (!selector.textMatches(""withIndices()"")) return false -+ -+ val bindingContext = AnalyzerFacadeWithCache.getContextForElement(element) -+ val callResolution = bindingContext[BindingContext.RESOLVED_CALL, selector.getCalleeExpression()!!] ?: return false -+ val fqName = DescriptorUtils.getFqNameSafe(callResolution.getCandidateDescriptor())","Ditto (`getFqNameSafe`) -",Please rename the file to `R -445,"@@ -0,0 +1,70 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetForExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression -+import org.jetbrains.jet.lang.psi.JetPsiUtil -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import com.intellij.find.FindManager -+import com.intellij.find.impl.FindManagerImpl -+import com.intellij.usageView.UsageInfo -+import org.jetbrains.jet.plugin.findUsages.KotlinPropertyFindUsagesOptions -+import org.jetbrains.jet.lang.resolve.BindingContext -+import org.jetbrains.jet.lang.psi.JetCallExpression -+import org.jetbrains.jet.lang.resolve.DescriptorUtils -+ -+public class RemoveForLoopIndicesIntention : JetSelfTargetingIntention( -+ ""remove.for.loop.indices"", javaClass()) { -+ override fun applyTo(element: JetForExpression, editor: Editor) { -+ val parameter = element.getMultiParameter()!! -+ val range = element.getLoopRange() as JetDotQualifiedExpression -+ val parameters = parameter.getEntries() -+ if (parameters.size() == 2) { -+ parameter.replace(parameters[1]) -+ } -+ else { -+ JetPsiUtil.deleteElementWithDelimiters(parameters[0]) -+ } -+ -+ range.replace(range.getReceiverExpression()) -+ } -+ -+ override fun isApplicableTo(element: JetForExpression): Boolean { -+ val multiParameter = element.getMultiParameter() ?: return false -+ val range = element.getLoopRange() as? JetDotQualifiedExpression ?: return false -+ val selector = range.getSelectorExpression() as? JetCallExpression ?: return false -+ -+ if (!selector.textMatches(""withIndices()"")) return false -+ -+ val bindingContext = AnalyzerFacadeWithCache.getContextForElement(element) -+ val callResolution = bindingContext[BindingContext.RESOLVED_CALL, selector.getCalleeExpression()!!] ?: return false -+ val fqName = DescriptorUtils.getFqNameSafe(callResolution.getCandidateDescriptor()) -+ if (fqName.toString() != ""kotlin.withIndices"") return false -+ -+ val indexVar = multiParameter.getEntries()[0]","You should check if there are any entries. Otherwise your intention fails with the exception on the following test case: - -``` kotlin - for (() in listOf(1).withIndices()) { - } -``` -",Please rename the file to `R -446,"@@ -0,0 +1,70 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetForExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression -+import org.jetbrains.jet.lang.psi.JetPsiUtil -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import com.intellij.find.FindManager -+import com.intellij.find.impl.FindManagerImpl -+import com.intellij.usageView.UsageInfo -+import org.jetbrains.jet.plugin.findUsages.KotlinPropertyFindUsagesOptions -+import org.jetbrains.jet.lang.resolve.BindingContext -+import org.jetbrains.jet.lang.psi.JetCallExpression -+import org.jetbrains.jet.lang.resolve.DescriptorUtils -+ -+public class RemoveForLoopIndicesIntention : JetSelfTargetingIntention( -+ ""remove.for.loop.indices"", javaClass()) { -+ override fun applyTo(element: JetForExpression, editor: Editor) { -+ val parameter = element.getMultiParameter()!! -+ val range = element.getLoopRange() as JetDotQualifiedExpression -+ val parameters = parameter.getEntries() -+ if (parameters.size() == 2) { -+ parameter.replace(parameters[1]) -+ } -+ else { -+ JetPsiUtil.deleteElementWithDelimiters(parameters[0]) -+ } -+ -+ range.replace(range.getReceiverExpression()) -+ } -+ -+ override fun isApplicableTo(element: JetForExpression): Boolean { -+ val multiParameter = element.getMultiParameter() ?: return false -+ val range = element.getLoopRange() as? JetDotQualifiedExpression ?: return false -+ val selector = range.getSelectorExpression() as? JetCallExpression ?: return false -+ -+ if (!selector.textMatches(""withIndices()"")) return false -+ -+ val bindingContext = AnalyzerFacadeWithCache.getContextForElement(element) -+ val callResolution = bindingContext[BindingContext.RESOLVED_CALL, selector.getCalleeExpression()!!] ?: return false -+ val fqName = DescriptorUtils.getFqNameSafe(callResolution.getCandidateDescriptor()) -+ if (fqName.toString() != ""kotlin.withIndices"") return false -+ -+ val indexVar = multiParameter.getEntries()[0] -+ val findManager = FindManager.getInstance(element.getProject()) as FindManagerImpl -+ val findHandler = findManager.getFindUsagesManager().getFindUsagesHandler(indexVar, false) ?: return false -+ val options = KotlinPropertyFindUsagesOptions(element.getProject()) -+ var usageCount = 0","As I mentioned earlier, this should be a boolean flag, rather than an integer variable -",Please rename the file to `R -447,"@@ -0,0 +1,70 @@ -+/* -+ * 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.wrappers.symbols -+ -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.load.java.structure.JavaAnnotation -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.java.structure.JavaMember -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.Name -+import javax.lang.model.element.Element -+import javax.lang.model.element.ExecutableElement -+import javax.lang.model.element.TypeElement -+ -+abstract class JavacMember(element: T, -+ javac: Javac) : JavacElement(element, javac), JavaMember { -+ override val containingClass: JavaClass -+ get() = JavacClass((element.enclosingElement as TypeElement), javac) -+ -+ override val annotations: Collection -+ get() = element.annotationMirrors -+ .map { JavacAnnotation(it, javac) } -+ -+ override fun findAnnotation(fqName: FqName): JavaAnnotation? = element.annotationMirrors -+ .filter { it.toString() == fqName.asString() } -+ .firstOrNull() -+ ?.let { JavacAnnotation(it, javac) } -+ -+ override val visibility -+ get() = element.getVisibility() -+ -+ override val name -+ get() = Name.identifier(element.simpleName.toString()) -+ -+ override val isDeprecatedInJavaDoc = false","Again, why false?",Could you please add a doc s -448,"@@ -0,0 +1,70 @@ -+/* -+ * 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.wrappers.symbols -+ -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.load.java.structure.JavaAnnotation -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.java.structure.JavaMember -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.Name -+import javax.lang.model.element.Element -+import javax.lang.model.element.ExecutableElement -+import javax.lang.model.element.TypeElement -+ -+abstract class JavacMember(element: T, -+ javac: Javac) : JavacElement(element, javac), JavaMember { -+ override val containingClass: JavaClass -+ get() = JavacClass((element.enclosingElement as TypeElement), javac) -+ -+ override val annotations: Collection -+ get() = element.annotationMirrors -+ .map { JavacAnnotation(it, javac) } -+ -+ override fun findAnnotation(fqName: FqName): JavaAnnotation? = element.annotationMirrors -+ .filter { it.toString() == fqName.asString() } -+ .firstOrNull() -+ ?.let { JavacAnnotation(it, javac) } -+ -+ override val visibility -+ get() = element.getVisibility() -+ -+ override val name -+ get() = Name.identifier(element.simpleName.toString()) -+ -+ override val isDeprecatedInJavaDoc = false -+ -+ override val isAbstract -+ get() = element.isAbstract -+ -+ override val isStatic -+ get() = element.isStatic -+ -+ override val isFinal -+ get() = element.isFinal -+ -+} -+ -+fun ExecutableElement.valueParameters(javac: Javac) = let {",May be create separate file like `JavacElementUtils.kt` for such things.,Could you please add a doc string about what this is? -449,"@@ -0,0 +1,70 @@ -+/* -+ * 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.wrappers.symbols -+ -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.load.java.structure.JavaAnnotation -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.java.structure.JavaMember -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.Name -+import javax.lang.model.element.Element -+import javax.lang.model.element.ExecutableElement -+import javax.lang.model.element.TypeElement -+ -+abstract class JavacMember(element: T, -+ javac: Javac) : JavacElement(element, javac), JavaMember { -+ override val containingClass: JavaClass -+ get() = JavacClass((element.enclosingElement as TypeElement), javac) -+ -+ override val annotations: Collection -+ get() = element.annotationMirrors -+ .map { JavacAnnotation(it, javac) } -+ -+ override fun findAnnotation(fqName: FqName): JavaAnnotation? = element.annotationMirrors -+ .filter { it.toString() == fqName.asString() } -+ .firstOrNull() -+ ?.let { JavacAnnotation(it, javac) } -+ -+ override val visibility -+ get() = element.getVisibility() -+ -+ override val name -+ get() = Name.identifier(element.simpleName.toString()) -+ -+ override val isDeprecatedInJavaDoc = false -+ -+ override val isAbstract -+ get() = element.isAbstract -+ -+ override val isStatic -+ get() = element.isStatic -+ -+ override val isFinal -+ get() = element.isFinal -+ -+} -+ -+fun ExecutableElement.valueParameters(javac: Javac) = let { -+ val parameterTypesCount = parameters.size -+ -+ parameters.mapIndexed { index, it -> -+ val isLastParameter = index == parameterTypesCount - 1 -+ val parameterName = it.simpleName.toString() -+ JavacValueParameter(it, parameterName, if (isLastParameter) isVarArgs else false, javac)",`isLastParameter && isVarArgs`,Could you please add a doc string about what this is? -450,"@@ -0,0 +1,70 @@ -+/* -+ * 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.wrappers.trees -+ -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.code.Flags -+import com.sun.tools.javac.tree.JCTree -+import org.jetbrains.kotlin.descriptors.Visibilities -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.java.structure.JavaField -+import org.jetbrains.kotlin.name.Name -+ -+class TreeBasedField(tree: T, -+ treePath: TreePath, -+ containingClass: JavaClass, -+ javac: JavacWrapper) : TreeBasedMember(tree, treePath, containingClass, javac), JavaField { -+ -+ override val name -+ get() = Name.identifier(tree.name.toString()) -+ -+ override val isAbstract -+ get() = tree.modifiers.isAbstract -+ -+ override val isStatic -+ get() = containingClass.isInterface || tree.modifiers.isStatic",Please ensure there's a test on static fields in annotations,I don't think this is the right place for this. I'd r -451,"@@ -0,0 +1,71 @@ -+/* -+ * 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.idea.inspections -+ -+import com.intellij.codeInspection.* -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiElementVisitor -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.idea.references.mainReference -+import org.jetbrains.kotlin.psi.* -+import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe -+import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode -+ -+class UnnecessaryJavaUsageInspection : AbstractKotlinInspection(), CleanupLocalInspectionTool { -+ -+ val patterns = mapOf( -+ ""java.io.PrintStream.println"" to ""println($0)"", -+ ""java.io.PrintStream.print"" to ""print($0)"", -+ ""java.util.Collections.sort"" to ""$0.sort()"" -+ ) -+ -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor { -+ return object : KtVisitorVoid() { -+ override fun visitQualifiedExpression(expression: KtQualifiedExpression) { -+ super.visitQualifiedExpression(expression) -+ -+ val selectorExpression = expression.selectorExpression ?: return -+ if (selectorExpression !is KtCallExpression) return -+ val value = selectorExpression.valueArguments.singleOrNull() ?: return -+ -+ val calleeExpression = selectorExpression.calleeExpression as KtSimpleNameExpression -+ val bindingContext = calleeExpression.analyze(BodyResolveMode.PARTIAL) -+ val target = calleeExpression.mainReference.resolveToDescriptors(bindingContext).singleOrNull() ?: return -+ val pattern = target.fqNameSafe.asString()","I tryed use `importableFqName` but it's was giving null for me. I am a bit confused with this. -",Remove the wildcard import. -452,"@@ -0,0 +1,71 @@ -+/* -+ * 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.idea.inspections -+ -+import com.intellij.codeInspection.ProblemHighlightType -+import com.intellij.codeInspection.ProblemsHolder -+import com.intellij.psi.PsiElementVisitor -+import org.jetbrains.kotlin.builtins.KotlinBuiltIns -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.idea.intentions.branchedTransformations.evaluatesTo -+import org.jetbrains.kotlin.idea.refactoring.getLineNumber -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.KtBinaryExpression -+import org.jetbrains.kotlin.psi.KtBlockExpression -+import org.jetbrains.kotlin.psi.KtLambdaExpression -+import org.jetbrains.kotlin.psi.KtVisitorVoid -+import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType -+import org.jetbrains.kotlin.psi.psiUtil.lastBlockStatementOrThis -+import org.jetbrains.kotlin.resolve.calls.callUtil.getType -+ -+class UnusedEqualsInspection : AbstractKotlinInspection() { -+ -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { -+ return object : KtVisitorVoid() { -+ override fun visitBinaryExpression(expression: KtBinaryExpression) { -+ super.visitBinaryExpression(expression) -+ if (expression.operationToken != KtTokens.EQEQ) return -+ val parent = expression.parent as? KtBlockExpression ?: return -+ val lastBlockStatement = parent.lastBlockStatementOrThis() -+ when { -+ expression.evaluatesTo(lastBlockStatement) && expression.getLineNumber() == lastBlockStatement.getLineNumber() -> -+ expression.getStrictParentOfType()?.visitLambdaExpression(holder, expression) ?: holder.registerUnusedEqualsProblem(expression)",All of this looks too nasty and unsafe. Please use `KtExpression.isUsedAsExpression` from `BindingContextUtils.kt` to determine whether your `equals` result is used or not.,Is this needed? -453,"@@ -0,0 +1,71 @@ -+/* -+ * 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.idea.inspections -+ -+import com.intellij.codeInspection.ProblemHighlightType -+import com.intellij.codeInspection.ProblemsHolder -+import com.intellij.psi.PsiElementVisitor -+import org.jetbrains.kotlin.builtins.KotlinBuiltIns -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.idea.intentions.branchedTransformations.evaluatesTo -+import org.jetbrains.kotlin.idea.refactoring.getLineNumber -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.KtBinaryExpression -+import org.jetbrains.kotlin.psi.KtBlockExpression -+import org.jetbrains.kotlin.psi.KtLambdaExpression -+import org.jetbrains.kotlin.psi.KtVisitorVoid -+import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType -+import org.jetbrains.kotlin.psi.psiUtil.lastBlockStatementOrThis -+import org.jetbrains.kotlin.resolve.calls.callUtil.getType -+ -+class UnusedEqualsInspection : AbstractKotlinInspection() { -+ -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { -+ return object : KtVisitorVoid() { -+ override fun visitBinaryExpression(expression: KtBinaryExpression) { -+ super.visitBinaryExpression(expression) -+ if (expression.operationToken != KtTokens.EQEQ) return -+ val parent = expression.parent as? KtBlockExpression ?: return -+ val lastBlockStatement = parent.lastBlockStatementOrThis() -+ when { -+ expression.evaluatesTo(lastBlockStatement) && expression.getLineNumber() == lastBlockStatement.getLineNumber() -> -+ expression.getStrictParentOfType()?.visitLambdaExpression(holder, expression) ?: holder.registerUnusedEqualsProblem(expression) -+ else -> holder.registerUnusedEqualsProblem(expression) -+ } -+ } -+ -+ private fun KtLambdaExpression.visitLambdaExpression(holder: ProblemsHolder, expression: KtBinaryExpression) { -+ val lambdaTypeArguments = getType(analyze())?.arguments ?: return -+ if (lambdaTypeArguments.size != 1) return -+ when { -+ KotlinBuiltIns.isBoolean(lambdaTypeArguments[0].type) -> { -+ val lastBlockStatementOrThis = bodyExpression?.lastBlockStatementOrThis() ?: return -+ if (!expression.evaluatesTo(lastBlockStatementOrThis)) holder.registerUnusedEqualsProblem(expression) -+ } -+ else -> holder.registerUnusedEqualsProblem(expression) -+ } -+ } -+ -+ private fun ProblemsHolder.registerUnusedEqualsProblem(expression: KtBinaryExpression) { -+ registerProblem(expression,",I'd say it's better to provide also text range here and highlight `==` only as unused.,Is this needed? -454,"@@ -0,0 +1,71 @@ -+/* -+ * 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.idea.inspections -+ -+import com.intellij.codeInspection.ProblemHighlightType -+import com.intellij.codeInspection.ProblemsHolder -+import com.intellij.psi.PsiElementVisitor -+import org.jetbrains.kotlin.builtins.KotlinBuiltIns -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.idea.intentions.branchedTransformations.evaluatesTo -+import org.jetbrains.kotlin.idea.refactoring.getLineNumber -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.KtBinaryExpression -+import org.jetbrains.kotlin.psi.KtBlockExpression -+import org.jetbrains.kotlin.psi.KtLambdaExpression -+import org.jetbrains.kotlin.psi.KtVisitorVoid -+import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType -+import org.jetbrains.kotlin.psi.psiUtil.lastBlockStatementOrThis -+import org.jetbrains.kotlin.resolve.calls.callUtil.getType -+ -+class UnusedEqualsInspection : AbstractKotlinInspection() { -+ -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { -+ return object : KtVisitorVoid() { -+ override fun visitBinaryExpression(expression: KtBinaryExpression) { -+ super.visitBinaryExpression(expression) -+ if (expression.operationToken != KtTokens.EQEQ) return -+ val parent = expression.parent as? KtBlockExpression ?: return -+ val lastBlockStatement = parent.lastBlockStatementOrThis() -+ when { -+ expression.evaluatesTo(lastBlockStatement) && expression.getLineNumber() == lastBlockStatement.getLineNumber() -> -+ expression.getStrictParentOfType()?.visitLambdaExpression(holder, expression) ?: holder.registerUnusedEqualsProblem(expression) -+ else -> holder.registerUnusedEqualsProblem(expression) -+ } -+ } -+ -+ private fun KtLambdaExpression.visitLambdaExpression(holder: ProblemsHolder, expression: KtBinaryExpression) { -+ val lambdaTypeArguments = getType(analyze())?.arguments ?: return -+ if (lambdaTypeArguments.size != 1) return -+ when { -+ KotlinBuiltIns.isBoolean(lambdaTypeArguments[0].type) -> { -+ val lastBlockStatementOrThis = bodyExpression?.lastBlockStatementOrThis() ?: return -+ if (!expression.evaluatesTo(lastBlockStatementOrThis)) holder.registerUnusedEqualsProblem(expression) -+ } -+ else -> holder.registerUnusedEqualsProblem(expression) -+ } -+ } -+ -+ private fun ProblemsHolder.registerUnusedEqualsProblem(expression: KtBinaryExpression) { -+ registerProblem(expression, -+ ""Unused equals expression"", -+ ProblemHighlightType.LIKE_UNUSED_SYMBOL)","Should we provide some quick fix? I'd say that in simple cases with local variables or constants binary expression could be completely deleted, but in cases like `foo() == bar()` we should get - -``` -foo() -bar() -``` - -instead",Is this needed? -455,"@@ -0,0 +1,72 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.lang.ASTNode; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.project.Project; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.impl.PsiImplUtil; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.psi.JetDelegationSpecifier; -+import org.jetbrains.jet.lexer.JetTokens; -+import org.jetbrains.jet.plugin.JetBundle; -+ -+public class RemoveSupertypeFix extends JetIntentionAction { -+ private final JetDelegationSpecifier superClass; -+ -+ public RemoveSupertypeFix(@NotNull JetDelegationSpecifier superClass) { -+ super(superClass); -+ this.superClass = superClass; -+ } -+ -+ @NotNull -+ @Override -+ public String getText() { -+ return JetBundle.message(""remove.supertype"", superClass.getText()); -+ } -+ -+ @NotNull -+ @Override -+ public String getFamilyName() { -+ return JetBundle.message(""remove.supertype.family""); -+ } -+ -+ @Override -+ public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { -+ // Find the preceding comma and delete it as well. -+ // We must ignore whitespaces and comments when looking for the comma. -+ ASTNode prev = PsiImplUtil.skipWhitespaceAndCommentsBack(superClass.getPrevSibling().getNode());","Possible NullPointerException if superClass has no previous sibling??? But will it ever have no previous sibling? -",This file needs to be renamed (as well as the class) -456,"@@ -0,0 +1,73 @@ -+/* -+ * Copyright 2010-2012 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.project.Project; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.impl.source.tree.LeafPsiElement; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.jet.lang.psi.JetFile; -+import org.jetbrains.jet.lexer.JetTokens; -+import org.jetbrains.jet.plugin.JetBundle; -+ -+/** -+ * @author slukjanov aka Frostman -+ */ -+public class UnnecessaryNotNullAssertionFix implements IntentionAction {","I understand why you decided to create another class for that task but still think that there should be another logic in UnnecessaryNotNullAssertionFix and ReplaceCallFix. I propose ReplaceCallFix could also be used for replacing !!. call to something else as it can be used for introducing such calls now. And this class can could be responsible only for introducing and removing a!! postfix operation. -What do you think? -",I am not sure if this annotation is required -457,"@@ -0,0 +1,73 @@ -+/* -+ * Copyright 2010-2012 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.project.Project; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.impl.source.tree.LeafPsiElement; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.jet.lang.psi.JetFile; -+import org.jetbrains.jet.lexer.JetTokens; -+import org.jetbrains.jet.plugin.JetBundle; -+ -+/** -+ * @author slukjanov aka Frostman -+ */ -+public class UnnecessaryNotNullAssertionFix implements IntentionAction { -+ @NotNull -+ @Override -+ public String getText() { -+ return JetBundle.message(""remove.unnecessary.non.null.assertion""); -+ } -+ -+ @NotNull -+ @Override -+ public String getFamilyName() { -+ return getText(); -+ } -+ -+ @Override -+ public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { -+ return file instanceof JetFile && getExclExclElement(editor, file) != null; -+ } -+ -+ @Override -+ public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { -+ final PsiElement exclExcl = getExclExclElement(editor, file); -+ assert exclExcl != null; -+ -+ exclExcl.delete();","There's a problem with removing PSI element this way. It looks like IDEA can't handle the region for update correctly. I'm going to debug and fix it. It can be reproduced with this chunk of code. After applying the fix idea shows errors in internal mode (with -Didea.is.internal=true in javac string). -fun test(value : String) : String { - return value!! -} -",This file needs to be renamed to 'UnnecessaryNullAsse -458,"@@ -0,0 +1,74 @@ -+/* -+ * 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.wrappers.trees -+ -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.tree.JCTree -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.javac.MockKotlinClassifier -+import org.jetbrains.kotlin.load.java.structure.* -+ -+sealed class ClassifierType(tree: T, -+ treePath: TreePath, -+ javac: JavacWrapper) : JCType(tree, treePath, javac), JavaClassifierType { -+ -+ override val classifier by lazy { treePath.resolve(javac) } -+ -+ override val canonicalText -+ get() = (classifier as? JavaClass)?.fqName?.asString() ?: treePath.leaf.toString() -+ -+ override val presentableText -+ get() = canonicalText -+ -+ private val typeParameter -+ get() = treePath.filter { it is JCTree.JCClassDecl || it is JCTree.JCMethodDecl } -+ .flatMap { -+ when (it) { -+ is JCTree.JCClassDecl -> it.typarams -+ is JCTree.JCMethodDecl -> it.typarams -+ else -> throw UnsupportedOperationException(""${it.kind} cannot have a type parameter"") -+ } -+ } -+ .find { it.toString().substringBefore("" "") == treePath.leaf.toString() } -+ -+} -+ -+class JCClassifierType(tree: T, -+ treePath: TreePath, -+ javac: JavacWrapper) : ClassifierType(tree, treePath, javac) { -+ -+ override val typeArguments: List -+ get() = emptyList() -+ -+ override val isRaw -+ get() = (classifier as? MockKotlinClassifier)?.hasTypeParameters -+ ?: (classifier as? JavaClass)?.typeParameters?.isNotEmpty() -+ ?: false -+ -+} -+ -+class JCClassifierTypeWithTypeArgument(tree: T,","May be it's not the best name. For me it's more or less obvious, that `JCClassifierTypeWithTypeArgument` is an inheritor of `JCClassifierType`, but in fact it's not so. I'd change one of these two names.",This feels like an unnecessary abstraction. I would j -459,"@@ -0,0 +1,75 @@ -+/* -+ * 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.wrappers.trees -+ -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.tree.JCTree -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.javac.MockKotlinClassifier -+import org.jetbrains.kotlin.load.java.structure.* -+ -+sealed class TreeBasedClassifierType(tree: T, -+ treePath: TreePath, -+ javac: JavacWrapper) : TreeBasedType(tree, treePath, javac), JavaClassifierType { -+ -+ override val classifier -+ get() = javac.resolve(treePath) -+ -+ override val classifierQualifiedName -+ get() = (classifier as? JavaClass)?.fqName?.asString() ?: treePath.leaf.toString() -+ -+ override val presentableText -+ get() = classifierQualifiedName -+ -+ private val typeParameter -+ get() = treePath.filter { it is JCTree.JCClassDecl || it is JCTree.JCMethodDecl } -+ .flatMap { -+ when (it) { -+ is JCTree.JCClassDecl -> it.typarams -+ is JCTree.JCMethodDecl -> it.typarams -+ else -> throw UnsupportedOperationException(""${it.kind} cannot have a type parameter"")","You can remove `.filter { ... }` above, and use `else -> emptyList()` here",This feels odd... I would expect this to return a `Tr -460,"@@ -0,0 +1,75 @@ -+/* -+ * 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.wrappers.trees -+ -+import com.sun.source.util.TreePath -+import com.sun.tools.javac.tree.JCTree -+import org.jetbrains.kotlin.javac.JavacWrapper -+import org.jetbrains.kotlin.javac.MockKotlinClassifier -+import org.jetbrains.kotlin.load.java.structure.* -+ -+sealed class TreeBasedClassifierType(tree: T, -+ treePath: TreePath, -+ javac: JavacWrapper) : TreeBasedType(tree, treePath, javac), JavaClassifierType { -+ -+ override val classifier -+ get() = javac.resolve(treePath) -+ -+ override val classifierQualifiedName -+ get() = (classifier as? JavaClass)?.fqName?.asString() ?: treePath.leaf.toString() -+ -+ override val presentableText -+ get() = classifierQualifiedName -+ -+ private val typeParameter -+ get() = treePath.filter { it is JCTree.JCClassDecl || it is JCTree.JCMethodDecl } -+ .flatMap { -+ when (it) { -+ is JCTree.JCClassDecl -> it.typarams -+ is JCTree.JCMethodDecl -> it.typarams -+ else -> throw UnsupportedOperationException(""${it.kind} cannot have a type parameter"") -+ } -+ } -+ .find { it.toString().substringBefore("" "") == treePath.leaf.toString() } -+ -+} -+ -+class TreeBasedClassifierTypeWithoutTypeArgument(tree: T,",Consider renaming to `TreeBasedNonGenericClassifierType` and `TreeBasedGenericClassifierType`,"I don't think this is the right place for this, since" -461,"@@ -0,0 +1,77 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.plugin.JetBundle -+import com.intellij.openapi.project.Project -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetFile -+import com.intellij.psi.PsiFile -+import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression -+import org.jetbrains.jet.plugin.intentions.JetSelfTargetingIntention -+import org.jetbrains.jet.lang.psi.JetCallExpression -+import org.jetbrains.jet.lang.psi.JetExpression -+import com.intellij.psi.PsiElement -+import com.intellij.refactoring.changeSignature.PsiCallReference -+import org.jetbrains.jet.lang.psi.JetArrayAccessExpression -+import com.intellij.psi.PsiArrayAccessExpression -+import com.intellij.psi.impl.source.tree.java.PsiArrayAccessExpressionImpl -+import org.jetbrains.jet.lang.psi.JetVisitorVoid -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.plugin.quickfix.JetIntentionAction -+ -+public class GetCallReplacementIntention : JetSelfTargetingIntention(""get.call.replacement"", javaClass()) { -+ var project : Project? = null -+ -+ override fun invoke(project: Project, editor: Editor, file: PsiFile) { -+ this.project = project -+ super.invoke(project, editor, file) -+ } -+ -+ override fun isApplicableTo(element: JetDotQualifiedExpression): Boolean { -+ val selector : JetCallExpression? = element.getSelectorExpression() as? JetCallExpression","Code formatting is inconsistent. -",Add file header -462,"@@ -0,0 +1,77 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.plugin.JetBundle -+import com.intellij.openapi.project.Project -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetFile -+import com.intellij.psi.PsiFile -+import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression -+import org.jetbrains.jet.plugin.intentions.JetSelfTargetingIntention -+import org.jetbrains.jet.lang.psi.JetCallExpression -+import org.jetbrains.jet.lang.psi.JetExpression -+import com.intellij.psi.PsiElement -+import com.intellij.refactoring.changeSignature.PsiCallReference -+import org.jetbrains.jet.lang.psi.JetArrayAccessExpression -+import com.intellij.psi.PsiArrayAccessExpression -+import com.intellij.psi.impl.source.tree.java.PsiArrayAccessExpressionImpl -+import org.jetbrains.jet.lang.psi.JetVisitorVoid -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.plugin.quickfix.JetIntentionAction -+ -+public class GetCallReplacementIntention : JetSelfTargetingIntention(""get.call.replacement"", javaClass()) { -+ var project : Project? = null -+ -+ override fun invoke(project: Project, editor: Editor, file: PsiFile) { -+ this.project = project -+ super.invoke(project, editor, file) -+ } -+ -+ override fun isApplicableTo(element: JetDotQualifiedExpression): Boolean { -+ val selector : JetCallExpression? = element.getSelectorExpression() as? JetCallExpression -+ val callee : JetExpression? = selector?.getCalleeExpression() -+ -+ return callee != null && callee.textMatches(""get"") -+ } -+ -+ override fun applyTo(element: JetDotQualifiedExpression, editor: Editor) { -+ val selector : JetCallExpression? = element.getSelectorExpression() as? JetCallExpression -+ val callee : JetExpression? = selector?.getCalleeExpression() -+ val arguments = selector?.getValueArgumentList() -+ assert(arguments != null) -+ val argumentsText = arguments!!.getText() -+ assert(argumentsText != null) -+ val receiver : JetExpression = element.getReceiverExpression() -+ var arrayArgumentsText = """" -+ -+ for (i in 0..argumentsText!!.length() - 1) { -+ when (i) { -+ 0 -> arrayArgumentsText += ""["" -+ argumentsText.length() - 1 -> arrayArgumentsText += ""]"" -+ else -> arrayArgumentsText += argumentsText[i] -+ } -+ } -+ -+ if (project == null) {","No need to save project to local property: it can be obtained from `element` -",Add file header -463,"@@ -0,0 +1,78 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetCallExpression -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.resolve.BindingContext -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetPrefixExpression -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import org.jetbrains.jet.lang.psi.JetBinaryExpression -+import org.jetbrains.jet.plugin.codeInsight.ShortenReferences -+import org.jetbrains.jet.lang.psi.JetCallableReferenceExpression -+ -+public class ConvertAssertToIfWithThrowIntention : JetSelfTargetingIntention( -+ ""convert.assert.to.if.with.throw"", javaClass()) { -+ -+ override fun isApplicableTo(element: JetCallExpression): Boolean { -+ if (element.getCalleeExpression()?.getText() != ""assert"") return false -+ val arguments = element.getValueArguments().size -+ val lambdas = element.getFunctionLiteralArguments().size -+ if (!(arguments == 1 && (lambdas == 1 || lambdas == 0)) && arguments != 2) return false -+ val context = AnalyzerFacadeWithCache.getContextForElement(element) -+ val resolvedCall = context[BindingContext.RESOLVED_CALL, element.getCalleeExpression()] -+ return resolvedCall?.getResultingDescriptor()?.getContainingDeclaration()?.getName().toString() == ""kotlin"" -+ } -+ -+ override fun applyTo(element: JetCallExpression, editor: Editor) { -+ val args = element.getValueArguments() -+ val condition = args[0]?.getArgumentExpression() -+ val lambdas = element.getFunctionLiteralArguments() -+ -+ val messageExpr = if (args.size == 2) { -+ args[1]?.getArgumentExpression() -+ } else if (!lambdas.isEmpty()) { -+ element.getFunctionLiteralArguments()[0] -+ } else { -+ JetPsiFactory.createExpression(element.getProject(), ""\""Assertion failed\"""")","not sure on this line, basically i just want that string, but later i use messageExpr as an expression, so i was debating whether to create an expression with the string and then have easier handling at line 62, or i thought maybe setting messageExpr to be Any and then just assigning the string and adding a special check for String in line 62, probably more efficient but less readable. -Ended up going for readability -",Please annotate `@since` rather than `@since`. -464,"@@ -0,0 +1,78 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetBinaryExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lexer.JetTokens -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.plugin.references.JetSimpleNameReference -+import org.jetbrains.jet.lang.psi.JetSimpleNameExpression -+ -+public class ReplaceWithOperatorAssignIntention : JetSelfTargetingIntention(""replace.with.operator.assign.intention"", javaClass()) { -+ override fun isApplicableTo(element: JetBinaryExpression): Boolean { -+ fun checkForNullSafety(element : JetBinaryExpression): Boolean { -+ val rightExpression = element.getRight() -+ -+ return element.getLeft() != null && -+ element.getRight() != null && -+ element.getLeft() is JetSimpleNameExpression && -+ element.getOperationToken() == JetTokens.EQ && -+ rightExpression is JetBinaryExpression && -+ rightExpression.getLeft() != null && -+ rightExpression.getRight() != null","1) Extract `element.getLeft()` just like you did for `element.getRight()` (let's call it leftExpression) -2) There is no point in using `element.getRight()`/`element.getLeft()` in comparisons since they are/will be extracted to variables -3) `leftExpression !=null` is redundant (it's implied by `leftExpression is JetSimpleNameExpression`) -The same goes for `element.getRight() != null` -4) Also I'd change the function name since it doesn't just check for null safety. Something like `isWellFormedAssignment`, for example. -","Please put this on the previous line, with the rest of the file" -465,"@@ -0,0 +1,78 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetBinaryExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lexer.JetTokens -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.plugin.references.JetSimpleNameReference -+import org.jetbrains.jet.lang.psi.JetSimpleNameExpression -+ -+public class ReplaceWithOperatorAssignIntention : JetSelfTargetingIntention(""replace.with.operator.assign.intention"", javaClass()) { -+ override fun isApplicableTo(element: JetBinaryExpression): Boolean { -+ fun checkForNullSafety(element : JetBinaryExpression): Boolean { -+ val rightExpression = element.getRight() -+ -+ return element.getLeft() != null && -+ element.getRight() != null && -+ element.getLeft() is JetSimpleNameExpression && -+ element.getOperationToken() == JetTokens.EQ && -+ rightExpression is JetBinaryExpression && -+ rightExpression.getLeft() != null && -+ rightExpression.getRight() != null -+ } -+ -+ fun checkExpressionRepeat(variableExpression: JetSimpleNameExpression, expression: JetBinaryExpression): Boolean { -+ if (variableExpression.getText().equals(expression.getLeft()!!.getText())) -+ return expression.getOperationToken() == JetTokens.PLUS || -+ expression.getOperationToken() == JetTokens.MINUS || -+ expression.getOperationToken() == JetTokens.MUL || -+ expression.getOperationToken() == JetTokens.DIV || -+ expression.getOperationToken() == JetTokens.PERC -+ else if (variableExpression.getText().equals(expression.getRight()!!.getText())) -+ return expression.getOperationToken() == JetTokens.PLUS || -+ expression.getOperationToken() == JetTokens.MUL -+ else if (expression.getLeft() is JetBinaryExpression) -+ return checkExpressionRepeat(variableExpression, expression.getLeft() as JetBinaryExpression) -+ else -+ return false -+ } -+","1) JetPsiMatcher class provides more reliable and generic way to compare PSI elements. Please, use it instead of comparing element text directly. For example, `JetPsiMatcher.checkElementMatch(variableExpression, expression.getLeft())` -2) I suggest to use when expression instead of nested ""ifs"". Like this: - -``` -return when { - JetPsiMatcher.checkElementMatch(variableExpression, expression.getLeft()) -> ... - ... -} -``` - -3) This function is tail-recursive, so it's worth annotating it with `tailRecursive`. Then compiler can apply tail-call optimization to it. -",Is this the correct way to check for a null safe expression? I -466,"@@ -0,0 +1,78 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetBinaryExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lexer.JetTokens -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.plugin.references.JetSimpleNameReference -+import org.jetbrains.jet.lang.psi.JetSimpleNameExpression -+ -+public class ReplaceWithOperatorAssignIntention : JetSelfTargetingIntention(""replace.with.operator.assign.intention"", javaClass()) { -+ override fun isApplicableTo(element: JetBinaryExpression): Boolean { -+ fun checkForNullSafety(element : JetBinaryExpression): Boolean { -+ val rightExpression = element.getRight() -+ -+ return element.getLeft() != null && -+ element.getRight() != null && -+ element.getLeft() is JetSimpleNameExpression && -+ element.getOperationToken() == JetTokens.EQ && -+ rightExpression is JetBinaryExpression && -+ rightExpression.getLeft() != null && -+ rightExpression.getRight() != null -+ } -+ -+ fun checkExpressionRepeat(variableExpression: JetSimpleNameExpression, expression: JetBinaryExpression): Boolean { -+ if (variableExpression.getText().equals(expression.getLeft()!!.getText())) -+ return expression.getOperationToken() == JetTokens.PLUS || -+ expression.getOperationToken() == JetTokens.MINUS || -+ expression.getOperationToken() == JetTokens.MUL || -+ expression.getOperationToken() == JetTokens.DIV || -+ expression.getOperationToken() == JetTokens.PERC -+ else if (variableExpression.getText().equals(expression.getRight()!!.getText())) -+ return expression.getOperationToken() == JetTokens.PLUS || -+ expression.getOperationToken() == JetTokens.MUL -+ else if (expression.getLeft() is JetBinaryExpression) -+ return checkExpressionRepeat(variableExpression, expression.getLeft() as JetBinaryExpression) -+ else -+ return false -+ } -+ -+ if (checkForNullSafety(element)) { -+ return checkExpressionRepeat(element.getLeft() as JetSimpleNameExpression, element.getRight() as JetBinaryExpression) -+ } else { -+ return false -+ } -+ } -+ -+ override fun applyTo(element: JetBinaryExpression, editor: Editor) { -+ fun buildReplacement(variableExpression: JetSimpleNameExpression, expression: JetBinaryExpression, replacementBuilder: StringBuilder): String {","This function is also tail-recursive, so please add [tailRecursive] annotation. -",Is this the correct way to check for a null safe expression? I -467,"@@ -0,0 +1,79 @@ -+/* -+ * 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.components -+ -+import org.jetbrains.kotlin.descriptors.ClassDescriptor -+import org.jetbrains.kotlin.descriptors.ConstructorDescriptor -+import org.jetbrains.kotlin.descriptors.PropertyDescriptor -+import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor -+import org.jetbrains.kotlin.load.java.components.JavaResolverCache -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.java.structure.JavaElement -+import org.jetbrains.kotlin.load.java.structure.JavaField -+import org.jetbrains.kotlin.load.java.structure.JavaMethod -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.tail -+import org.jetbrains.kotlin.resolve.BindingContext -+import org.jetbrains.kotlin.resolve.BindingTrace -+import org.jetbrains.kotlin.resolve.lazy.ResolveSession -+import org.jetbrains.kotlin.resolve.lazy.ResolveSessionUtils -+import javax.inject.Inject -+ -+class JavacJavaResolverCache : JavaResolverCache {",Here we also could extract `AbstractJavaResolverCache`,Could you please add a license header like the one in the `Head -468,"@@ -0,0 +1,79 @@ -+/* -+ * 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.components -+ -+import org.jetbrains.kotlin.descriptors.ClassDescriptor -+import org.jetbrains.kotlin.descriptors.ConstructorDescriptor -+import org.jetbrains.kotlin.descriptors.PropertyDescriptor -+import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor -+import org.jetbrains.kotlin.load.java.components.JavaResolverCache -+import org.jetbrains.kotlin.load.java.structure.JavaClass -+import org.jetbrains.kotlin.load.java.structure.JavaElement -+import org.jetbrains.kotlin.load.java.structure.JavaField -+import org.jetbrains.kotlin.load.java.structure.JavaMethod -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.name.tail -+import org.jetbrains.kotlin.resolve.BindingContext -+import org.jetbrains.kotlin.resolve.BindingTrace -+import org.jetbrains.kotlin.resolve.lazy.ResolveSession -+import org.jetbrains.kotlin.resolve.lazy.ResolveSessionUtils -+import javax.inject.Inject -+ -+class JavacJavaResolverCache : JavaResolverCache { -+ -+ private lateinit var trace: BindingTrace -+ private lateinit var resolveSession: ResolveSession","In `LazyJavaResolverCache` both of them are `val`, why we do not want the same behaviour here?",Is this necessary? I don't see the need for a separate class. -469,"@@ -0,0 +1,8 @@ -+// ""Create method 'get' from usage"" ""true"" -+import java.util.ArrayList -+ -+class Foo {","Isn't it better to remove type parameter of class to avoid confusing when reading test? Or is it intentional? -",Could you add a license header here? -470,"@@ -0,0 +1,8 @@ -+enum class E { -+FOO -+fun foo() : Unit { -+FOO.toString() -+} -+public fun name() : String { return """" } -+public fun order() : Int { return 0 } -+} -\ No newline at end of file","The same: code formatting is wrong -",missing new line at the end of file -471,"@@ -0,0 +1,8 @@ -+var status: String = ""fail""","I beleive it would be good to add comment explaining why ""status"" here is top-level property instead of local variable. -",what is the reason for this change? -472,"@@ -0,0 +1,80 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetCallExpression -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.resolve.BindingContext -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetPrefixExpression -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import org.jetbrains.jet.lang.psi.JetBinaryExpression -+import org.jetbrains.jet.plugin.codeInsight.ShortenReferences -+import org.jetbrains.jet.lang.psi.JetCallableReferenceExpression -+import org.jetbrains.jet.lang.resolve.DescriptorUtils -+ -+public class ConvertAssertToIfWithThrowIntention : JetSelfTargetingIntention( -+ ""convert.assert.to.if.with.throw"", javaClass()) { -+ -+ override fun isApplicableTo(element: JetCallExpression): Boolean { -+ if (element.getCalleeExpression()?.getText() != ""assert"") return false -+ val arguments = element.getValueArguments().size -+ val lambdas = element.getFunctionLiteralArguments().size -+ if (!(arguments == 1 && (lambdas == 1 || lambdas == 0)) && arguments != 2) return false -+ val context = AnalyzerFacadeWithCache.getContextForElement(element) -+ val resolvedCall = context[BindingContext.RESOLVED_CALL, element.getCalleeExpression()] -+ if (resolvedCall == null) return false -+ return DescriptorUtils.getFqName(resolvedCall.getResultingDescriptor()).toString() == ""kotlin.assert""","fixed to use DescriptorUtils.getFqName -",Please annotate `@since` with `@since` -473,"@@ -0,0 +1,80 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetCallExpression -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.resolve.BindingContext -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetPrefixExpression -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import org.jetbrains.jet.lang.psi.JetBinaryExpression -+import org.jetbrains.jet.plugin.codeInsight.ShortenReferences -+import org.jetbrains.jet.lang.psi.JetCallableReferenceExpression -+import org.jetbrains.jet.lang.resolve.DescriptorUtils -+ -+public class ConvertAssertToIfWithThrowIntention : JetSelfTargetingIntention( -+ ""convert.assert.to.if.with.throw"", javaClass()) { -+ -+ override fun isApplicableTo(element: JetCallExpression): Boolean { -+ if (element.getCalleeExpression()?.getText() != ""assert"") return false -+ val arguments = element.getValueArguments().size -+ val lambdas = element.getFunctionLiteralArguments().size -+ if (!(arguments == 1 && (lambdas == 1 || lambdas == 0)) && arguments != 2) return false -+ val context = AnalyzerFacadeWithCache.getContextForElement(element) -+ val resolvedCall = context[BindingContext.RESOLVED_CALL, element.getCalleeExpression()] -+ if (resolvedCall == null) return false -+ return DescriptorUtils.getFqName(resolvedCall.getResultingDescriptor()).toString() == ""kotlin.assert"" -+ } -+ -+ override fun applyTo(element: JetCallExpression, editor: Editor) { -+ val args = element.getValueArguments() -+ val condition = args[0]?.getArgumentExpression() -+ val lambdas = element.getFunctionLiteralArguments() -+ -+ val messageExpr = if (args.size == 2) { -+ args[1]?.getArgumentExpression() -+ } else if (lambdas.isNotEmpty()) {","!lambdas.isEmpty changed to lambdas.isNotEmpty() -",Please annotate `@since` with `@since` -474,"@@ -0,0 +1,81 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+ -+public class MakeTypeImplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.implicit.in.lambda"", javaClass()) { -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ throw IllegalStateException(""isApplicableTo(JetExpressionImpl, Editor) should be called instead"") -+ } -+ -+ override fun isApplicableTo(element: JetFunctionLiteralExpression, editor: Editor): Boolean { -+ val openBraceOffset = element.getLeftCurlyBrace().getStartOffset() -+ val closeBraceOffset = element.getRightCurlyBrace()?.getStartOffset() -+ val caretLocation = editor.getCaretModel().getOffset() -+ val paramsTextRange = element.getFunctionLiteral().getValueParameterList()?.getTextRange() -+ val caretIsInParams = if (paramsTextRange != null) {","Ditto (`paramsTextRange != null && caretLocation in paramsTextRange` or `paramsTextRange?.contains(caretLocation) ?: false`) -",Please rename the file to `MakeTypeImplicitInLambdaIntention.ja -475,"@@ -0,0 +1,81 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+ -+public class MakeTypeImplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.implicit.in.lambda"", javaClass()) { -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ throw IllegalStateException(""isApplicableTo(JetExpressionImpl, Editor) should be called instead"") -+ } -+ -+ override fun isApplicableTo(element: JetFunctionLiteralExpression, editor: Editor): Boolean { -+ val openBraceOffset = element.getLeftCurlyBrace().getStartOffset() -+ val closeBraceOffset = element.getRightCurlyBrace()?.getStartOffset() -+ val caretLocation = editor.getCaretModel().getOffset() -+ val paramsTextRange = element.getFunctionLiteral().getValueParameterList()?.getTextRange() -+ val caretIsInParams = if (paramsTextRange != null) { -+ caretLocation in paramsTextRange -+ } -+ else false -+ if (!(caretLocation == openBraceOffset + 1 || caretLocation == closeBraceOffset || caretIsInParams)) return false","Ditto -",Please rename the file to 'implicit.in.lambda' -476,"@@ -0,0 +1,81 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+ -+public class MakeTypeImplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.implicit.in.lambda"", javaClass()) { -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ throw IllegalStateException(""isApplicableTo(JetExpressionImpl, Editor) should be called instead"") -+ } -+ -+ override fun isApplicableTo(element: JetFunctionLiteralExpression, editor: Editor): Boolean { -+ val openBraceOffset = element.getLeftCurlyBrace().getStartOffset() -+ val closeBraceOffset = element.getRightCurlyBrace()?.getStartOffset() -+ val caretLocation = editor.getCaretModel().getOffset() -+ val paramsTextRange = element.getFunctionLiteral().getValueParameterList()?.getTextRange() -+ val caretIsInParams = if (paramsTextRange != null) { -+ caretLocation in paramsTextRange -+ } -+ else false -+ if (!(caretLocation == openBraceOffset + 1 || caretLocation == closeBraceOffset || caretIsInParams)) return false -+ -+ val params = element.getValueParameters() -+ val hasDeclaredParamsType = params.any { it.getTypeReference() != null } -+ val hasDeclaredReturnType = element.hasDeclaredReturnType() -+ val hasDeclaredReceiverType = element.getFunctionLiteral().getReceiverTypeRef() != null -+ if (hasDeclaredParamsType || hasDeclaredReturnType || hasDeclaredReceiverType) return true","I think I noticed the first time: such code creates a false sense that the applicability of the intention here depends on all three of these variables. Your code should look more like this: -1. if has declared params type, return true -2. if has declared return type, return true -3. if has declared receiver type, return true -4. return false - -Once you refactor your code to look like this, you'll notice that these variables are no longer needed since they can be inlined. This will make the code shorter. Please do this. -",Please rename the class to `MakeTypeImplicitInLambdaExpression` -477,"@@ -0,0 +1,81 @@ -+/* -+ * 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.idea.inspections -+ -+import com.intellij.codeInspection.* -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiElementVisitor -+import org.jetbrains.kotlin.KtNodeTypes -+import org.jetbrains.kotlin.psi.* -+ -+class RedundantIfInspection : AbstractKotlinInspection(), CleanupLocalInspectionTool { -+ -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor { -+ return object : KtVisitorVoid() { -+ override fun visitIfExpression(expression: KtIfExpression) { -+ super.visitIfExpression(expression) -+ -+ if (expression.condition != null && isRedundant(expression)) { -+ holder.registerProblem(expression, -+ ""Redundant 'if' statement"", -+ ProblemHighlightType.LIKE_UNUSED_SYMBOL, -+ RemoveRedundantIf) -+ } -+ } -+ } -+ } -+ -+ private fun isRedundant(expression: KtIfExpression): Boolean { -+ val thenReturn = getReturnedExpression(expression.then) ?: return false -+ val elseReturn = getReturnedExpression(expression.`else`) ?: return false -+ -+ if (KtPsiUtil.isTrueConstant(thenReturn) && !KtPsiUtil.isTrueConstant(elseReturn)) {","I find it somewhat confusing that the KtNodeTypes.BOOLEAN_CONSTANT check is separate from the value check. It would be clearer to add the corresponding `isFalseConstant()` method to `KtPsiUtil` and to remove the node type check from `getReturnedExpression()`. -",Why only for `if` expressions? -478,"@@ -0,0 +1,81 @@ -+/* -+ * 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.idea.inspections -+ -+import com.intellij.codeInspection.* -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiElementVisitor -+import org.jetbrains.kotlin.KtNodeTypes -+import org.jetbrains.kotlin.psi.* -+ -+class RedundantIfInspection : AbstractKotlinInspection(), CleanupLocalInspectionTool { -+ -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor { -+ return object : KtVisitorVoid() { -+ override fun visitIfExpression(expression: KtIfExpression) { -+ super.visitIfExpression(expression) -+ -+ if (expression.condition != null && isRedundant(expression)) { -+ holder.registerProblem(expression, -+ ""Redundant 'if' statement"", -+ ProblemHighlightType.LIKE_UNUSED_SYMBOL, -+ RemoveRedundantIf) -+ } -+ } -+ } -+ } -+ -+ private fun isRedundant(expression: KtIfExpression): Boolean { -+ val thenReturn = getReturnedExpression(expression.then) ?: return false -+ val elseReturn = getReturnedExpression(expression.`else`) ?: return false -+ -+ if (KtPsiUtil.isTrueConstant(thenReturn) && !KtPsiUtil.isTrueConstant(elseReturn)) { -+ return true -+ } -+ -+ if (!KtPsiUtil.isTrueConstant(thenReturn) && KtPsiUtil.isTrueConstant(elseReturn)) { -+ return true -+ } -+ -+ return false -+ } -+ -+ private fun getReturnedExpression(expression: KtExpression?) : KtExpression? { -+ if (expression == null) return null -+ if (expression !is KtBlockExpression) return null","This check isn't necessary: a statement where `return` is not enclosed in braces is no less trivial. -",Why only for `if` expressions? -479,"@@ -0,0 +1,81 @@ -+/* -+ * 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.idea.inspections -+ -+import com.intellij.codeInspection.* -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiElementVisitor -+import org.jetbrains.kotlin.KtNodeTypes -+import org.jetbrains.kotlin.psi.* -+ -+class RedundantIfInspection : AbstractKotlinInspection(), CleanupLocalInspectionTool { -+ -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor { -+ return object : KtVisitorVoid() { -+ override fun visitIfExpression(expression: KtIfExpression) { -+ super.visitIfExpression(expression) -+ -+ if (expression.condition != null && isRedundant(expression)) { -+ holder.registerProblem(expression, -+ ""Redundant 'if' statement"", -+ ProblemHighlightType.LIKE_UNUSED_SYMBOL, -+ RemoveRedundantIf) -+ } -+ } -+ } -+ } -+ -+ private fun isRedundant(expression: KtIfExpression): Boolean { -+ val thenReturn = getReturnedExpression(expression.then) ?: return false -+ val elseReturn = getReturnedExpression(expression.`else`) ?: return false -+ -+ if (KtPsiUtil.isTrueConstant(thenReturn) && !KtPsiUtil.isTrueConstant(elseReturn)) { -+ return true -+ } -+ -+ if (!KtPsiUtil.isTrueConstant(thenReturn) && KtPsiUtil.isTrueConstant(elseReturn)) { -+ return true -+ } -+ -+ return false -+ } -+ -+ private fun getReturnedExpression(expression: KtExpression?) : KtExpression? { -+ if (expression == null) return null -+ if (expression !is KtBlockExpression) return null -+ if (expression.statements.size != 1) return null -+ -+ val statement = expression.statements[0]","`expression.statements.singleOrNull() as? KtReturnExpression ?: return null` -",Why only for `if` expressions? -480,"@@ -0,0 +1,81 @@ -+/* -+ * 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.idea.quickfix -+ -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiElement -+import com.intellij.psi.PsiFile -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers -+import org.jetbrains.kotlin.idea.util.ShortenReferences -+import org.jetbrains.kotlin.psi.KtClassOrObject -+import org.jetbrains.kotlin.psi.KtExpression -+import org.jetbrains.kotlin.psi.KtFile -+import org.jetbrains.kotlin.psi.KtPsiFactory -+import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils -+import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode -+import org.jetbrains.kotlin.types.KotlinType -+import org.jetbrains.kotlin.types.typeUtil.isInterface -+import org.jetbrains.kotlin.types.typeUtil.supertypes -+ -+private fun KotlinType.renderShort() = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.renderType(this) -+ -+private fun KotlinType.getSuperTypesRecursive() = constructor.supertypes.let { it + it.flatMap { it.supertypes() } }","BTW, this is exponential; please use `TypeUtils#getAllSupertypes` instead -",Could you please move this to the bottom of the package? -481,"@@ -0,0 +1,82 @@ -+/* -+ * 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.idea.inspections -+ -+import com.intellij.codeInspection.* -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiElementVisitor -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.idea.references.mainReference -+import org.jetbrains.kotlin.psi.* -+import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe -+import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode -+ -+class UnnecessaryJavaUsageInspection : AbstractKotlinInspection(), CleanupLocalInspectionTool { -+ -+ private val patterns = mapOf( -+ ""java.io.PrintStream.println"" to Pair(""println($0)"", ConversionType.METHOD),","What about other usages of `PrintStream.println` outside of `System.out`, e.g. `System.err`? This will produce a lot of false positives. -",Remove the wildcard import. -482,"@@ -0,0 +1,82 @@ -+/* -+ * 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.idea.inspections -+ -+import com.intellij.codeInspection.* -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiElementVisitor -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.idea.references.mainReference -+import org.jetbrains.kotlin.psi.* -+import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe -+import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode -+ -+class UnnecessaryJavaUsageInspection : AbstractKotlinInspection(), CleanupLocalInspectionTool { -+ -+ private val patterns = mapOf( -+ ""java.io.PrintStream.println"" to Pair(""println($0)"", ConversionType.METHOD), -+ ""java.io.PrintStream.print"" to Pair(""print($0)"", ConversionType.METHOD), -+ ""java.util.Collections.sort"" to Pair(""$0.sort()"", ConversionType.METHOD), -+ ""java.util.HashMap.put"" to Pair(""$0[$1] = $2"", ConversionType.ASSIGNMENT)","Why limit to `HashMap`? -",Remove the wildcard import. -483,"@@ -0,0 +1,82 @@ -+/* -+ * 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.idea.inspections -+ -+import com.intellij.codeInspection.* -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiElementVisitor -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.idea.references.mainReference -+import org.jetbrains.kotlin.psi.* -+import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe -+import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode -+ -+class UnnecessaryJavaUsageInspection : AbstractKotlinInspection(), CleanupLocalInspectionTool { -+ -+ private val patterns = mapOf( -+ ""java.io.PrintStream.println"" to Pair(""println($0)"", ConversionType.METHOD), -+ ""java.io.PrintStream.print"" to Pair(""print($0)"", ConversionType.METHOD), -+ ""java.util.Collections.sort"" to Pair(""$0.sort()"", ConversionType.METHOD), -+ ""java.util.HashMap.put"" to Pair(""$0[$1] = $2"", ConversionType.ASSIGNMENT) -+ ) -+ -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor { -+ return object : KtVisitorVoid() { -+ override fun visitQualifiedExpression(expression: KtQualifiedExpression) { -+ super.visitQualifiedExpression(expression) -+ -+ val selectorExpression = expression.selectorExpression -+ if(selectorExpression !is KtCallExpression) return -+ val args = selectorExpression.valueArguments -+ if(args.isEmpty()) return -+ -+ val calleeExpression = selectorExpression.calleeExpression as? KtSimpleNameExpression ?: return -+ val bindingContext = calleeExpression.analyze(BodyResolveMode.PARTIAL) -+ val target = calleeExpression.mainReference.resolveToDescriptors(bindingContext).singleOrNull() ?: return","You can use `findOriginalTopMostOverriddenDescriptors` e.g. to to get `MutableMap.put` instead of `HashMap.put` -",Remove the wildcard import. -484,"@@ -0,0 +1,82 @@ -+/* -+ * 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.idea.quickfix -+ -+import com.intellij.codeInsight.intention.IntentionAction -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiFile -+import org.jetbrains.kotlin.builtins.KotlinBuiltIns -+import org.jetbrains.kotlin.descriptors.ClassDescriptor -+import org.jetbrains.kotlin.diagnostics.Diagnostic -+import org.jetbrains.kotlin.diagnostics.Errors -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.psi.KtDotQualifiedExpression -+import org.jetbrains.kotlin.psi.KtExpression -+import org.jetbrains.kotlin.psi.KtFile -+import org.jetbrains.kotlin.psi.psiUtil.endOffset -+import org.jetbrains.kotlin.psi.psiUtil.startOffset -+import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe -+import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode -+import org.jetbrains.kotlin.types.KotlinType -+import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf -+ -+private val JAVA_LANG_CLASS_FQ_NAME = FqName(""java.lang.Class"") -+ -+private fun KotlinType.isJClass(): Boolean { -+ val expressionTypeFqName = constructor.declarationDescriptor?.fqNameSafe ?: return false -+ return expressionTypeFqName == JAVA_LANG_CLASS_FQ_NAME -+} -+ -+class ConvertClassToKClassFix(element: KtDotQualifiedExpression, private val type: KotlinType) : KotlinQuickFixAction(element) { -+ override fun getText() = ""Remove '.${element.children.lastOrNull()?.text}'"" -+ override fun getFamilyName() = ""Remove conversion from 'KClass' to 'Class'"" -+ -+ -+ override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean { -+ if (!super.isAvailable(project, editor, file)) return false -+ -+ val expressionType = element.analyze(BodyResolveMode.PARTIAL).getType(element) ?: return false -+ if (!expressionType.isJClass()) return false -+ -+ val children = element.children -+ if (children.size != 2) return false -+ -+ val firstChild = children.first() as? KtExpression ?: return false -+ val firstChildType = firstChild.analyze(BodyResolveMode.PARTIAL).getType(firstChild) ?: return false","You should reuse the BindingContext from the first analyze() call. -",Could you please move this to the bottom of the package? -485,"@@ -0,0 +1,82 @@ -+/* -+ * 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.idea.quickfix -+ -+import com.intellij.codeInsight.intention.IntentionAction -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiFile -+import org.jetbrains.kotlin.builtins.KotlinBuiltIns -+import org.jetbrains.kotlin.descriptors.ClassDescriptor -+import org.jetbrains.kotlin.diagnostics.Diagnostic -+import org.jetbrains.kotlin.diagnostics.Errors -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.psi.KtDotQualifiedExpression -+import org.jetbrains.kotlin.psi.KtExpression -+import org.jetbrains.kotlin.psi.KtFile -+import org.jetbrains.kotlin.psi.psiUtil.endOffset -+import org.jetbrains.kotlin.psi.psiUtil.startOffset -+import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe -+import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode -+import org.jetbrains.kotlin.types.KotlinType -+import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf -+ -+private val JAVA_LANG_CLASS_FQ_NAME = FqName(""java.lang.Class"") -+ -+private fun KotlinType.isJClass(): Boolean { -+ val expressionTypeFqName = constructor.declarationDescriptor?.fqNameSafe ?: return false -+ return expressionTypeFqName == JAVA_LANG_CLASS_FQ_NAME -+} -+ -+class ConvertClassToKClassFix(element: KtDotQualifiedExpression, private val type: KotlinType) : KotlinQuickFixAction(element) { -+ override fun getText() = ""Remove '.${element.children.lastOrNull()?.text}'"" -+ override fun getFamilyName() = ""Remove conversion from 'KClass' to 'Class'"" -+ -+ -+ override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean { -+ if (!super.isAvailable(project, editor, file)) return false -+ -+ val expressionType = element.analyze(BodyResolveMode.PARTIAL).getType(element) ?: return false -+ if (!expressionType.isJClass()) return false -+ -+ val children = element.children -+ if (children.size != 2) return false -+ -+ val firstChild = children.first() as? KtExpression ?: return false -+ val firstChildType = firstChild.analyze(BodyResolveMode.PARTIAL).getType(firstChild) ?: return false -+ -+ return firstChildType.isSubtypeOf(type) -+ } -+ -+ override fun invoke(project: Project, editor: Editor?, file: KtFile) { -+ val lastChild = element.children.lastOrNull() ?: return -+ editor?.document?.replaceString(lastChild.startOffset - 1, lastChild.endOffset, """")","The quickfix will do nothing if there is no editor. It's possible to perform the change through the PSI, and it's better to do it that way. -",Could you please move this to the bottom of the package? -486,"@@ -0,0 +1,82 @@ -+/* -+ * 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.components -+ -+import com.intellij.openapi.project.Project -+import com.intellij.openapi.vfs.VirtualFile -+import com.intellij.psi.search.DelegatingGlobalSearchScope -+import com.intellij.psi.search.GlobalSearchScope -+import org.jetbrains.kotlin.javac.Javac -+import org.jetbrains.kotlin.idea.KotlinFileType -+import org.jetbrains.kotlin.load.java.JavaClassFinder -+import org.jetbrains.kotlin.name.ClassId -+import org.jetbrains.kotlin.name.FqName -+import org.jetbrains.kotlin.resolve.BindingTrace -+import org.jetbrains.kotlin.resolve.CodeAnalyzerInitializer -+import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer -+import javax.annotation.PostConstruct -+import javax.inject.Inject -+ -+class JavacClassFinder : JavaClassFinder {",JavacBasedClassFinder?,Is this annotation needed? I don't see any references to -487,"@@ -0,0 +1,83 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetForExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression -+import com.intellij.psi.util.PsiTreeUtil -+import com.intellij.psi.PsiDocumentManager -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.resolve.BindingContext -+import org.jetbrains.jet.lang.psi.JetParenthesizedExpression -+import com.intellij.codeInsight.template.TemplateBuilderImpl -+import com.intellij.codeInsight.template.impl.TemplateManagerImpl -+import org.jetbrains.jet.lang.resolve.DescriptorUtils -+import org.jetbrains.jet.analyzer.analyzeInContext -+import org.jetbrains.jet.lang.psi.JetCallExpression -+ -+public class AddForLoopIndicesIntention : JetSelfTargetingIntention( -+ ""add.for.loop.indices"", javaClass()) { -+ override fun applyTo(element: JetForExpression, editor: Editor) { -+ val loopRange = element.getLoopRange()!! -+ val newRangeText = ""${loopRange.getText()}.withIndices()"" -+ val newRange = JetPsiFactory.createExpression(editor.getProject(), newRangeText) -+ -+ //Roundabout way to create new multiparameter element so as not to incorrectly trigger syntax error highlighting -+ val loopParameter = element.getLoopParameter()!! -+ val parenthesizedParam = JetPsiFactory.createExpression(editor.getProject(), ""(index)"") as JetParenthesizedExpression -+ val indexElement = parenthesizedParam.getExpression()!! -+ val comma = JetPsiFactory.createComma(editor.getProject()) -+ val newParamElement = JetPsiFactory.createExpression(editor.getProject(), "" ${loopParameter.getText()}"") -+ parenthesizedParam.addAfter(newParamElement, indexElement) -+ parenthesizedParam.addAfter(comma, indexElement) -+ -+ loopParameter.replace(parenthesizedParam) -+ loopRange.replace(newRange) -+ -+ val multiParameter = PsiTreeUtil.findChildOfType(element, indexElement.javaClass)!! -+ -+ editor.getCaretModel().moveToOffset(multiParameter.getTextOffset()) -+ val templateBuilder = TemplateBuilderImpl(multiParameter) -+ templateBuilder.replaceElement(multiParameter, ""index"") -+ val manager = TemplateManagerImpl(editor.getProject()) -+ PsiDocumentManager.getInstance(editor.getProject()!!).doPostponedOperationsAndUnblockDocument(editor.getDocument()) -+ manager.startTemplate(editor, templateBuilder.buildInlineTemplate()!!) -+ } -+ -+ override fun isApplicableTo(element: JetForExpression): Boolean { -+ if (element.getLoopParameter() == null) return false -+ val range = element.getLoopRange() ?: return false -+ if (range is JetDotQualifiedExpression) { -+ val selector = range.getSelectorExpression() ?: return true -+ if (selector.getText() == ""withIndices()"") return false","The same here, I wouldn't want **add withIndices** intention to be applicable where I've typed `withIndices ()` -",missing new line -488,"@@ -0,0 +1,83 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetForExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression -+import com.intellij.psi.util.PsiTreeUtil -+import com.intellij.psi.PsiDocumentManager -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.resolve.BindingContext -+import org.jetbrains.jet.lang.psi.JetParenthesizedExpression -+import com.intellij.codeInsight.template.TemplateBuilderImpl -+import com.intellij.codeInsight.template.impl.TemplateManagerImpl -+import org.jetbrains.jet.lang.resolve.DescriptorUtils -+import org.jetbrains.jet.analyzer.analyzeInContext -+import org.jetbrains.jet.lang.psi.JetCallExpression -+ -+public class AddForLoopIndicesIntention : JetSelfTargetingIntention( -+ ""add.for.loop.indices"", javaClass()) { -+ override fun applyTo(element: JetForExpression, editor: Editor) { -+ val loopRange = element.getLoopRange()!! -+ val newRangeText = ""${loopRange.getText()}.withIndices()"" -+ val newRange = JetPsiFactory.createExpression(editor.getProject(), newRangeText) -+ -+ //Roundabout way to create new multiparameter element so as not to incorrectly trigger syntax error highlighting -+ val loopParameter = element.getLoopParameter()!! -+ val parenthesizedParam = JetPsiFactory.createExpression(editor.getProject(), ""(index)"") as JetParenthesizedExpression -+ val indexElement = parenthesizedParam.getExpression()!! -+ val comma = JetPsiFactory.createComma(editor.getProject()) -+ val newParamElement = JetPsiFactory.createExpression(editor.getProject(), "" ${loopParameter.getText()}"") -+ parenthesizedParam.addAfter(newParamElement, indexElement) -+ parenthesizedParam.addAfter(comma, indexElement) -+ -+ loopParameter.replace(parenthesizedParam) -+ loopRange.replace(newRange) -+ -+ val multiParameter = PsiTreeUtil.findChildOfType(element, indexElement.javaClass)!! -+ -+ editor.getCaretModel().moveToOffset(multiParameter.getTextOffset()) -+ val templateBuilder = TemplateBuilderImpl(multiParameter) -+ templateBuilder.replaceElement(multiParameter, ""index"") -+ val manager = TemplateManagerImpl(editor.getProject()) -+ PsiDocumentManager.getInstance(editor.getProject()!!).doPostponedOperationsAndUnblockDocument(editor.getDocument()) -+ manager.startTemplate(editor, templateBuilder.buildInlineTemplate()!!) -+ } -+ -+ override fun isApplicableTo(element: JetForExpression): Boolean { -+ if (element.getLoopParameter() == null) return false -+ val range = element.getLoopRange() ?: return false -+ if (range is JetDotQualifiedExpression) { -+ val selector = range.getSelectorExpression() ?: return true -+ if (selector.getText() == ""withIndices()"") return false -+ } -+ -+ val potentialExpression = JetPsiFactory.createExpression(element.getProject(), -+ ""${range.getText()}.withIndices()"") as JetDotQualifiedExpression -+ -+ val bindingContext = AnalyzerFacadeWithCache.getContextForElement(element) -+ val scope = bindingContext[BindingContext.RESOLUTION_SCOPE, element] ?: return false -+ val functionSelector = potentialExpression.getSelectorExpression() as JetCallExpression -+ val updatedContext = potentialExpression.analyzeInContext(scope) -+ val callScope = updatedContext[BindingContext.RESOLVED_CALL, functionSelector.getCalleeExpression()!!] ?: return false -+ val callFqName = DescriptorUtils.getFqNameSafe(callScope.getCandidateDescriptor())","You shouldn't call `getFqNameSafe`, because FQ name can be unsafe here (consider functions in class objects) -",missing new line -489,"@@ -0,0 +1,83 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetForExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression -+import org.jetbrains.jet.lang.psi.JetPsiUtil -+import org.jetbrains.jet.lang.cfg.PseudocodeVariablesData.VariableUseState -+import org.jetbrains.jet.lang.cfg.pseudocode.PseudocodeUtil -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.psi.JetFile -+import org.jetbrains.jet.lang.resolve.ObservableBindingTrace -+import org.jetbrains.jet.lang.resolve.BindingTraceContext -+import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider -+import org.jetbrains.jet.lang.cfg.JetControlFlowProcessor -+import com.intellij.debugger.jdi.LocalVariablesUtil -+import com.siyeh.ig.psiutils.VariableAccessUtils -+import com.google.dart.compiler.util.AstUtil -+import com.intellij.find.FindManager -+import com.intellij.find.impl.FindManagerImpl -+import com.intellij.usageView.UsageInfo -+import com.intellij.util.Processor -+import org.jetbrains.jet.plugin.findUsages.KotlinPropertyFindUsagesOptions -+ -+public class RemoveForLoopIndicesIntention : JetSelfTargetingIntention( -+ ""remove.for.loop.indices"", javaClass()) { -+ override fun applyTo(element: JetForExpression, editor: Editor) { -+ val parameter = element.getMultiParameter()!! -+ val range = element.getLoopRange() as JetDotQualifiedExpression -+ val parameters = parameter.getEntries() -+ if (parameters.size() == 2) { -+ parameter.replace(parameters[1]) -+ } else { -+ JetPsiUtil.deleteElementWithDelimiters(parameters[0]) -+ } -+ -+ range.replace(range.getReceiverExpression()) -+ } -+ -+ override fun isApplicableTo(element: JetForExpression): Boolean { -+ if (element.getMultiParameter() == null) return false -+ val range = element.getLoopRange() as? JetDotQualifiedExpression ?: return false -+ val selector = range.getSelectorExpression() ?: return false -+ if (!selector.textMatches(""withIndices()"")) return false -+ -+ val indexVar = element.getMultiParameter()!!.getEntries()[0] -+ -+ val findManager = FindManager.getInstance(element.getProject()) as FindManagerImpl -+ val findHandler = findManager.getFindUsagesManager().getFindUsagesHandler(indexVar,false) ?: return false -+ val options = KotlinPropertyFindUsagesOptions(element.getProject()) -+ val usageCount = array(0)","Once again experience the power of Kotlin and just use a `var` here -",Please move intellij copyright date to the header -490,"@@ -0,0 +1,83 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetForExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression -+import org.jetbrains.jet.lang.psi.JetPsiUtil -+import org.jetbrains.jet.lang.cfg.PseudocodeVariablesData.VariableUseState -+import org.jetbrains.jet.lang.cfg.pseudocode.PseudocodeUtil -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.psi.JetFile -+import org.jetbrains.jet.lang.resolve.ObservableBindingTrace -+import org.jetbrains.jet.lang.resolve.BindingTraceContext -+import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider -+import org.jetbrains.jet.lang.cfg.JetControlFlowProcessor -+import com.intellij.debugger.jdi.LocalVariablesUtil -+import com.siyeh.ig.psiutils.VariableAccessUtils -+import com.google.dart.compiler.util.AstUtil -+import com.intellij.find.FindManager -+import com.intellij.find.impl.FindManagerImpl -+import com.intellij.usageView.UsageInfo -+import com.intellij.util.Processor -+import org.jetbrains.jet.plugin.findUsages.KotlinPropertyFindUsagesOptions -+ -+public class RemoveForLoopIndicesIntention : JetSelfTargetingIntention( -+ ""remove.for.loop.indices"", javaClass()) { -+ override fun applyTo(element: JetForExpression, editor: Editor) { -+ val parameter = element.getMultiParameter()!! -+ val range = element.getLoopRange() as JetDotQualifiedExpression -+ val parameters = parameter.getEntries() -+ if (parameters.size() == 2) { -+ parameter.replace(parameters[1]) -+ } else { -+ JetPsiUtil.deleteElementWithDelimiters(parameters[0]) -+ } -+ -+ range.replace(range.getReceiverExpression()) -+ } -+ -+ override fun isApplicableTo(element: JetForExpression): Boolean { -+ if (element.getMultiParameter() == null) return false -+ val range = element.getLoopRange() as? JetDotQualifiedExpression ?: return false -+ val selector = range.getSelectorExpression() ?: return false -+ if (!selector.textMatches(""withIndices()"")) return false -+ -+ val indexVar = element.getMultiParameter()!!.getEntries()[0] -+ -+ val findManager = FindManager.getInstance(element.getProject()) as FindManagerImpl -+ val findHandler = findManager.getFindUsagesManager().getFindUsagesHandler(indexVar,false) ?: return false -+ val options = KotlinPropertyFindUsagesOptions(element.getProject()) -+ val usageCount = array(0) -+ val usageFinderRunnable = object : Runnable { -+ override fun run() { -+ val processor = object : Processor { -+ override fun process(t: UsageInfo?): Boolean { -+ usageCount[0] = usageCount[0] + 1","How about `++`? -",Please move intellij copyright date to the header -491,"@@ -0,0 +1,83 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetForExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression -+import org.jetbrains.jet.lang.psi.JetPsiUtil -+import org.jetbrains.jet.lang.cfg.PseudocodeVariablesData.VariableUseState -+import org.jetbrains.jet.lang.cfg.pseudocode.PseudocodeUtil -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.psi.JetFile -+import org.jetbrains.jet.lang.resolve.ObservableBindingTrace -+import org.jetbrains.jet.lang.resolve.BindingTraceContext -+import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider -+import org.jetbrains.jet.lang.cfg.JetControlFlowProcessor -+import com.intellij.debugger.jdi.LocalVariablesUtil -+import com.siyeh.ig.psiutils.VariableAccessUtils -+import com.google.dart.compiler.util.AstUtil -+import com.intellij.find.FindManager -+import com.intellij.find.impl.FindManagerImpl -+import com.intellij.usageView.UsageInfo -+import com.intellij.util.Processor -+import org.jetbrains.jet.plugin.findUsages.KotlinPropertyFindUsagesOptions -+ -+public class RemoveForLoopIndicesIntention : JetSelfTargetingIntention( -+ ""remove.for.loop.indices"", javaClass()) { -+ override fun applyTo(element: JetForExpression, editor: Editor) { -+ val parameter = element.getMultiParameter()!! -+ val range = element.getLoopRange() as JetDotQualifiedExpression -+ val parameters = parameter.getEntries() -+ if (parameters.size() == 2) { -+ parameter.replace(parameters[1]) -+ } else { -+ JetPsiUtil.deleteElementWithDelimiters(parameters[0]) -+ } -+ -+ range.replace(range.getReceiverExpression()) -+ } -+ -+ override fun isApplicableTo(element: JetForExpression): Boolean { -+ if (element.getMultiParameter() == null) return false -+ val range = element.getLoopRange() as? JetDotQualifiedExpression ?: return false -+ val selector = range.getSelectorExpression() ?: return false -+ if (!selector.textMatches(""withIndices()"")) return false -+ -+ val indexVar = element.getMultiParameter()!!.getEntries()[0] -+ -+ val findManager = FindManager.getInstance(element.getProject()) as FindManagerImpl -+ val findHandler = findManager.getFindUsagesManager().getFindUsagesHandler(indexVar,false) ?: return false -+ val options = KotlinPropertyFindUsagesOptions(element.getProject()) -+ val usageCount = array(0) -+ val usageFinderRunnable = object : Runnable { -+ override fun run() { -+ val processor = object : Processor { -+ override fun process(t: UsageInfo?): Boolean { -+ usageCount[0] = usageCount[0] + 1 -+ return true","Do you really need to continue processing all usages if you've already found one? This also means that you should just have a boolean flag instead of an integer value -",Please move intellij copyright date to the header -492,"@@ -0,0 +1,83 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetForExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression -+import org.jetbrains.jet.lang.psi.JetPsiUtil -+import org.jetbrains.jet.lang.cfg.PseudocodeVariablesData.VariableUseState -+import org.jetbrains.jet.lang.cfg.pseudocode.PseudocodeUtil -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.psi.JetFile -+import org.jetbrains.jet.lang.resolve.ObservableBindingTrace -+import org.jetbrains.jet.lang.resolve.BindingTraceContext -+import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider -+import org.jetbrains.jet.lang.cfg.JetControlFlowProcessor -+import com.intellij.debugger.jdi.LocalVariablesUtil -+import com.siyeh.ig.psiutils.VariableAccessUtils -+import com.google.dart.compiler.util.AstUtil -+import com.intellij.find.FindManager -+import com.intellij.find.impl.FindManagerImpl -+import com.intellij.usageView.UsageInfo -+import com.intellij.util.Processor -+import org.jetbrains.jet.plugin.findUsages.KotlinPropertyFindUsagesOptions -+ -+public class RemoveForLoopIndicesIntention : JetSelfTargetingIntention( -+ ""remove.for.loop.indices"", javaClass()) { -+ override fun applyTo(element: JetForExpression, editor: Editor) { -+ val parameter = element.getMultiParameter()!! -+ val range = element.getLoopRange() as JetDotQualifiedExpression -+ val parameters = parameter.getEntries() -+ if (parameters.size() == 2) { -+ parameter.replace(parameters[1]) -+ } else { -+ JetPsiUtil.deleteElementWithDelimiters(parameters[0]) -+ } -+ -+ range.replace(range.getReceiverExpression()) -+ } -+ -+ override fun isApplicableTo(element: JetForExpression): Boolean { -+ if (element.getMultiParameter() == null) return false -+ val range = element.getLoopRange() as? JetDotQualifiedExpression ?: return false -+ val selector = range.getSelectorExpression() ?: return false -+ if (!selector.textMatches(""withIndices()"")) return false -+ -+ val indexVar = element.getMultiParameter()!!.getEntries()[0] -+ -+ val findManager = FindManager.getInstance(element.getProject()) as FindManagerImpl -+ val findHandler = findManager.getFindUsagesManager().getFindUsagesHandler(indexVar,false) ?: return false -+ val options = KotlinPropertyFindUsagesOptions(element.getProject()) -+ val usageCount = array(0) -+ val usageFinderRunnable = object : Runnable { -+ override fun run() { -+ val processor = object : Processor { -+ override fun process(t: UsageInfo?): Boolean { -+ usageCount[0] = usageCount[0] + 1 -+ return true -+ } -+ } -+ findHandler.processElementUsages(indexVar,processor,options)","`Processor` is a Java interface with a single method (SAM interface), so you should be able to just pass a lambda instead of an object expression, thanks to SAM conversion in Kotlin -",Please move intellij copyright date to the header -493,"@@ -0,0 +1,83 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetForExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression -+import org.jetbrains.jet.lang.psi.JetPsiUtil -+import org.jetbrains.jet.lang.cfg.PseudocodeVariablesData.VariableUseState -+import org.jetbrains.jet.lang.cfg.pseudocode.PseudocodeUtil -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.psi.JetFile -+import org.jetbrains.jet.lang.resolve.ObservableBindingTrace -+import org.jetbrains.jet.lang.resolve.BindingTraceContext -+import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider -+import org.jetbrains.jet.lang.cfg.JetControlFlowProcessor -+import com.intellij.debugger.jdi.LocalVariablesUtil -+import com.siyeh.ig.psiutils.VariableAccessUtils -+import com.google.dart.compiler.util.AstUtil -+import com.intellij.find.FindManager -+import com.intellij.find.impl.FindManagerImpl -+import com.intellij.usageView.UsageInfo -+import com.intellij.util.Processor -+import org.jetbrains.jet.plugin.findUsages.KotlinPropertyFindUsagesOptions -+ -+public class RemoveForLoopIndicesIntention : JetSelfTargetingIntention( -+ ""remove.for.loop.indices"", javaClass()) { -+ override fun applyTo(element: JetForExpression, editor: Editor) { -+ val parameter = element.getMultiParameter()!! -+ val range = element.getLoopRange() as JetDotQualifiedExpression -+ val parameters = parameter.getEntries() -+ if (parameters.size() == 2) { -+ parameter.replace(parameters[1]) -+ } else { -+ JetPsiUtil.deleteElementWithDelimiters(parameters[0]) -+ } -+ -+ range.replace(range.getReceiverExpression()) -+ } -+ -+ override fun isApplicableTo(element: JetForExpression): Boolean { -+ if (element.getMultiParameter() == null) return false -+ val range = element.getLoopRange() as? JetDotQualifiedExpression ?: return false -+ val selector = range.getSelectorExpression() ?: return false -+ if (!selector.textMatches(""withIndices()"")) return false -+ -+ val indexVar = element.getMultiParameter()!!.getEntries()[0] -+ -+ val findManager = FindManager.getInstance(element.getProject()) as FindManagerImpl -+ val findHandler = findManager.getFindUsagesManager().getFindUsagesHandler(indexVar,false) ?: return false -+ val options = KotlinPropertyFindUsagesOptions(element.getProject()) -+ val usageCount = array(0) -+ val usageFinderRunnable = object : Runnable { -+ override fun run() { -+ val processor = object : Processor { -+ override fun process(t: UsageInfo?): Boolean { -+ usageCount[0] = usageCount[0] + 1 -+ return true -+ } -+ } -+ findHandler.processElementUsages(indexVar,processor,options) -+ } -+ } -+ usageFinderRunnable.run()","I'm not sure what's the point in creating a `Runnable` and immediately running it? -",Please move intellij copyright date to the header -494,"@@ -0,0 +1,83 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetForExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression -+import org.jetbrains.jet.lang.psi.JetPsiUtil -+import org.jetbrains.jet.lang.cfg.PseudocodeVariablesData.VariableUseState -+import org.jetbrains.jet.lang.cfg.pseudocode.PseudocodeUtil -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.lang.psi.JetFile -+import org.jetbrains.jet.lang.resolve.ObservableBindingTrace -+import org.jetbrains.jet.lang.resolve.BindingTraceContext -+import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider -+import org.jetbrains.jet.lang.cfg.JetControlFlowProcessor -+import com.intellij.debugger.jdi.LocalVariablesUtil -+import com.siyeh.ig.psiutils.VariableAccessUtils -+import com.google.dart.compiler.util.AstUtil -+import com.intellij.find.FindManager -+import com.intellij.find.impl.FindManagerImpl -+import com.intellij.usageView.UsageInfo -+import com.intellij.util.Processor -+import org.jetbrains.jet.plugin.findUsages.KotlinPropertyFindUsagesOptions -+ -+public class RemoveForLoopIndicesIntention : JetSelfTargetingIntention( -+ ""remove.for.loop.indices"", javaClass()) { -+ override fun applyTo(element: JetForExpression, editor: Editor) { -+ val parameter = element.getMultiParameter()!! -+ val range = element.getLoopRange() as JetDotQualifiedExpression -+ val parameters = parameter.getEntries() -+ if (parameters.size() == 2) { -+ parameter.replace(parameters[1]) -+ } else { -+ JetPsiUtil.deleteElementWithDelimiters(parameters[0]) -+ } -+ -+ range.replace(range.getReceiverExpression()) -+ } -+ -+ override fun isApplicableTo(element: JetForExpression): Boolean { -+ if (element.getMultiParameter() == null) return false -+ val range = element.getLoopRange() as? JetDotQualifiedExpression ?: return false -+ val selector = range.getSelectorExpression() ?: return false -+ if (!selector.textMatches(""withIndices()"")) return false -+ -+ val indexVar = element.getMultiParameter()!!.getEntries()[0] -+ -+ val findManager = FindManager.getInstance(element.getProject()) as FindManagerImpl -+ val findHandler = findManager.getFindUsagesManager().getFindUsagesHandler(indexVar,false) ?: return false -+ val options = KotlinPropertyFindUsagesOptions(element.getProject()) -+ val usageCount = array(0) -+ val usageFinderRunnable = object : Runnable { -+ override fun run() { -+ val processor = object : Processor { -+ override fun process(t: UsageInfo?): Boolean { -+ usageCount[0] = usageCount[0] + 1 -+ return true -+ } -+ } -+ findHandler.processElementUsages(indexVar,processor,options) -+ } -+ } -+ usageFinderRunnable.run() -+ return usageCount[0] == 0","Similarly to the first intention, I think we should check here if `withIndices` is actually resolved to `kotlin.withIndices` (don't forget about a test) -",Please move intellij copyright date to the header -495,"@@ -0,0 +1,84 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.fileEditor.FileEditorManager; -+import com.intellij.openapi.project.Project; -+import com.intellij.openapi.vfs.VirtualFile; -+import com.intellij.psi.PsiElement; -+import com.intellij.psi.PsiFile; -+import com.intellij.psi.PsiReference; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.psi.*; -+import org.jetbrains.jet.plugin.JetBundle; -+ -+public class CreateClassObjectFromUsageFix extends CreateFromUsageFixBase { -+ private final JetClass klass; -+ -+ public CreateClassObjectFromUsageFix(@NotNull PsiElement element, @NotNull JetClass klass) { -+ super(element); -+ this.klass = klass; -+ } -+ -+ @NotNull -+ @Override -+ public String getText() { -+ return JetBundle.message(""create.class.object.from.usage""); -+ } -+ -+ @Override -+ public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { -+ PsiFile containingFile = klass.getContainingFile(); -+ VirtualFile virtualFile = containingFile.getVirtualFile(); -+ assert virtualFile != null; -+ FileEditorManager fileEditorManager = FileEditorManager.getInstance(project); -+ fileEditorManager.openFile(virtualFile, true);","This piece of code can be replaced with `NavigationUtil.activateFileWithPsiElement(klass)` -",I don't like the name of this class either. It's a bit c -496,"@@ -0,0 +1,84 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+package org.jetbrains.jet.plugin.intentions -+ -+ -+import org.jetbrains.jet.plugin.intentions.JetSelfTargetingIntention -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression -+import org.jetbrains.jet.lang.psi.JetCallExpression -+import org.jetbrains.jet.lang.psi.JetExpression -+import org.jetbrains.jet.lang.psi.JetPsiUtil -+import com.intellij.psi.PsiElement -+import org.jetbrains.jet.lang.psi.JetArrayAccessExpression -+import org.jetbrains.jet.lang.psi.ValueArgument -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetSimpleNameExpression -+ -+public class GetToSquareBracketsIntention : JetSelfTargetingIntention(""get.to.square.brackets"", javaClass()) { -+ -+ override fun isApplicableTo(element: JetCallExpression): Boolean { -+ val expression = element.getCalleeExpression() as? JetSimpleNameExpression -+ -+ if (expression?.getReferencedName() != ""get"") -+ return false -+ -+ if (element.getValueArguments().isEmpty()) -+ return false -+ -+ val arguments = element.getValueArguments()","You declare this variable here, but for some reason only use it once: in other places, you still call `element.getValueArguments()` -",Please don't do this. It's better to do `asBoolean()` rather than `asBoolean()`. -497,"@@ -0,0 +1,84 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+package org.jetbrains.jet.plugin.intentions -+ -+ -+import org.jetbrains.jet.plugin.intentions.JetSelfTargetingIntention -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression -+import org.jetbrains.jet.lang.psi.JetCallExpression -+import org.jetbrains.jet.lang.psi.JetExpression -+import org.jetbrains.jet.lang.psi.JetPsiUtil -+import com.intellij.psi.PsiElement -+import org.jetbrains.jet.lang.psi.JetArrayAccessExpression -+import org.jetbrains.jet.lang.psi.ValueArgument -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetSimpleNameExpression -+ -+public class GetToSquareBracketsIntention : JetSelfTargetingIntention(""get.to.square.brackets"", javaClass()) { -+ -+ override fun isApplicableTo(element: JetCallExpression): Boolean { -+ val expression = element.getCalleeExpression() as? JetSimpleNameExpression -+ -+ if (expression?.getReferencedName() != ""get"") -+ return false -+ -+ if (element.getValueArguments().isEmpty()) -+ return false -+ -+ val arguments = element.getValueArguments() -+ -+ for (argument in arguments) { -+ if (argument?.getArgumentExpression().equals(null))","Note that in Kotlin `==` is equivalent to `equals`. The former looks a lot more readable, so we usually prefer it over `equals` -",Please don't do this. It's better to do `asBoolean()` rather than `asBoolean()`. -498,"@@ -0,0 +1,84 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+package org.jetbrains.jet.plugin.intentions -+ -+ -+import org.jetbrains.jet.plugin.intentions.JetSelfTargetingIntention -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression -+import org.jetbrains.jet.lang.psi.JetCallExpression -+import org.jetbrains.jet.lang.psi.JetExpression -+import org.jetbrains.jet.lang.psi.JetPsiUtil -+import com.intellij.psi.PsiElement -+import org.jetbrains.jet.lang.psi.JetArrayAccessExpression -+import org.jetbrains.jet.lang.psi.ValueArgument -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetSimpleNameExpression -+ -+public class GetToSquareBracketsIntention : JetSelfTargetingIntention(""get.to.square.brackets"", javaClass()) { -+ -+ override fun isApplicableTo(element: JetCallExpression): Boolean { -+ val expression = element.getCalleeExpression() as? JetSimpleNameExpression -+ -+ if (expression?.getReferencedName() != ""get"") -+ return false -+ -+ if (element.getValueArguments().isEmpty()) -+ return false -+ -+ val arguments = element.getValueArguments() -+ -+ for (argument in arguments) { -+ if (argument?.getArgumentExpression().equals(null)) -+ return false -+ } -+ -+ if (element.getValueArguments().any() { it!!.isNamed() })","Please don't just copy-paste code without adapting it :) Here you use `any`, but a few lines earlier you use a hand-written for-loop. You should attempt to use similar constructs for similar intents: either `any` everywhere, or for-loops everywhere. You can also combine these two and save a few lines -",Please don't do this. It's better to do `asBoolean()` rather than `asBoolean()`. -499,"@@ -0,0 +1,84 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+package org.jetbrains.jet.plugin.intentions -+ -+ -+import org.jetbrains.jet.plugin.intentions.JetSelfTargetingIntention -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression -+import org.jetbrains.jet.lang.psi.JetCallExpression -+import org.jetbrains.jet.lang.psi.JetExpression -+import org.jetbrains.jet.lang.psi.JetPsiUtil -+import com.intellij.psi.PsiElement -+import org.jetbrains.jet.lang.psi.JetArrayAccessExpression -+import org.jetbrains.jet.lang.psi.ValueArgument -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetSimpleNameExpression -+ -+public class GetToSquareBracketsIntention : JetSelfTargetingIntention(""get.to.square.brackets"", javaClass()) { -+ -+ override fun isApplicableTo(element: JetCallExpression): Boolean { -+ val expression = element.getCalleeExpression() as? JetSimpleNameExpression -+ -+ if (expression?.getReferencedName() != ""get"") -+ return false -+ -+ if (element.getValueArguments().isEmpty()) -+ return false -+ -+ val arguments = element.getValueArguments() -+ -+ for (argument in arguments) { -+ if (argument?.getArgumentExpression().equals(null)) -+ return false -+ } -+ -+ if (element.getValueArguments().any() { it!!.isNamed() }) -+ return false -+ -+ return element.getTypeArguments().isEmpty() && element.getFunctionLiteralArguments().isEmpty() -+ -+ } -+ -+ override fun applyTo(element: JetCallExpression, editor: Editor) { -+ val parentElement = element.getParent() -+ val parentExpression: String? -+ -+ if (parentElement is JetDotQualifiedExpression) { -+ parentExpression = parentElement.getReceiverExpression().getText() -+ } else { -+ return","`return` in `applyTo` should give you a hint that's something's not right: your `isApplicableTo` should've already filtered out inapplicable usages and `applyTo` should only _apply_ the intention on a good code. Here it appears that your intention says that it **is applicable** to expressions other than `JetDotQualifiedExpression` (in `isApplicable`), but `applyTo` doesn't do anything on them. As a result, your intention is available on `get(0)` (without any receiver expression), but does nothing, which is not right for an intention -",Please don't do this. It's better to do `asBoolean()` rather than `asBoolean()`. -500,"@@ -0,0 +1,84 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+package org.jetbrains.jet.plugin.intentions -+ -+ -+import org.jetbrains.jet.plugin.intentions.JetSelfTargetingIntention -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression -+import org.jetbrains.jet.lang.psi.JetCallExpression -+import org.jetbrains.jet.lang.psi.JetExpression -+import org.jetbrains.jet.lang.psi.JetPsiUtil -+import com.intellij.psi.PsiElement -+import org.jetbrains.jet.lang.psi.JetArrayAccessExpression -+import org.jetbrains.jet.lang.psi.ValueArgument -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetSimpleNameExpression -+ -+public class GetToSquareBracketsIntention : JetSelfTargetingIntention(""get.to.square.brackets"", javaClass()) { -+ -+ override fun isApplicableTo(element: JetCallExpression): Boolean { -+ val expression = element.getCalleeExpression() as? JetSimpleNameExpression -+ -+ if (expression?.getReferencedName() != ""get"") -+ return false -+ -+ if (element.getValueArguments().isEmpty()) -+ return false -+ -+ val arguments = element.getValueArguments() -+ -+ for (argument in arguments) { -+ if (argument?.getArgumentExpression().equals(null)) -+ return false -+ } -+ -+ if (element.getValueArguments().any() { it!!.isNamed() }) -+ return false -+ -+ return element.getTypeArguments().isEmpty() && element.getFunctionLiteralArguments().isEmpty() -+ -+ } -+ -+ override fun applyTo(element: JetCallExpression, editor: Editor) { -+ val parentElement = element.getParent() -+ val parentExpression: String? -+ -+ if (parentElement is JetDotQualifiedExpression) { -+ parentExpression = parentElement.getReceiverExpression().getText() -+ } else { -+ return -+ } -+ var expressionString = StringBuilder() -+ expressionString.append(parentExpression) -+ expressionString.append(""["") -+ val arguments = element.getValueArguments() -+ val numberOfArguments = arguments.size()","This variable is no longer used. Please watch out for compilation warnings in your code (yellow spots on the scroll bar in IDEA) -",Please don't do this. It's better to do `asBoolean()` rather than `asBoolean()`. -501,"@@ -0,0 +1,85 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetBinaryExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetPrefixExpression -+import org.jetbrains.jet.lexer.JetTokens -+import com.intellij.psi.impl.source.tree.PsiErrorElementImpl -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetParenthesizedExpression -+import org.jetbrains.jet.lang.psi.JetPsiUtil -+ -+ -+public class ConvertNegatedBooleanSequenceIntention : JetSelfTargetingIntention( -+ ""convert.negated.boolean.sequence"", javaClass()) { -+ -+ override fun isApplicableTo(element: JetBinaryExpression): Boolean { -+ if (element.getParent() is JetBinaryExpression) return false // operate only on the longest sequence -+ var binaryExpression = element : JetBinaryExpression?","Maybe 'var binaryExpression : JetBinaryExpression? = element' would be best -",Why do we need a new class for this? -502,"@@ -0,0 +1,85 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetBinaryExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetPrefixExpression -+import org.jetbrains.jet.lexer.JetTokens -+import com.intellij.psi.impl.source.tree.PsiErrorElementImpl -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetParenthesizedExpression -+import org.jetbrains.jet.lang.psi.JetPsiUtil -+ -+ -+public class ConvertNegatedBooleanSequenceIntention : JetSelfTargetingIntention( -+ ""convert.negated.boolean.sequence"", javaClass()) { -+ -+ override fun isApplicableTo(element: JetBinaryExpression): Boolean { -+ if (element.getParent() is JetBinaryExpression) return false // operate only on the longest sequence -+ var binaryExpression = element : JetBinaryExpression? -+ val originalOperator = element.getOperationToken() -+","What about Demorgan transformation here? -",Add a license header here -503,"@@ -0,0 +1,85 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetBinaryExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetPrefixExpression -+import org.jetbrains.jet.lexer.JetTokens -+import com.intellij.psi.impl.source.tree.PsiErrorElementImpl -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetParenthesizedExpression -+import org.jetbrains.jet.lang.psi.JetPsiUtil -+ -+ -+public class ConvertNegatedBooleanSequenceIntention : JetSelfTargetingIntention( -+ ""convert.negated.boolean.sequence"", javaClass()) { -+ -+ override fun isApplicableTo(element: JetBinaryExpression): Boolean { -+ if (element.getParent() is JetBinaryExpression) return false // operate only on the longest sequence -+ var binaryExpression = element : JetBinaryExpression? -+ val originalOperator = element.getOperationToken() -+ -+ if (!(originalOperator == (JetTokens.ANDAND)) && !(originalOperator == (JetTokens.OROR))) { -+ return false -+ } -+ -+ do { -+ val leftChild = binaryExpression?.getFirstChild() -+ val rightChild = binaryExpression?.getLastChild() -+ val operator = binaryExpression?.getOperationToken() -+ when { -+ rightChild !is JetPrefixExpression, -+ rightChild is PsiErrorElementImpl,","Why you need 'rightChild is PsiErrorElementImpl' check? -",Add a do {} while loop to reduce code indentation. -504,"@@ -0,0 +1,85 @@ -+/* -+ * 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.inspections -+ -+import com.intellij.codeInspection.* -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiElement -+import com.intellij.psi.PsiElementVisitor -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.* -+import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall -+ -+class RemoveRedundantBackticksInspection : AbstractKotlinInspection() { -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { -+ return object : KtVisitorVoid() { -+ override fun visitProperty(property: KtProperty) {","This still handles only a random subset of PSI elements. The correct way to handle this is to override `visitKtElement` and to look for all children with element type `KtTokens.IDENTIFIER`, similar to how it's done [here](https://github.com/JetBrains/intellij-community/blob/b6dcce52194f52c921c414b7ccc01dbb3363cc7d/platform/core-impl/src/com/intellij/extapi/psi/ASTDelegatePsiElement.java#L230)","The package name is wrong, this should be called `RemoveRedundantBackticksInspec" -505,"@@ -0,0 +1,85 @@ -+/* -+ * 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.inspections -+ -+import com.intellij.codeInspection.* -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiElement -+import com.intellij.psi.PsiElementVisitor -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.* -+import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall -+ -+class RemoveRedundantBackticksInspection : AbstractKotlinInspection() { -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { -+ return object : KtVisitorVoid() { -+ override fun visitProperty(property: KtProperty) { -+ super.visitProperty(property) -+ val nameIdentifier = property.nameIdentifier ?: return -+ if (isRedundantBackticks(nameIdentifier)) { -+ registerProblem(holder, nameIdentifier) -+ } -+ } -+ -+ override fun visitNamedFunction(function: KtNamedFunction) { -+ super.visitNamedFunction(function) -+ function.valueParameters.map { -+ val nameIdentifier = it.nameIdentifier ?: return@map -+ if (isRedundantBackticks(nameIdentifier)) { -+ registerProblem(holder, nameIdentifier) -+ } -+ } -+ } -+ -+ override fun visitReferenceExpression(expression: KtReferenceExpression) { -+ super.visitReferenceExpression(expression) -+ val bindingContext = expression.analyze() -+ expression.getResolvedCall(bindingContext) ?: return -+ if (isRedundantBackticks(expression)) { -+ registerProblem(holder, expression) -+ } -+ } -+ } -+ } -+ -+ private fun isKeyword(text: String): Boolean {",Backticks can also be used to enclose identifiers containing spaces and other characters not allowed in Java identifiers. In this case they must not be highlighted as redundant.,Remove this line -506,"@@ -0,0 +1,85 @@ -+/* -+ * 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.inspections -+ -+import com.intellij.codeInspection.* -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiElement -+import com.intellij.psi.PsiElementVisitor -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.* -+import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall -+ -+class RemoveRedundantBackticksInspection : AbstractKotlinInspection() { -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { -+ return object : KtVisitorVoid() { -+ override fun visitProperty(property: KtProperty) { -+ super.visitProperty(property) -+ val nameIdentifier = property.nameIdentifier ?: return -+ if (isRedundantBackticks(nameIdentifier)) { -+ registerProblem(holder, nameIdentifier) -+ } -+ } -+ -+ override fun visitNamedFunction(function: KtNamedFunction) { -+ super.visitNamedFunction(function) -+ function.valueParameters.map { -+ val nameIdentifier = it.nameIdentifier ?: return@map -+ if (isRedundantBackticks(nameIdentifier)) { -+ registerProblem(holder, nameIdentifier) -+ } -+ } -+ } -+ -+ override fun visitReferenceExpression(expression: KtReferenceExpression) { -+ super.visitReferenceExpression(expression) -+ val bindingContext = expression.analyze() -+ expression.getResolvedCall(bindingContext) ?: return -+ if (isRedundantBackticks(expression)) { -+ registerProblem(holder, expression) -+ } -+ } -+ } -+ } -+ -+ private fun isKeyword(text: String): Boolean { -+ return (KtTokens.KEYWORDS.types + KtTokens.SOFT_KEYWORDS.types).any { it.toString() == text } -+ } -+ -+ private fun isRedundantBackticks(element: PsiElement): Boolean { -+ return (element.text.contains(""^`.+`$"".toRegex()) &&",Please don't use regular expressions here. Use `startsWith` and `endsWith`.,Remove this line -507,"@@ -0,0 +1,85 @@ -+/* -+ * 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.inspections -+ -+import com.intellij.codeInspection.* -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiElement -+import com.intellij.psi.PsiElementVisitor -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.* -+import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall -+ -+class RemoveRedundantBackticksInspection : AbstractKotlinInspection() { -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { -+ return object : KtVisitorVoid() { -+ override fun visitProperty(property: KtProperty) { -+ super.visitProperty(property) -+ val nameIdentifier = property.nameIdentifier ?: return -+ if (isRedundantBackticks(nameIdentifier)) { -+ registerProblem(holder, nameIdentifier) -+ } -+ } -+ -+ override fun visitNamedFunction(function: KtNamedFunction) { -+ super.visitNamedFunction(function) -+ function.valueParameters.map { -+ val nameIdentifier = it.nameIdentifier ?: return@map -+ if (isRedundantBackticks(nameIdentifier)) { -+ registerProblem(holder, nameIdentifier) -+ } -+ } -+ } -+ -+ override fun visitReferenceExpression(expression: KtReferenceExpression) { -+ super.visitReferenceExpression(expression) -+ val bindingContext = expression.analyze() -+ expression.getResolvedCall(bindingContext) ?: return -+ if (isRedundantBackticks(expression)) { -+ registerProblem(holder, expression) -+ } -+ } -+ } -+ } -+ -+ private fun isKeyword(text: String): Boolean { -+ return (KtTokens.KEYWORDS.types + KtTokens.SOFT_KEYWORDS.types).any { it.toString() == text } -+ } -+ -+ private fun isRedundantBackticks(element: PsiElement): Boolean { -+ return (element.text.contains(""^`.+`$"".toRegex()) && -+ !isKeyword(element.text.removePrefix(""`"").removeSuffix(""`""))) -+ } -+ -+ private fun registerProblem(holder: ProblemsHolder, element: PsiElement) { -+ holder.registerProblem(element, -+ ""Remove redundant backticks"", -+ ProblemHighlightType.GENERIC_ERROR_OR_WARNING, -+ RemoveRedundantBackticksQuickFix()) -+ } -+} -+ -+class RemoveRedundantBackticksQuickFix : LocalQuickFix { -+ override fun getName() = ""Remove redundant backticks"" -+ override fun getFamilyName() = name -+ -+ override fun applyFix(project: Project, descriptor: ProblemDescriptor) { -+ val element = descriptor.psiElement -+ val factory = KtPsiFactory(project) -+ element.replace(factory.createExpression(element.text.removePrefix(""`"").removeSuffix(""`"")))","If you replace an arbitrary element in a PSI tree (such as the name identifier of a property) with an expression, this will create an invalid PSI structure and will break other code insight features until the file contents is reparsed. You need to always replace an element with another element of the same type (in this case, an identifier with an identifier). Use `KtPsiFactory.createIdentifier()`.",Remove this line -508,"@@ -0,0 +1,87 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.project.Project; -+import com.intellij.psi.PsiFile; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1; -+import org.jetbrains.jet.lang.psi.JetParameter; -+import org.jetbrains.jet.lang.psi.JetPsiFactory; -+import org.jetbrains.jet.lang.psi.JetTypeReference; -+import org.jetbrains.jet.lang.types.JetType; -+import org.jetbrains.jet.plugin.JetBundle; -+ -+public class ChangeTypeFix extends JetIntentionAction { -+ private JetType type;","Field may be 'final' -",Please add a license to the top of all new files -509,"@@ -0,0 +1,87 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.project.Project; -+import com.intellij.psi.PsiFile; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1; -+import org.jetbrains.jet.lang.psi.JetParameter; -+import org.jetbrains.jet.lang.psi.JetPsiFactory; -+import org.jetbrains.jet.lang.psi.JetTypeReference; -+import org.jetbrains.jet.lang.types.JetType; -+import org.jetbrains.jet.plugin.JetBundle; -+ -+public class ChangeTypeFix extends JetIntentionAction { -+ private JetType type; -+ -+ public ChangeTypeFix(@NotNull JetTypeReference element, JetType type) { -+ super(element); -+ this.type = type; -+ } -+ -+ @NotNull -+ @Override -+ public String getText() { -+ return JetBundle.message(""change.type"", element.getText(), type); -+ } -+ -+ @NotNull -+ @Override -+ public String getFamilyName() { -+ return JetBundle.message(""change.type.family""); -+ } -+ -+ @Override -+ public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { -+ element.replace(JetPsiFactory.createType(project, type.toString())); -+ } -+ -+ @NotNull -+ public static JetIntentionActionFactory createFactoryForExpectedParameterTypeMismatch() { -+ return new JetIntentionActionFactory() { -+ @Nullable -+ @Override -+ public IntentionAction createAction(Diagnostic diagnostic) { -+ JetParameter property = QuickFixUtil.getParentElementOfType(diagnostic, JetParameter.class);","Add please checking for diagnostic factory. Look like line 91 in `idea/src/org/jetbrains/jet/plugin/quickfix/AddStarProjectionsFix.java` -",I don't like the name of this class because it has nothing to do with a type fix -510,"@@ -0,0 +1,87 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.project.Project; -+import com.intellij.psi.PsiFile; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1; -+import org.jetbrains.jet.lang.psi.JetParameter; -+import org.jetbrains.jet.lang.psi.JetPsiFactory; -+import org.jetbrains.jet.lang.psi.JetTypeReference; -+import org.jetbrains.jet.lang.types.JetType; -+import org.jetbrains.jet.plugin.JetBundle; -+ -+public class ChangeTypeFix extends JetIntentionAction { -+ private JetType type; -+ -+ public ChangeTypeFix(@NotNull JetTypeReference element, JetType type) { -+ super(element); -+ this.type = type; -+ } -+ -+ @NotNull -+ @Override -+ public String getText() { -+ return JetBundle.message(""change.type"", element.getText(), type); -+ } -+ -+ @NotNull -+ @Override -+ public String getFamilyName() { -+ return JetBundle.message(""change.type.family""); -+ } -+ -+ @Override -+ public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { -+ element.replace(JetPsiFactory.createType(project, type.toString())); -+ } -+ -+ @NotNull -+ public static JetIntentionActionFactory createFactoryForExpectedParameterTypeMismatch() { -+ return new JetIntentionActionFactory() { -+ @Nullable -+ @Override -+ public IntentionAction createAction(Diagnostic diagnostic) { -+ JetParameter property = QuickFixUtil.getParentElementOfType(diagnostic, JetParameter.class); -+ assert property != null : ""EXPECTED_PARAMETER_TYPE_MISMATCH reported on element that is not within any property""; -+ JetTypeReference typeReference = property.getTypeReference(); -+ JetType type = ((DiagnosticWithParameters1) diagnostic).getA();","Use SuppressWarnings, please, like line 92-95 in `idea/src/org/jetbrains/jet/plugin/quickfix/AddStarProjectionsFix.java` -",I don't like the name of this class because it has nothing to do with a type fix -511,"@@ -0,0 +1,87 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.project.Project; -+import com.intellij.psi.PsiFile; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1; -+import org.jetbrains.jet.lang.psi.JetParameter; -+import org.jetbrains.jet.lang.psi.JetPsiFactory; -+import org.jetbrains.jet.lang.psi.JetTypeReference; -+import org.jetbrains.jet.lang.types.JetType; -+import org.jetbrains.jet.plugin.JetBundle; -+ -+public class ChangeTypeFix extends JetIntentionAction { -+ private JetType type; -+ -+ public ChangeTypeFix(@NotNull JetTypeReference element, JetType type) { -+ super(element); -+ this.type = type; -+ } -+ -+ @NotNull -+ @Override -+ public String getText() { -+ return JetBundle.message(""change.type"", element.getText(), type); -+ } -+ -+ @NotNull -+ @Override -+ public String getFamilyName() { -+ return JetBundle.message(""change.type.family""); -+ } -+ -+ @Override -+ public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { -+ element.replace(JetPsiFactory.createType(project, type.toString())); -+ } -+ -+ @NotNull -+ public static JetIntentionActionFactory createFactoryForExpectedParameterTypeMismatch() { -+ return new JetIntentionActionFactory() { -+ @Nullable -+ @Override -+ public IntentionAction createAction(Diagnostic diagnostic) { -+ JetParameter property = QuickFixUtil.getParentElementOfType(diagnostic, JetParameter.class); -+ assert property != null : ""EXPECTED_PARAMETER_TYPE_MISMATCH reported on element that is not within any property""; -+ JetTypeReference typeReference = property.getTypeReference(); -+ JetType type = ((DiagnosticWithParameters1) diagnostic).getA(); -+ return typeReference == null ? null : new ChangeTypeFix(typeReference, type);","Maybe `typeReference == null` should be just `assert` -",I don't like the name of this class because it has nothing to do with a type fix -512,"@@ -0,0 +1,87 @@ -+/* -+ * Copyright 2010-2013 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.quickfix; -+ -+import com.intellij.codeInsight.intention.IntentionAction; -+import com.intellij.openapi.editor.Editor; -+import com.intellij.openapi.project.Project; -+import com.intellij.psi.PsiFile; -+import com.intellij.util.IncorrectOperationException; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.jetbrains.jet.lang.diagnostics.Diagnostic; -+import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1; -+import org.jetbrains.jet.lang.psi.JetParameter; -+import org.jetbrains.jet.lang.psi.JetPsiFactory; -+import org.jetbrains.jet.lang.psi.JetTypeReference; -+import org.jetbrains.jet.lang.types.JetType; -+import org.jetbrains.jet.plugin.JetBundle; -+ -+public class ChangeTypeFix extends JetIntentionAction { -+ private JetType type; -+ -+ public ChangeTypeFix(@NotNull JetTypeReference element, JetType type) { -+ super(element); -+ this.type = type; -+ } -+ -+ @NotNull -+ @Override -+ public String getText() { -+ return JetBundle.message(""change.type"", element.getText(), type); -+ } -+ -+ @NotNull -+ @Override -+ public String getFamilyName() { -+ return JetBundle.message(""change.type.family""); -+ } -+ -+ @Override -+ public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { -+ element.replace(JetPsiFactory.createType(project, type.toString())); -+ } -+ -+ @NotNull -+ public static JetIntentionActionFactory createFactoryForExpectedParameterTypeMismatch() { -+ return new JetIntentionActionFactory() { -+ @Nullable -+ @Override -+ public IntentionAction createAction(Diagnostic diagnostic) { -+ JetParameter property = QuickFixUtil.getParentElementOfType(diagnostic, JetParameter.class); -+ assert property != null : ""EXPECTED_PARAMETER_TYPE_MISMATCH reported on element that is not within any property""; -+ JetTypeReference typeReference = property.getTypeReference(); -+ JetType type = ((DiagnosticWithParameters1) diagnostic).getA(); -+ return typeReference == null ? null : new ChangeTypeFix(typeReference, type); -+ } -+ }; -+ } -+ -+ @NotNull -+ public static JetIntentionActionFactory createFactoryForExpectedReturnTypeMismatch() { -+ return new JetIntentionActionFactory() { -+ @Nullable -+ @Override -+ public IntentionAction createAction(Diagnostic diagnostic) { -+ JetTypeReference typeReference = QuickFixUtil.getParentElementOfType(diagnostic, JetTypeReference.class); -+ assert typeReference != null : ""EXPECTED_RETURN_TYPE_MISMATCH reported on element that is not a type reference""; -+ JetType type = ((DiagnosticWithParameters1) diagnostic).getA();","Use SuppressWarnings, please. -",I don't like the name of this class because it has nothing to do with a type fix. ChangeTypeFix seems like a generic name. -513,"@@ -0,0 +1,87 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetForExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression -+import com.intellij.psi.util.PsiTreeUtil -+import com.intellij.psi.PsiDocumentManager -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.di.InjectorForMacros -+import org.jetbrains.jet.lang.resolve.BindingContext -+import org.jetbrains.jet.lang.types.TypeUtils -+import org.jetbrains.jet.lang.resolve.ObservableBindingTrace -+import org.jetbrains.jet.lang.resolve.BindingTraceContext -+import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo -+import org.jetbrains.jet.lang.psi.JetParenthesizedExpression -+import com.intellij.codeInsight.template.TemplateBuilderImpl -+import com.intellij.codeInsight.template.impl.TemplateManagerImpl -+import org.jetbrains.jet.lang.resolve.DescriptorUtils -+import org.jetbrains.jet.lang.descriptors.ModuleDescriptor -+ -+ -+public class AddForLoopIndicesIntention : JetSelfTargetingIntention( -+ ""add.for.loop.indices"", javaClass()) { -+ override fun applyTo(element: JetForExpression, editor: Editor) { -+ val loopRange = element.getLoopRange()!! -+ val newRangeText = ""${loopRange.getText()}.withIndices()"" -+ val newRange = JetPsiFactory.createExpression(editor.getProject(), newRangeText) -+ -+ //Roundabout way to create new multiparameter element so as not to incorrectly trigger syntax error highlighting -+ val loopParameter = element.getLoopParameter()!! -+ val parenthesizedParam = JetPsiFactory.createExpression(editor.getProject(), ""(index)"") as JetParenthesizedExpression -+ val indexElement = parenthesizedParam.getExpression()!! -+ val comma = JetPsiFactory.createComma(editor.getProject()) -+ val newParamElement = JetPsiFactory.createExpression(editor.getProject(), "" ${loopParameter.getText()}"") -+ parenthesizedParam.addAfter(newParamElement, indexElement) -+ parenthesizedParam.addAfter(comma, indexElement) -+ -+ loopParameter.replace(parenthesizedParam) -+ loopRange.replace(newRange) -+ -+ val multiParameter = PsiTreeUtil.findChildOfType(element, indexElement.javaClass)!! -+ -+ editor.getCaretModel().moveToOffset(multiParameter.getTextOffset()) -+ val templateBuilder = TemplateBuilderImpl(multiParameter) -+ templateBuilder.replaceElement(multiParameter, ""index"") -+ val manager = TemplateManagerImpl(editor.getProject()) -+ PsiDocumentManager.getInstance(editor.getProject()!!).doPostponedOperationsAndUnblockDocument(editor.getDocument()) -+ manager.startTemplate(editor, templateBuilder.buildInlineTemplate()!!) -+ } -+ -+ override fun isApplicableTo(element: JetForExpression): Boolean { -+ if (element.getLoopParameter() == null) return false -+ val range = element.getLoopRange() ?: return false -+ if (range is JetDotQualifiedExpression) { -+ val selector = (range as JetDotQualifiedExpression).getSelectorExpression() ?: return true","You don't need this cast (experience the power of Kotlin) -",Please remove intellij copyright header -514,"@@ -0,0 +1,87 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetForExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression -+import com.intellij.psi.util.PsiTreeUtil -+import com.intellij.psi.PsiDocumentManager -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.di.InjectorForMacros -+import org.jetbrains.jet.lang.resolve.BindingContext -+import org.jetbrains.jet.lang.types.TypeUtils -+import org.jetbrains.jet.lang.resolve.ObservableBindingTrace -+import org.jetbrains.jet.lang.resolve.BindingTraceContext -+import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo -+import org.jetbrains.jet.lang.psi.JetParenthesizedExpression -+import com.intellij.codeInsight.template.TemplateBuilderImpl -+import com.intellij.codeInsight.template.impl.TemplateManagerImpl -+import org.jetbrains.jet.lang.resolve.DescriptorUtils -+import org.jetbrains.jet.lang.descriptors.ModuleDescriptor -+ -+ -+public class AddForLoopIndicesIntention : JetSelfTargetingIntention( -+ ""add.for.loop.indices"", javaClass()) { -+ override fun applyTo(element: JetForExpression, editor: Editor) { -+ val loopRange = element.getLoopRange()!! -+ val newRangeText = ""${loopRange.getText()}.withIndices()"" -+ val newRange = JetPsiFactory.createExpression(editor.getProject(), newRangeText) -+ -+ //Roundabout way to create new multiparameter element so as not to incorrectly trigger syntax error highlighting -+ val loopParameter = element.getLoopParameter()!! -+ val parenthesizedParam = JetPsiFactory.createExpression(editor.getProject(), ""(index)"") as JetParenthesizedExpression -+ val indexElement = parenthesizedParam.getExpression()!! -+ val comma = JetPsiFactory.createComma(editor.getProject()) -+ val newParamElement = JetPsiFactory.createExpression(editor.getProject(), "" ${loopParameter.getText()}"") -+ parenthesizedParam.addAfter(newParamElement, indexElement) -+ parenthesizedParam.addAfter(comma, indexElement) -+ -+ loopParameter.replace(parenthesizedParam) -+ loopRange.replace(newRange) -+ -+ val multiParameter = PsiTreeUtil.findChildOfType(element, indexElement.javaClass)!! -+ -+ editor.getCaretModel().moveToOffset(multiParameter.getTextOffset()) -+ val templateBuilder = TemplateBuilderImpl(multiParameter) -+ templateBuilder.replaceElement(multiParameter, ""index"") -+ val manager = TemplateManagerImpl(editor.getProject()) -+ PsiDocumentManager.getInstance(editor.getProject()!!).doPostponedOperationsAndUnblockDocument(editor.getDocument()) -+ manager.startTemplate(editor, templateBuilder.buildInlineTemplate()!!) -+ } -+ -+ override fun isApplicableTo(element: JetForExpression): Boolean { -+ if (element.getLoopParameter() == null) return false -+ val range = element.getLoopRange() ?: return false -+ if (range is JetDotQualifiedExpression) { -+ val selector = (range as JetDotQualifiedExpression).getSelectorExpression() ?: return true -+ if (selector.getText().equals(""withIndices()"")) return false","Please use `==` instead of `equals` in Kotlin code -",Please remove intellij copyright header -515,"@@ -0,0 +1,87 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetForExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression -+import com.intellij.psi.util.PsiTreeUtil -+import com.intellij.psi.PsiDocumentManager -+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache -+import org.jetbrains.jet.di.InjectorForMacros -+import org.jetbrains.jet.lang.resolve.BindingContext -+import org.jetbrains.jet.lang.types.TypeUtils -+import org.jetbrains.jet.lang.resolve.ObservableBindingTrace -+import org.jetbrains.jet.lang.resolve.BindingTraceContext -+import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo -+import org.jetbrains.jet.lang.psi.JetParenthesizedExpression -+import com.intellij.codeInsight.template.TemplateBuilderImpl -+import com.intellij.codeInsight.template.impl.TemplateManagerImpl -+import org.jetbrains.jet.lang.resolve.DescriptorUtils -+import org.jetbrains.jet.lang.descriptors.ModuleDescriptor -+ -+ -+public class AddForLoopIndicesIntention : JetSelfTargetingIntention( -+ ""add.for.loop.indices"", javaClass()) { -+ override fun applyTo(element: JetForExpression, editor: Editor) { -+ val loopRange = element.getLoopRange()!! -+ val newRangeText = ""${loopRange.getText()}.withIndices()"" -+ val newRange = JetPsiFactory.createExpression(editor.getProject(), newRangeText) -+ -+ //Roundabout way to create new multiparameter element so as not to incorrectly trigger syntax error highlighting -+ val loopParameter = element.getLoopParameter()!! -+ val parenthesizedParam = JetPsiFactory.createExpression(editor.getProject(), ""(index)"") as JetParenthesizedExpression -+ val indexElement = parenthesizedParam.getExpression()!! -+ val comma = JetPsiFactory.createComma(editor.getProject()) -+ val newParamElement = JetPsiFactory.createExpression(editor.getProject(), "" ${loopParameter.getText()}"") -+ parenthesizedParam.addAfter(newParamElement, indexElement) -+ parenthesizedParam.addAfter(comma, indexElement) -+ -+ loopParameter.replace(parenthesizedParam) -+ loopRange.replace(newRange) -+ -+ val multiParameter = PsiTreeUtil.findChildOfType(element, indexElement.javaClass)!! -+ -+ editor.getCaretModel().moveToOffset(multiParameter.getTextOffset()) -+ val templateBuilder = TemplateBuilderImpl(multiParameter) -+ templateBuilder.replaceElement(multiParameter, ""index"") -+ val manager = TemplateManagerImpl(editor.getProject()) -+ PsiDocumentManager.getInstance(editor.getProject()!!).doPostponedOperationsAndUnblockDocument(editor.getDocument()) -+ manager.startTemplate(editor, templateBuilder.buildInlineTemplate()!!) -+ } -+ -+ override fun isApplicableTo(element: JetForExpression): Boolean { -+ if (element.getLoopParameter() == null) return false -+ val range = element.getLoopRange() ?: return false -+ if (range is JetDotQualifiedExpression) { -+ val selector = (range as JetDotQualifiedExpression).getSelectorExpression() ?: return true -+ if (selector.getText().equals(""withIndices()"")) return false -+ } -+ -+ val potentialExpression = JetPsiFactory.createExpression(element.getProject(), ""${range.getText()}.withIndices()"") -+ val bindingContext = AnalyzerFacadeWithCache.getContextForElement(element) -+ val scope = bindingContext[BindingContext.RESOLUTION_SCOPE, element] ?: return false -+ val module = DescriptorUtils.getParentOfType(scope.getContainingDeclaration(), javaClass())!! -+ val components = InjectorForMacros(element.getProject(), module) -+ val dataFlowInfo = bindingContext[BindingContext.NON_DEFAULT_EXPRESSION_DATA_FLOW, element] ?: DataFlowInfo.EMPTY -+ val bindingTrace = ObservableBindingTrace(BindingTraceContext()) -+ val expressionType = components.getExpressionTypingServices()!!.getTypeInfo(scope, potentialExpression, TypeUtils.NO_EXPECTED_TYPE, dataFlowInfo, bindingTrace) -+ return expressionType.getType() != null","Do you allow to use the intention only if the resulting code will be green? In that case, I'm not sure what's wrong, but it's still applicable whenever there are errors in the initial code, e.g. - -``` -fun foo() { - for (a in b) { // <-- still applicable here, although 'b' is unresolved - } -} -``` -",Please remove intellij copyright header -516,"@@ -0,0 +1,89 @@ -+/* -+ * 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.inspections -+ -+import com.intellij.codeInsight.FileModificationService -+import com.intellij.codeInspection.* -+import com.intellij.openapi.project.Project -+import com.intellij.openapi.util.TextRange -+import com.intellij.psi.PsiElementVisitor -+import com.intellij.psi.impl.source.tree.LeafPsiElement -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.idea.core.replaced -+import org.jetbrains.kotlin.idea.imports.importableFqName -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.KtBinaryExpression -+import org.jetbrains.kotlin.psi.KtConstantExpression -+import org.jetbrains.kotlin.psi.KtVisitorVoid -+import org.jetbrains.kotlin.psi.psiUtil.endOffset -+import org.jetbrains.kotlin.psi.psiUtil.startOffset -+import org.jetbrains.kotlin.resolve.BindingContext -+import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall -+ -+class RedundantProgressionStepInspection : AbstractKotlinInspection() { -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor { -+ return object : KtVisitorVoid() { -+ override fun visitBinaryExpression(expression: KtBinaryExpression) { -+ if (isStepOneCall(expression)) { -+ holder.registerProblem(expression, -+ ""Iteration step is redundant. Recommended to remove it."",","No need to say ""Recommended..."" in the problem description; ""redundant"" implies that already.",Why not use the package name `JetBrains.idea.unresolved.ResolvedCall`? -517,"@@ -0,0 +1,89 @@ -+/* -+ * 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.inspections -+ -+import com.intellij.codeInsight.FileModificationService -+import com.intellij.codeInspection.* -+import com.intellij.openapi.project.Project -+import com.intellij.openapi.util.TextRange -+import com.intellij.psi.PsiElementVisitor -+import com.intellij.psi.impl.source.tree.LeafPsiElement -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.idea.core.replaced -+import org.jetbrains.kotlin.idea.imports.importableFqName -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.KtBinaryExpression -+import org.jetbrains.kotlin.psi.KtConstantExpression -+import org.jetbrains.kotlin.psi.KtVisitorVoid -+import org.jetbrains.kotlin.psi.psiUtil.endOffset -+import org.jetbrains.kotlin.psi.psiUtil.startOffset -+import org.jetbrains.kotlin.resolve.BindingContext -+import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall -+ -+class RedundantProgressionStepInspection : AbstractKotlinInspection() { -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor { -+ return object : KtVisitorVoid() { -+ override fun visitBinaryExpression(expression: KtBinaryExpression) { -+ if (isStepOneCall(expression)) { -+ holder.registerProblem(expression, -+ ""Iteration step is redundant. Recommended to remove it."", -+ ProblemHighlightType.WEAK_WARNING, -+ TextRange(expression.operationReference.startOffsetInParent, expression.endOffset - expression.startOffset), -+ EliminateStepOneFix()) -+ } -+ } -+ } -+ } -+ -+ -+ class EliminateStepOneFix : LocalQuickFix { -+ override fun getName() = ""Eliminate redundant iteration step size"" -+ -+ override fun getFamilyName() = name -+ -+ override fun applyFix(project: Project, descriptor: ProblemDescriptor) { -+ if (!FileModificationService.getInstance().preparePsiElementForWrite(descriptor.psiElement)) return -+ val expression = descriptor.psiElement as? KtBinaryExpression ?: return","This only handles ""step"" called as an infix function; would be better to handle regular ""step"" calls too.",Why not use the package name `JetBrains.idea.unresolved.ResolvedCall`? -518,"@@ -0,0 +1,89 @@ -+/* -+ * 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.inspections -+ -+import com.intellij.codeInsight.FileModificationService -+import com.intellij.codeInspection.* -+import com.intellij.openapi.project.Project -+import com.intellij.openapi.util.TextRange -+import com.intellij.psi.PsiElementVisitor -+import com.intellij.psi.impl.source.tree.LeafPsiElement -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.idea.core.replaced -+import org.jetbrains.kotlin.idea.imports.importableFqName -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.KtBinaryExpression -+import org.jetbrains.kotlin.psi.KtConstantExpression -+import org.jetbrains.kotlin.psi.KtVisitorVoid -+import org.jetbrains.kotlin.psi.psiUtil.endOffset -+import org.jetbrains.kotlin.psi.psiUtil.startOffset -+import org.jetbrains.kotlin.resolve.BindingContext -+import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall -+ -+class RedundantProgressionStepInspection : AbstractKotlinInspection() { -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor { -+ return object : KtVisitorVoid() { -+ override fun visitBinaryExpression(expression: KtBinaryExpression) { -+ if (isStepOneCall(expression)) { -+ holder.registerProblem(expression, -+ ""Iteration step is redundant. Recommended to remove it."", -+ ProblemHighlightType.WEAK_WARNING, -+ TextRange(expression.operationReference.startOffsetInParent, expression.endOffset - expression.startOffset), -+ EliminateStepOneFix()) -+ } -+ } -+ } -+ } -+ -+ -+ class EliminateStepOneFix : LocalQuickFix { -+ override fun getName() = ""Eliminate redundant iteration step size"" -+ -+ override fun getFamilyName() = name -+ -+ override fun applyFix(project: Project, descriptor: ProblemDescriptor) { -+ if (!FileModificationService.getInstance().preparePsiElementForWrite(descriptor.psiElement)) return -+ val expression = descriptor.psiElement as? KtBinaryExpression ?: return -+ if (!isStepOneCall(expression)) return -+ expression.replaced(expression.left!!) -+ } -+ } -+ -+ companion object { -+ private val STEP_FUNCTION_FQ_NAME = ""kotlin.ranges.step"" -+ -+ fun isStepOneCall(expression: KtBinaryExpression): Boolean { -+ val left = expression.left as? KtBinaryExpression ?: return false",You should use KtPsiUtil.deparenthesize() to handle the case when the range expression is in parentheses.,Why not use the package name `JetBrains.idea.unresolved.ResolvedCall`? -519,"@@ -0,0 +1,89 @@ -+/* -+ * 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.inspections -+ -+import com.intellij.codeInsight.FileModificationService -+import com.intellij.codeInspection.* -+import com.intellij.openapi.project.Project -+import com.intellij.openapi.util.TextRange -+import com.intellij.psi.PsiElementVisitor -+import com.intellij.psi.impl.source.tree.LeafPsiElement -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.idea.core.replaced -+import org.jetbrains.kotlin.idea.imports.importableFqName -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.KtBinaryExpression -+import org.jetbrains.kotlin.psi.KtConstantExpression -+import org.jetbrains.kotlin.psi.KtVisitorVoid -+import org.jetbrains.kotlin.psi.psiUtil.endOffset -+import org.jetbrains.kotlin.psi.psiUtil.startOffset -+import org.jetbrains.kotlin.resolve.BindingContext -+import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall -+ -+class RedundantProgressionStepInspection : AbstractKotlinInspection() { -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor { -+ return object : KtVisitorVoid() { -+ override fun visitBinaryExpression(expression: KtBinaryExpression) { -+ if (isStepOneCall(expression)) { -+ holder.registerProblem(expression, -+ ""Iteration step is redundant. Recommended to remove it."", -+ ProblemHighlightType.WEAK_WARNING, -+ TextRange(expression.operationReference.startOffsetInParent, expression.endOffset - expression.startOffset), -+ EliminateStepOneFix()) -+ } -+ } -+ } -+ } -+ -+ -+ class EliminateStepOneFix : LocalQuickFix { -+ override fun getName() = ""Eliminate redundant iteration step size"" -+ -+ override fun getFamilyName() = name -+ -+ override fun applyFix(project: Project, descriptor: ProblemDescriptor) { -+ if (!FileModificationService.getInstance().preparePsiElementForWrite(descriptor.psiElement)) return -+ val expression = descriptor.psiElement as? KtBinaryExpression ?: return -+ if (!isStepOneCall(expression)) return -+ expression.replaced(expression.left!!) -+ } -+ } -+ -+ companion object { -+ private val STEP_FUNCTION_FQ_NAME = ""kotlin.ranges.step"" -+ -+ fun isStepOneCall(expression: KtBinaryExpression): Boolean { -+ val left = expression.left as? KtBinaryExpression ?: return false -+ if (left.operationToken != KtTokens.RANGE) return false -+ if (expression.operationReference.text != ""step"") return false -+ val right = expression.right as? KtConstantExpression ?: return false -+ val rightConst = right.firstChild as? LeafPsiElement ?: return false -+ if (rightConst.elementType != KtTokens.INTEGER_LITERAL) return false -+ -+ if (rightConst.text !in setOf(""1"", ""1L"")) return false",Please use ConstantExpressionEvaluator.getConstant() instead.,Why not use the package name `JetBrains.idea.unresolved.ResolvedCall`? -520,"@@ -0,0 +1,89 @@ -+/* -+ * 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.inspections -+ -+import com.intellij.codeInsight.FileModificationService -+import com.intellij.codeInspection.LocalQuickFix -+import com.intellij.codeInspection.ProblemDescriptor -+import com.intellij.codeInspection.ProblemHighlightType -+import com.intellij.codeInspection.ProblemsHolder -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiElementVisitor -+import com.intellij.psi.search.LocalSearchScope -+import com.intellij.psi.search.searches.ReferencesSearch -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.* -+import org.jetbrains.kotlin.psi.addRemoveModifier.addModifier -+import org.jetbrains.kotlin.psi.psiUtil.getParentOfType -+import org.jetbrains.kotlin.psi.psiUtil.isInheritable -+import org.jetbrains.kotlin.psi.psiUtil.isOverridable -+ -+class MemberVisibilityCanPrivateInspection : AbstractKotlinInspection() { -+ -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { -+ return object : KtVisitorVoid() { -+ override fun visitProperty(property: KtProperty) {","This should check val/var parameters defined in the primary constructor, too (KtParameter)","I don't like the name of this class. In my opinion, it should be named `MemberVisibilityCanPrivateInspection`." -521,"@@ -0,0 +1,89 @@ -+/* -+ * 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.inspections -+ -+import com.intellij.codeInsight.FileModificationService -+import com.intellij.codeInspection.LocalQuickFix -+import com.intellij.codeInspection.ProblemDescriptor -+import com.intellij.codeInspection.ProblemHighlightType -+import com.intellij.codeInspection.ProblemsHolder -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiElementVisitor -+import com.intellij.psi.search.LocalSearchScope -+import com.intellij.psi.search.searches.ReferencesSearch -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.* -+import org.jetbrains.kotlin.psi.addRemoveModifier.addModifier -+import org.jetbrains.kotlin.psi.psiUtil.getParentOfType -+import org.jetbrains.kotlin.psi.psiUtil.isInheritable -+import org.jetbrains.kotlin.psi.psiUtil.isOverridable -+ -+class MemberVisibilityCanPrivateInspection : AbstractKotlinInspection() { -+ -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { -+ return object : KtVisitorVoid() { -+ override fun visitProperty(property: KtProperty) { -+ super.visitProperty(property) -+ if (canBePrivate(property)) { -+ registerProblem(holder, property) -+ } -+ } -+ -+ override fun visitNamedFunction(function: KtNamedFunction) { -+ super.visitNamedFunction(function) -+ if (canBePrivate(function)) { -+ registerProblem(holder, function) -+ } -+ } -+ } -+ } -+ -+ -+ private fun canBePrivate(declaration: KtDeclaration): Boolean { -+ val modifiers = declaration.modifierList -+ if (modifiers != null && (modifiers.hasModifier(KtTokens.PRIVATE_KEYWORD) || modifiers.hasModifier(KtTokens.OVERRIDE_KEYWORD))) return false",You can use `declaration.hasModifier()` directly,"I don't like the name of this class. In my opinion, it should be named `MemberVisibilityCanPrivateInspection`." -522,"@@ -0,0 +1,89 @@ -+/* -+ * 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.inspections -+ -+import com.intellij.codeInsight.FileModificationService -+import com.intellij.codeInspection.LocalQuickFix -+import com.intellij.codeInspection.ProblemDescriptor -+import com.intellij.codeInspection.ProblemHighlightType -+import com.intellij.codeInspection.ProblemsHolder -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiElementVisitor -+import com.intellij.psi.search.LocalSearchScope -+import com.intellij.psi.search.searches.ReferencesSearch -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.* -+import org.jetbrains.kotlin.psi.addRemoveModifier.addModifier -+import org.jetbrains.kotlin.psi.psiUtil.getParentOfType -+import org.jetbrains.kotlin.psi.psiUtil.isInheritable -+import org.jetbrains.kotlin.psi.psiUtil.isOverridable -+ -+class MemberVisibilityCanPrivateInspection : AbstractKotlinInspection() { -+ -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { -+ return object : KtVisitorVoid() { -+ override fun visitProperty(property: KtProperty) { -+ super.visitProperty(property) -+ if (canBePrivate(property)) { -+ registerProblem(holder, property) -+ } -+ } -+ -+ override fun visitNamedFunction(function: KtNamedFunction) { -+ super.visitNamedFunction(function) -+ if (canBePrivate(function)) { -+ registerProblem(holder, function) -+ } -+ } -+ } -+ } -+ -+ -+ private fun canBePrivate(declaration: KtDeclaration): Boolean { -+ val modifiers = declaration.modifierList -+ if (modifiers != null && (modifiers.hasModifier(KtTokens.PRIVATE_KEYWORD) || modifiers.hasModifier(KtTokens.OVERRIDE_KEYWORD))) return false -+ val klass = (declaration.parent as? KtClassBody)?.parent as? KtClass ?: return false -+ if (!klass.isInheritable() && modifiers?.hasModifier(KtTokens.PROTECTED_KEYWORD) ?: false) return false //reported by ProtectedInFinalInspection -+ if (declaration.isOverridable()) return false -+ val allUsages = ReferencesSearch.search(declaration, declaration.useScope).count()","This is very inefficient: usages search is an expensive operation and most of the cost is wasted. You should iterate over all usages and stop as soon as you find one outside the local search scope. - -See also the [corresponding Java inspection](https://github.com/JetBrains/intellij-community/blob/master/java/java-analysis-impl/src/com/intellij/codeInspection/visibility/AccessCanBeTightenedInspection.java#L143) for inspiration.","I don't like the name of this class. In my opinion, it should be named `MemberVisibilityCanPrivateInspection`." -523,"@@ -0,0 +1,89 @@ -+/* -+ * 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.inspections -+ -+import com.intellij.codeInsight.FileModificationService -+import com.intellij.codeInspection.LocalQuickFix -+import com.intellij.codeInspection.ProblemDescriptor -+import com.intellij.codeInspection.ProblemHighlightType -+import com.intellij.codeInspection.ProblemsHolder -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiElementVisitor -+import com.intellij.psi.search.LocalSearchScope -+import com.intellij.psi.search.searches.ReferencesSearch -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.* -+import org.jetbrains.kotlin.psi.addRemoveModifier.addModifier -+import org.jetbrains.kotlin.psi.psiUtil.getParentOfType -+import org.jetbrains.kotlin.psi.psiUtil.isInheritable -+import org.jetbrains.kotlin.psi.psiUtil.isOverridable -+ -+class MemberVisibilityCanPrivateInspection : AbstractKotlinInspection() { -+ -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { -+ return object : KtVisitorVoid() { -+ override fun visitProperty(property: KtProperty) { -+ super.visitProperty(property) -+ if (canBePrivate(property)) { -+ registerProblem(holder, property) -+ } -+ } -+ -+ override fun visitNamedFunction(function: KtNamedFunction) { -+ super.visitNamedFunction(function) -+ if (canBePrivate(function)) { -+ registerProblem(holder, function) -+ } -+ } -+ } -+ } -+ -+ -+ private fun canBePrivate(declaration: KtDeclaration): Boolean { -+ val modifiers = declaration.modifierList -+ if (modifiers != null && (modifiers.hasModifier(KtTokens.PRIVATE_KEYWORD) || modifiers.hasModifier(KtTokens.OVERRIDE_KEYWORD))) return false -+ val klass = (declaration.parent as? KtClassBody)?.parent as? KtClass ?: return false -+ if (!klass.isInheritable() && modifiers?.hasModifier(KtTokens.PROTECTED_KEYWORD) ?: false) return false //reported by ProtectedInFinalInspection -+ if (declaration.isOverridable()) return false -+ val allUsages = ReferencesSearch.search(declaration, declaration.useScope).count() -+ if (allUsages == 0) return false -+ val classUsages = ReferencesSearch.search(declaration, LocalSearchScope(klass)).count() -+ if (allUsages != classUsages) -+ return false -+ return true -+ } -+ -+ private fun registerProblem(holder: ProblemsHolder, declaration: KtDeclaration) { -+ holder.registerProblem(declaration, -+ ""Can have 'private' visibility"", -+ ProblemHighlightType.WEAK_WARNING, -+ MakePrivateFix()) -+ } -+ -+ class MakePrivateFix : LocalQuickFix {",You can reuse `AddModifierFix`,"I don't like the name of this class. In my opinion, it should be named `MemberVisibilityCanPrivateInspection`." -524,"@@ -0,0 +1,89 @@ -+/* -+ * 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.inspections -+ -+import com.intellij.codeInspection.* -+import com.intellij.psi.PsiElementVisitor -+import com.intellij.psi.PsiReference -+import com.intellij.psi.search.LocalSearchScope -+import com.intellij.psi.search.searches.ReferencesSearch -+import com.intellij.util.Processor -+import org.jetbrains.kotlin.idea.quickfix.AddModifierFix -+import org.jetbrains.kotlin.idea.refactoring.isConstructorDeclaredProperty -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.* -+import org.jetbrains.kotlin.psi.psiUtil.containingClass -+import org.jetbrains.kotlin.psi.psiUtil.getParentOfType -+import org.jetbrains.kotlin.psi.psiUtil.isInheritable -+import org.jetbrains.kotlin.psi.psiUtil.isOverridable -+ -+class MemberVisibilityCanPrivateInspection : AbstractKotlinInspection() { -+ -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { -+ return object : KtVisitorVoid() { -+ override fun visitProperty(property: KtProperty) { -+ super.visitProperty(property) -+ if (canBePrivate(property)) {",This is now reported on local variables (which are also KtProperty instances).,Please don't use wildcard imports. -525,"@@ -0,0 +1,89 @@ -+/* -+ * 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.inspections -+ -+import com.intellij.codeInspection.* -+import com.intellij.psi.PsiElementVisitor -+import com.intellij.psi.PsiReference -+import com.intellij.psi.search.LocalSearchScope -+import com.intellij.psi.search.searches.ReferencesSearch -+import com.intellij.util.Processor -+import org.jetbrains.kotlin.idea.quickfix.AddModifierFix -+import org.jetbrains.kotlin.idea.refactoring.isConstructorDeclaredProperty -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.* -+import org.jetbrains.kotlin.psi.psiUtil.containingClass -+import org.jetbrains.kotlin.psi.psiUtil.getParentOfType -+import org.jetbrains.kotlin.psi.psiUtil.isInheritable -+import org.jetbrains.kotlin.psi.psiUtil.isOverridable -+ -+class MemberVisibilityCanPrivateInspection : AbstractKotlinInspection() { -+ -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { -+ return object : KtVisitorVoid() { -+ override fun visitProperty(property: KtProperty) { -+ super.visitProperty(property) -+ if (canBePrivate(property)) { -+ registerProblem(holder, property) -+ } -+ } -+ -+ override fun visitNamedFunction(function: KtNamedFunction) { -+ super.visitNamedFunction(function) -+ if (canBePrivate(function)) { -+ registerProblem(holder, function) -+ } -+ } -+ -+ override fun visitParameter(parameter: KtParameter) { -+ super.visitParameter(parameter) -+ if (parameter.isConstructorDeclaredProperty() && canBePrivate(parameter)) { -+ registerProblem(holder, parameter) -+ } -+ } -+ } -+ } -+ -+ -+ private fun canBePrivate(declaration: KtDeclaration): Boolean { -+ if (declaration.hasModifier(KtTokens.PRIVATE_KEYWORD) || declaration.hasModifier(KtTokens.OVERRIDE_KEYWORD)) return false -+ val klass = declaration.containingClass() ?: return false",Wouldn't hurt to handle members of `object` declarations too.,Please don't use wildcard imports. -526,"@@ -0,0 +1,89 @@ -+/* -+ * 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.inspections -+ -+import com.intellij.codeInspection.* -+import com.intellij.psi.PsiElementVisitor -+import com.intellij.psi.PsiReference -+import com.intellij.psi.search.LocalSearchScope -+import com.intellij.psi.search.searches.ReferencesSearch -+import com.intellij.util.Processor -+import org.jetbrains.kotlin.idea.quickfix.AddModifierFix -+import org.jetbrains.kotlin.idea.refactoring.isConstructorDeclaredProperty -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.* -+import org.jetbrains.kotlin.psi.psiUtil.containingClass -+import org.jetbrains.kotlin.psi.psiUtil.getParentOfType -+import org.jetbrains.kotlin.psi.psiUtil.isInheritable -+import org.jetbrains.kotlin.psi.psiUtil.isOverridable -+ -+class MemberVisibilityCanPrivateInspection : AbstractKotlinInspection() { -+ -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { -+ return object : KtVisitorVoid() { -+ override fun visitProperty(property: KtProperty) { -+ super.visitProperty(property) -+ if (canBePrivate(property)) { -+ registerProblem(holder, property) -+ } -+ } -+ -+ override fun visitNamedFunction(function: KtNamedFunction) { -+ super.visitNamedFunction(function) -+ if (canBePrivate(function)) { -+ registerProblem(holder, function) -+ } -+ } -+ -+ override fun visitParameter(parameter: KtParameter) { -+ super.visitParameter(parameter) -+ if (parameter.isConstructorDeclaredProperty() && canBePrivate(parameter)) { -+ registerProblem(holder, parameter) -+ } -+ } -+ } -+ } -+ -+ -+ private fun canBePrivate(declaration: KtDeclaration): Boolean { -+ if (declaration.hasModifier(KtTokens.PRIVATE_KEYWORD) || declaration.hasModifier(KtTokens.OVERRIDE_KEYWORD)) return false -+ val klass = declaration.containingClass() ?: return false -+ if (!klass.isInheritable() && declaration.hasModifier(KtTokens.PROTECTED_KEYWORD)) return false //reported by ProtectedInFinalInspection -+ if (declaration.isOverridable()) return false -+ var otherUsageFound = false -+ var inClassUsageFound = false -+ ReferencesSearch.search(declaration, declaration.useScope).forEach(Processor { -+ val usage = it.element -+ if (klass != usage.getParentOfType(false)) { -+ otherUsageFound = true -+ false -+ } else { -+ inClassUsageFound = true -+ true -+ } -+ }) -+ return inClassUsageFound && !otherUsageFound -+ } -+ -+ private fun registerProblem(holder: ProblemsHolder, declaration: KtDeclaration) { -+ val modifierListOwner = declaration.getParentOfType(false) ?: return -+ holder.registerProblem(declaration, -+ ""Can have 'private' visibility"",","Better to include name of declaration in the message, otherwise it's hard to understand results of a batch inspection.",Please don't use wildcard imports. -527,"@@ -0,0 +1,9 @@ -+// IS_APPLICABLE: false -+// WITH_RUNTIME -+class A(val _value: Int) { -+ operator fun compareTo(other: Int) = _value.compareTo(other) -+} -+ -+fun test(a: A): Boolean { -+ return a >= 0 && a <= 100","My suggested change to KotlinType.isComparable() will break this test, but I think it's OK because this test should be red, and we make no guarantees regarding the behavior of intentions on red code.",The name of this test case is a bit misleading. I would expect a test like this to return `true` if `a` is `false` and `a -528,"@@ -0,0 +1,9 @@ -+// WITH_RUNTIME -+// IS_APPLICABLE: FALSE -+fun String.withIndices(): Int = 42 -+ -+fun foo(s: String) { -+ for (a in s) { -+ -+ } -+}","The test is fine, the naming is not: _overridden_ function is a function declaration in a subclass with the same signature as in the superclass. There are no overridden functions here, `withIndices` is just an extension function -",I think this will fail on older browsers. -529,"@@ -0,0 +1,9 @@ -+interface B { -+ fun c() -+} -+ -+ -+object A : B {",This should be `object a`,I am not sure how this will work. The `B` -530,"@@ -0,0 +1,91 @@ -+/* -+ * 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.rmi.service -+ -+import java.io.FilePermission -+import java.net.SocketPermission -+import java.security.CodeSource -+import java.security.Permission -+import java.security.PermissionCollection -+import java.security.Policy -+import java.util.ArrayList -+import java.util.Collections -+import java.util.Enumeration -+import java.util.PropertyPermission -+ -+ -+public class DaemonPolicy(val port: Int) : Policy() { -+ -+ private fun createPermissions(): PermissionCollection { -+ val perms = DaemonPermissionCollection() -+ -+ val socketPermission = SocketPermission(""localhost:$port-"", ""connect, accept, resolve"") -+ val propertyPermission = PropertyPermission(""localhost:$port"", ""read"") -+ //val filePermission = FilePermission(""<>"", ""read"") -+ -+ perms.add(socketPermission) -+ perms.add(propertyPermission) -+ //perms.add(filePermission) -+ -+ return perms -+ } -+ -+ private val perms: PermissionCollection by lazy { createPermissions() } -+ -+ override fun getPermissions(codesource: CodeSource?): PermissionCollection { -+ return perms -+ } -+} -+ -+ -+class DaemonPermissionCollection : PermissionCollection() { -+ var perms = ArrayList()","why `var`? -",Remove this line -531,"@@ -0,0 +1,91 @@ -+/* -+ * 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.rmi.service -+ -+import java.io.FilePermission -+import java.net.SocketPermission -+import java.security.CodeSource -+import java.security.Permission -+import java.security.PermissionCollection -+import java.security.Policy -+import java.util.ArrayList -+import java.util.Collections -+import java.util.Enumeration -+import java.util.PropertyPermission -+ -+ -+public class DaemonPolicy(val port: Int) : Policy() { -+ -+ private fun createPermissions(): PermissionCollection { -+ val perms = DaemonPermissionCollection() -+ -+ val socketPermission = SocketPermission(""localhost:$port-"", ""connect, accept, resolve"") -+ val propertyPermission = PropertyPermission(""localhost:$port"", ""read"") -+ //val filePermission = FilePermission(""<>"", ""read"") -+ -+ perms.add(socketPermission) -+ perms.add(propertyPermission) -+ //perms.add(filePermission) -+ -+ return perms -+ } -+ -+ private val perms: PermissionCollection by lazy { createPermissions() } -+ -+ override fun getPermissions(codesource: CodeSource?): PermissionCollection { -+ return perms -+ } -+} -+ -+ -+class DaemonPermissionCollection : PermissionCollection() { -+ var perms = ArrayList() -+ -+ override fun add(p: Permission) { -+ perms.add(p) -+ } -+ -+ override fun implies(p: Permission): Boolean { -+ val i = perms.iterator()","perms.any { it.implies(p) } -",Remove this line. -532,"@@ -0,0 +1,91 @@ -+/* -+ * 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.inspections -+ -+import com.intellij.codeInspection.* -+import com.intellij.psi.PsiElementVisitor -+import com.intellij.psi.PsiReference -+import com.intellij.psi.search.LocalSearchScope -+import com.intellij.psi.search.searches.ReferencesSearch -+import com.intellij.util.Processor -+import org.jetbrains.kotlin.idea.quickfix.AddModifierFix -+import org.jetbrains.kotlin.idea.refactoring.isConstructorDeclaredProperty -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.* -+import org.jetbrains.kotlin.psi.psiUtil.* -+ -+class MemberVisibilityCanPrivateInspection : AbstractKotlinInspection() { -+ -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { -+ return object : KtVisitorVoid() { -+ override fun visitProperty(property: KtProperty) { -+ super.visitProperty(property) -+ if (!property.isLocal && canBePrivate(property)) { -+ registerProblem(holder, property) -+ } -+ } -+ -+ override fun visitNamedFunction(function: KtNamedFunction) { -+ super.visitNamedFunction(function) -+ if (canBePrivate(function)) { -+ registerProblem(holder, function) -+ } -+ } -+ -+ override fun visitParameter(parameter: KtParameter) { -+ super.visitParameter(parameter) -+ if (parameter.isConstructorDeclaredProperty() && canBePrivate(parameter)) { -+ registerProblem(holder, parameter) -+ } -+ } -+ } -+ } -+ -+ -+ private fun canBePrivate(declaration: KtDeclaration): Boolean { -+ if (declaration.hasModifier(KtTokens.PRIVATE_KEYWORD) || declaration.hasModifier(KtTokens.OVERRIDE_KEYWORD)) return false -+ val classOrObject = declaration.containingClassOrObject ?: return false -+ val inheritable = classOrObject is KtClass && classOrObject.isInheritable() -+ if (!inheritable && declaration.hasModifier(KtTokens.PROTECTED_KEYWORD)) return false //reported by ProtectedInFinalInspection -+ if (declaration.isOverridable()) return false -+ var otherUsageFound = false -+ var inClassUsageFound = false -+ ReferencesSearch.search(declaration, declaration.useScope).forEach(Processor { -+ val usage = it.element -+ if (classOrObject != usage.getParentOfType(false)) { -+ otherUsageFound = true -+ false -+ } else { -+ inClassUsageFound = true -+ true -+ } -+ }) -+ return inClassUsageFound && !otherUsageFound -+ } -+ -+ private fun registerProblem(holder: ProblemsHolder, declaration: KtDeclaration) { -+ val modifierListOwner = declaration.getParentOfType(false) ?: return -+ val member = when (declaration) { -+ is KtNamedFunction -> ""Function"" -+ else -> ""Property"" -+ } -+ holder.registerProblem(declaration,","This highlights the entire declaration with a wavy underline, which is very intrusive. Should highlight only the name identifier.",I don't think you need to have an overrid -533,"@@ -0,0 +1,92 @@ -+/* -+ * 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.effectsystem.impls -+ -+import org.jetbrains.kotlin.effectsystem.structure.ESClause -+import org.jetbrains.kotlin.effectsystem.structure.EffectSchema -+import org.jetbrains.kotlin.effectsystem.structure.ESExpressionVisitor -+ -+class Printer : ESExpressionVisitor { -+ private val builder = StringBuilder() -+ -+ private fun print(string: String) { -+ builder.append(string) -+ } -+ -+ private inline fun line(block: () -> Unit) { -+ block() -+ } -+ -+ fun print(schema: EffectSchema) { -+ schema.clauses.forEach { visitClause(it) } -+ } -+ -+ fun visitClause(clause: ESClause) { -+ line { -+ clause.condition.accept(this) -+ print("" -> "")",Looks like this arrow has the wrong direction,You don't need to do this. EffectSchema a -534,"@@ -0,0 +1,93 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetParameter -+import org.jetbrains.jet.lexer.JetTokens -+ -+public class MakeTypeImplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.implicit.in.lambda"", javaClass()) { -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ throw IllegalStateException(""isApplicableTo(JetExpressionImpl, Editor) should be called instead"") -+ } -+ -+ override fun isApplicableTo(element: JetFunctionLiteralExpression, editor: Editor): Boolean { -+ val openBraceOffset = element.getLeftCurlyBrace().getStartOffset() -+ val closeBraceOffset = element.getRightCurlyBrace()?.getStartOffset() -+ val caretLocation = editor.getCaretModel().getOffset() -+ val arrow = element.getFunctionLiteral().getArrowNode() -+ if (arrow != null && !(openBraceOffset < caretLocation && caretLocation < arrow.getStartOffset() + 2) && -+ caretLocation != closeBraceOffset) return false -+ else if (arrow == null && caretLocation != openBraceOffset + 1 && caretLocation != closeBraceOffset) return false -+ return hasExplicitReturnType(element) || hasExplicitReceiverType(element) || hasExplicitParamType(element) -+ } -+ -+ override fun applyTo(element: JetFunctionLiteralExpression, editor: Editor) { -+ val functionLiteral = element.getFunctionLiteral() -+ val oldParameterList = functionLiteral.getValueParameterList() -+ -+ if (hasExplicitReturnType(element)) { -+ val childAfterParamList = oldParameterList?.getNextSibling() -+ val arrow = functionLiteral.getArrowNode()?.getPsi() -+ val childBeforeArrow = arrow?.getPrevSibling() -+ functionLiteral.deleteChildRange(childAfterParamList, childBeforeArrow) -+ val whiteSpaceBeforeArrow = JetPsiFactory.createWhiteSpace(element.getProject()) -+ functionLiteral.addBefore(whiteSpaceBeforeArrow, arrow) -+ } -+ -+ if (hasExplicitReceiverType(element)) { -+ val childAfterBrace = functionLiteral.getOpenBraceNode().getPsi()?.getNextSibling() -+ val childBeforeParamList = oldParameterList?.getPrevSibling() -+ functionLiteral.deleteChildRange(childAfterBrace, childBeforeParamList) -+ } -+ -+ val oldParameters = oldParameterList?.getParameters() -+ if (oldParameterList != null && oldParameters != null && hasExplicitParamType(element)) { -+ val parameterString = oldParameters.map({(parameter: JetParameter): String -> parameter.getNameIdentifier()!!.getText()!!","Your intention would be helpful to make types implicit here :) I think they don't really add anything to readability -",Please annotate `@since` with `@since`. -535,"@@ -0,0 +1,93 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetParameter -+import org.jetbrains.jet.lexer.JetTokens -+ -+public class MakeTypeImplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.implicit.in.lambda"", javaClass()) { -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ throw IllegalStateException(""isApplicableTo(JetExpressionImpl, Editor) should be called instead"") -+ } -+ -+ override fun isApplicableTo(element: JetFunctionLiteralExpression, editor: Editor): Boolean { -+ val openBraceOffset = element.getLeftCurlyBrace().getStartOffset() -+ val closeBraceOffset = element.getRightCurlyBrace()?.getStartOffset() -+ val caretLocation = editor.getCaretModel().getOffset() -+ val arrow = element.getFunctionLiteral().getArrowNode() -+ if (arrow != null && !(openBraceOffset < caretLocation && caretLocation < arrow.getStartOffset() + 2) && -+ caretLocation != closeBraceOffset) return false -+ else if (arrow == null && caretLocation != openBraceOffset + 1 && caretLocation != closeBraceOffset) return false -+ return hasExplicitReturnType(element) || hasExplicitReceiverType(element) || hasExplicitParamType(element) -+ } -+ -+ override fun applyTo(element: JetFunctionLiteralExpression, editor: Editor) { -+ val functionLiteral = element.getFunctionLiteral() -+ val oldParameterList = functionLiteral.getValueParameterList() -+ -+ if (hasExplicitReturnType(element)) { -+ val childAfterParamList = oldParameterList?.getNextSibling() -+ val arrow = functionLiteral.getArrowNode()?.getPsi() -+ val childBeforeArrow = arrow?.getPrevSibling() -+ functionLiteral.deleteChildRange(childAfterParamList, childBeforeArrow) -+ val whiteSpaceBeforeArrow = JetPsiFactory.createWhiteSpace(element.getProject()) -+ functionLiteral.addBefore(whiteSpaceBeforeArrow, arrow) -+ } -+ -+ if (hasExplicitReceiverType(element)) { -+ val childAfterBrace = functionLiteral.getOpenBraceNode().getPsi()?.getNextSibling() -+ val childBeforeParamList = oldParameterList?.getPrevSibling() -+ functionLiteral.deleteChildRange(childAfterBrace, childBeforeParamList) -+ } -+ -+ val oldParameters = oldParameterList?.getParameters() -+ if (oldParameterList != null && oldParameters != null && hasExplicitParamType(element)) { -+ val parameterString = oldParameters.map({(parameter: JetParameter): String -> parameter.getNameIdentifier()!!.getText()!! -+ }).makeString("", "", ""("", "")"") -+ val newParameterList = JetPsiFactory.createParameterList(element.getProject(), parameterString) -+ oldParameterList.replace(newParameterList) -+ } -+ -+ if (!hasExplicitParamType(element)) { -+ val currentParamList = element.getFunctionLiteral().getValueParameterList() -+ val firstChild = currentParamList?.getFirstChild() -+ if (firstChild?.getNode()?.getElementType() == JetTokens.LPAR) firstChild!!.delete() -+ val lastChild = currentParamList?.getLastChild() -+ if (lastChild?.getNode()?.getElementType() == JetTokens.RPAR) lastChild!!.delete() -+ } -+ } -+ -+ fun hasExplicitReturnType(element: JetFunctionLiteralExpression): Boolean { -+ return element.hasDeclaredReturnType() -+ } -+ -+ fun hasExplicitReceiverType(element: JetFunctionLiteralExpression): Boolean { -+ return element.getFunctionLiteral().getReceiverTypeRef() != null -+ } -+ -+ fun hasExplicitParamType(element: JetFunctionLiteralExpression): Boolean { -+ if (element.getValueParameters().any { it.getTypeReference() != null }) { -+ val parameters = element.getFunctionLiteral().getValueParameterList()?.getParameters() -+ return !(parameters?.any { it.getNameIdentifier()?.getText() == null } ?: false)","This code looks a little awkward to me. - -First, consider using other standard library functions such as `none` or `all` instead of `any` to prevent at least some negations. - -Second, why can't you iterate the parameter list with one simple `for` and check two conditions for each parameter in the loop body? -",Please annotate `@since` with `@since`. -536,"@@ -0,0 +1,93 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetParameter -+import org.jetbrains.jet.lexer.JetTokens -+ -+public class MakeTypeImplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.implicit.in.lambda"", javaClass()) { -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ throw IllegalStateException(""isApplicableTo(JetExpressionImpl, Editor) should be called instead"") -+ } -+ -+ override fun isApplicableTo(element: JetFunctionLiteralExpression, editor: Editor): Boolean { -+ val openBraceOffset = element.getLeftCurlyBrace().getStartOffset() -+ val closeBraceOffset = element.getRightCurlyBrace()?.getStartOffset() -+ val caretLocation = editor.getCaretModel().getOffset() -+ val arrow = element.getFunctionLiteral().getArrowNode() -+ if (arrow != null && !(openBraceOffset < caretLocation && caretLocation < arrow.getStartOffset() + 2) && -+ caretLocation != closeBraceOffset) return false -+ else if (arrow == null && caretLocation != openBraceOffset + 1 && caretLocation != closeBraceOffset) return false -+ return hasExplicitReturnType(element) || hasExplicitReceiverType(element) || hasExplicitParamType(element) -+ } -+ -+ override fun applyTo(element: JetFunctionLiteralExpression, editor: Editor) { -+ val functionLiteral = element.getFunctionLiteral() -+ val oldParameterList = functionLiteral.getValueParameterList() -+ -+ if (hasExplicitReturnType(element)) { -+ val childAfterParamList = oldParameterList?.getNextSibling() -+ val arrow = functionLiteral.getArrowNode()?.getPsi() -+ val childBeforeArrow = arrow?.getPrevSibling() -+ functionLiteral.deleteChildRange(childAfterParamList, childBeforeArrow) -+ val whiteSpaceBeforeArrow = JetPsiFactory.createWhiteSpace(element.getProject()) -+ functionLiteral.addBefore(whiteSpaceBeforeArrow, arrow) -+ } -+ -+ if (hasExplicitReceiverType(element)) { -+ val childAfterBrace = functionLiteral.getOpenBraceNode().getPsi()?.getNextSibling() -+ val childBeforeParamList = oldParameterList?.getPrevSibling() -+ functionLiteral.deleteChildRange(childAfterBrace, childBeforeParamList) -+ } -+ -+ val oldParameters = oldParameterList?.getParameters() -+ if (oldParameterList != null && oldParameters != null && hasExplicitParamType(element)) { -+ val parameterString = oldParameters.map({(parameter: JetParameter): String -> parameter.getNameIdentifier()!!.getText()!! -+ }).makeString("", "", ""("", "")"") -+ val newParameterList = JetPsiFactory.createParameterList(element.getProject(), parameterString) -+ oldParameterList.replace(newParameterList) -+ } -+ -+ if (!hasExplicitParamType(element)) { -+ val currentParamList = element.getFunctionLiteral().getValueParameterList() -+ val firstChild = currentParamList?.getFirstChild() -+ if (firstChild?.getNode()?.getElementType() == JetTokens.LPAR) firstChild!!.delete() -+ val lastChild = currentParamList?.getLastChild() -+ if (lastChild?.getNode()?.getElementType() == JetTokens.RPAR) lastChild!!.delete() -+ } -+ } -+ -+ fun hasExplicitReturnType(element: JetFunctionLiteralExpression): Boolean { -+ return element.hasDeclaredReturnType() -+ } -+ -+ fun hasExplicitReceiverType(element: JetFunctionLiteralExpression): Boolean { -+ return element.getFunctionLiteral().getReceiverTypeRef() != null -+ } -+ -+ fun hasExplicitParamType(element: JetFunctionLiteralExpression): Boolean { -+ if (element.getValueParameters().any { it.getTypeReference() != null }) { -+ val parameters = element.getFunctionLiteral().getValueParameterList()?.getParameters() -+ return !(parameters?.any { it.getNameIdentifier()?.getText() == null } ?: false) -+ } -+ return false; -+ }","Ditto (`private`) -",Please annotate `@since` with `@since`. -537,"@@ -0,0 +1,93 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetIfExpression -+import org.jetbrains.jet.lang.psi.JetWhileExpression -+import org.jetbrains.jet.lang.psi.JetForExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetDoWhileExpression -+import org.jetbrains.jet.lang.psi.JetExpressionImpl -+import org.jetbrains.jet.lang.psi.psiUtil.findBlockInExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.JetNodeTypes -+import org.jetbrains.jet.lang.psi.psiUtil.getExpressionType -+import org.jetbrains.jet.lang.psi.JetBlockExpression -+import com.intellij.lang.ASTNode -+import com.intellij.psi.PsiElement -+import com.siyeh.ig.PsiReplacementUtil -+import com.intellij.openapi.fileEditor.FileEditorManager -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiFile -+ -+public class AddBracesIntention : JetSelfTargetingIntention(""add.braces"", javaClass()) { -+ private var expressionType: String? = """" -+ private var caretLocation: Int = 1 -+ -+ override fun isAvailable(project: Project, editor: Editor, file: PsiFile): Boolean { -+ caretLocation = editor.getCaretModel().getOffset() -+ return getTarget(editor, file) != null -+ } -+ -+ override fun isApplicableTo(element: JetExpressionImpl): Boolean { -+ expressionType = element.getExpressionType(element) -+ if (expressionType == null) return false -+ -+ if (expressionType == ""else"") { -+ val elseLocation = (element as JetIfExpression).getElse()!!.getParent()!!.getTextOffset() - 5","Stricter way is to find ""else"" keyword directly by `element.getNode().findChildByType(JetTokens.ELSE_KEYWORD)`. And this ""minus 5"" looks very esoteric anyway :) -","Rather than introduce a new class, use th" -538,"@@ -0,0 +1,93 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetIfExpression -+import org.jetbrains.jet.lang.psi.JetWhileExpression -+import org.jetbrains.jet.lang.psi.JetForExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetDoWhileExpression -+import org.jetbrains.jet.lang.psi.JetExpressionImpl -+import org.jetbrains.jet.lang.psi.psiUtil.findBlockInExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.JetNodeTypes -+import org.jetbrains.jet.lang.psi.psiUtil.getExpressionType -+import org.jetbrains.jet.lang.psi.JetBlockExpression -+import com.intellij.lang.ASTNode -+import com.intellij.psi.PsiElement -+import com.siyeh.ig.PsiReplacementUtil -+import com.intellij.openapi.fileEditor.FileEditorManager -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiFile -+ -+public class AddBracesIntention : JetSelfTargetingIntention(""add.braces"", javaClass()) { -+ private var expressionType: String? = """" -+ private var caretLocation: Int = 1 -+ -+ override fun isAvailable(project: Project, editor: Editor, file: PsiFile): Boolean { -+ caretLocation = editor.getCaretModel().getOffset() -+ return getTarget(editor, file) != null -+ } -+ -+ override fun isApplicableTo(element: JetExpressionImpl): Boolean { -+ expressionType = element.getExpressionType(element) -+ if (expressionType == null) return false -+ -+ if (expressionType == ""else"") { -+ val elseLocation = (element as JetIfExpression).getElse()!!.getParent()!!.getTextOffset() - 5 -+ if (caretLocation < elseLocation) { -+ expressionType = ""if"" -+ } -+ }","This code for distinguishing ""if"" from ""else"" has two problems: -- It is duplicated (here and symmetric intention) -- It is spread among two places: first `getExpressionType` returns `else` (which actually means ""if or else, I don't know yet), and then it is recalculated for if-else case. - Alternative it to pass caret position to `getExpressionType`, so all these calculations will be there. -","Rather than introduce a new class, use th" -539,"@@ -0,0 +1,93 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetIfExpression -+import org.jetbrains.jet.lang.psi.JetWhileExpression -+import org.jetbrains.jet.lang.psi.JetForExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetDoWhileExpression -+import org.jetbrains.jet.lang.psi.JetExpressionImpl -+import org.jetbrains.jet.lang.psi.psiUtil.findBlockInExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.JetNodeTypes -+import org.jetbrains.jet.lang.psi.psiUtil.getExpressionType -+import org.jetbrains.jet.lang.psi.JetBlockExpression -+import com.intellij.lang.ASTNode -+import com.intellij.psi.PsiElement -+import com.siyeh.ig.PsiReplacementUtil -+import com.intellij.openapi.fileEditor.FileEditorManager -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiFile -+ -+public class AddBracesIntention : JetSelfTargetingIntention(""add.braces"", javaClass()) { -+ private var expressionType: String? = """" -+ private var caretLocation: Int = 1 -+ -+ override fun isAvailable(project: Project, editor: Editor, file: PsiFile): Boolean { -+ caretLocation = editor.getCaretModel().getOffset() -+ return getTarget(editor, file) != null -+ } -+ -+ override fun isApplicableTo(element: JetExpressionImpl): Boolean { -+ expressionType = element.getExpressionType(element) -+ if (expressionType == null) return false -+ -+ if (expressionType == ""else"") { -+ val elseLocation = (element as JetIfExpression).getElse()!!.getParent()!!.getTextOffset() - 5 -+ if (caretLocation < elseLocation) { -+ expressionType = ""if"" -+ } -+ } -+ val jetBlockElement = element.findBlockInExpression(element, expressionType) -+ if (jetBlockElement != null) return false -+ -+ setText(""Add braces to '$expressionType' statement"") -+ return true -+ } -+ -+ override fun applyTo(element: JetExpressionImpl, editor: Editor) { -+ val bodyNode = when (expressionType) { -+ ""else"" -> element.getNode().findChildByType(JetNodeTypes.ELSE) -+ ""if"" -> element.getNode().findChildByType(JetNodeTypes.THEN) -+ else -> element.getNode().findChildByType(JetNodeTypes.BODY) -+ } -+ generateCleanOutput(element, bodyNode) -+ } -+ -+ fun generateCleanOutput(element: JetExpressionImpl, bodyNode: ASTNode?) { -+ val newElement: PsiElement? -+ -+ if (element.getNextSibling()?.getText() == "";"") { -+ element.getNextSibling()!!.delete() -+ } -+ newElement = bodyNode!!.getPsi()!!.replace(JetPsiFactory.createFunctionBody(element.getProject(), bodyNode.getText())) -+ -+ //handles the case of the block statement being on a new line -+ if (newElement?.getPrevSibling()?.getText() != "")"") {","Checking for `is PsiWhiteSpace` is more robust. -","Rather than introduce a new class, use th" -540,"@@ -0,0 +1,93 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetIfExpression -+import org.jetbrains.jet.lang.psi.JetWhileExpression -+import org.jetbrains.jet.lang.psi.JetForExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetDoWhileExpression -+import org.jetbrains.jet.lang.psi.JetExpressionImpl -+import org.jetbrains.jet.lang.psi.psiUtil.findBlockInExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.JetNodeTypes -+import org.jetbrains.jet.lang.psi.psiUtil.getExpressionType -+import org.jetbrains.jet.lang.psi.JetBlockExpression -+import com.intellij.lang.ASTNode -+import com.intellij.psi.PsiElement -+import com.siyeh.ig.PsiReplacementUtil -+import com.intellij.openapi.fileEditor.FileEditorManager -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiFile -+ -+public class AddBracesIntention : JetSelfTargetingIntention(""add.braces"", javaClass()) { -+ private var expressionType: String? = """" -+ private var caretLocation: Int = 1 -+ -+ override fun isAvailable(project: Project, editor: Editor, file: PsiFile): Boolean { -+ caretLocation = editor.getCaretModel().getOffset() -+ return getTarget(editor, file) != null -+ } -+ -+ override fun isApplicableTo(element: JetExpressionImpl): Boolean { -+ expressionType = element.getExpressionType(element) -+ if (expressionType == null) return false -+ -+ if (expressionType == ""else"") { -+ val elseLocation = (element as JetIfExpression).getElse()!!.getParent()!!.getTextOffset() - 5 -+ if (caretLocation < elseLocation) { -+ expressionType = ""if"" -+ } -+ } -+ val jetBlockElement = element.findBlockInExpression(element, expressionType) -+ if (jetBlockElement != null) return false -+ -+ setText(""Add braces to '$expressionType' statement"") -+ return true -+ } -+ -+ override fun applyTo(element: JetExpressionImpl, editor: Editor) { -+ val bodyNode = when (expressionType) { -+ ""else"" -> element.getNode().findChildByType(JetNodeTypes.ELSE) -+ ""if"" -> element.getNode().findChildByType(JetNodeTypes.THEN) -+ else -> element.getNode().findChildByType(JetNodeTypes.BODY) -+ } -+ generateCleanOutput(element, bodyNode) -+ } -+ -+ fun generateCleanOutput(element: JetExpressionImpl, bodyNode: ASTNode?) { -+ val newElement: PsiElement? -+ -+ if (element.getNextSibling()?.getText() == "";"") { -+ element.getNextSibling()!!.delete() -+ } -+ newElement = bodyNode!!.getPsi()!!.replace(JetPsiFactory.createFunctionBody(element.getProject(), bodyNode.getText())) -+ -+ //handles the case of the block statement being on a new line -+ if (newElement?.getPrevSibling()?.getText() != "")"") { -+ newElement!!.getPrevSibling()!!.replace(JetPsiFactory.createWhiteSpace(element.getProject())) -+ } -+ //handles the case of no space between condition and statement -+ if (newElement?.getPrevSibling()?.getText() == "")"") {","Shouldn't it be just an `else` for previous `if`? -","Rather than introduce a new class, use th" -541,"@@ -0,0 +1,93 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import org.jetbrains.jet.lang.psi.JetIfExpression -+import org.jetbrains.jet.lang.psi.JetWhileExpression -+import org.jetbrains.jet.lang.psi.JetForExpression -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetDoWhileExpression -+import org.jetbrains.jet.lang.psi.JetExpressionImpl -+import org.jetbrains.jet.lang.psi.psiUtil.findBlockInExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.JetNodeTypes -+import org.jetbrains.jet.lang.psi.psiUtil.getExpressionType -+import org.jetbrains.jet.lang.psi.JetBlockExpression -+import com.intellij.lang.ASTNode -+import com.intellij.psi.PsiElement -+import com.siyeh.ig.PsiReplacementUtil -+import com.intellij.openapi.fileEditor.FileEditorManager -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiFile -+ -+public class AddBracesIntention : JetSelfTargetingIntention(""add.braces"", javaClass()) { -+ private var expressionType: String? = """" -+ private var caretLocation: Int = 1 -+ -+ override fun isAvailable(project: Project, editor: Editor, file: PsiFile): Boolean { -+ caretLocation = editor.getCaretModel().getOffset() -+ return getTarget(editor, file) != null -+ } -+ -+ override fun isApplicableTo(element: JetExpressionImpl): Boolean { -+ expressionType = element.getExpressionType(element) -+ if (expressionType == null) return false -+ -+ if (expressionType == ""else"") { -+ val elseLocation = (element as JetIfExpression).getElse()!!.getParent()!!.getTextOffset() - 5 -+ if (caretLocation < elseLocation) { -+ expressionType = ""if"" -+ } -+ } -+ val jetBlockElement = element.findBlockInExpression(element, expressionType) -+ if (jetBlockElement != null) return false -+ -+ setText(""Add braces to '$expressionType' statement"") -+ return true -+ } -+ -+ override fun applyTo(element: JetExpressionImpl, editor: Editor) { -+ val bodyNode = when (expressionType) { -+ ""else"" -> element.getNode().findChildByType(JetNodeTypes.ELSE) -+ ""if"" -> element.getNode().findChildByType(JetNodeTypes.THEN) -+ else -> element.getNode().findChildByType(JetNodeTypes.BODY) -+ } -+ generateCleanOutput(element, bodyNode) -+ } -+ -+ fun generateCleanOutput(element: JetExpressionImpl, bodyNode: ASTNode?) { -+ val newElement: PsiElement? -+ -+ if (element.getNextSibling()?.getText() == "";"") { -+ element.getNextSibling()!!.delete() -+ } -+ newElement = bodyNode!!.getPsi()!!.replace(JetPsiFactory.createFunctionBody(element.getProject(), bodyNode.getText())) -+ -+ //handles the case of the block statement being on a new line -+ if (newElement?.getPrevSibling()?.getText() != "")"") { -+ newElement!!.getPrevSibling()!!.replace(JetPsiFactory.createWhiteSpace(element.getProject())) -+ } -+ //handles the case of no space between condition and statement -+ if (newElement?.getPrevSibling()?.getText() == "")"") { -+ newElement!!.addBefore(JetPsiFactory.createWhiteSpace(element.getProject()), newElement.getFirstChild()) -+ } -+ if (expressionType == ""do...while"") { -+ newElement?.getNextSibling()?.delete() -+ } -+ bodyNode.getPsi()!!.delete()","What is this for? Couldn't understand without comment. -","Rather than introduce a new class, use th" -542,"@@ -0,0 +1,94 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetBlockExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetWhileExpression -+import org.jetbrains.jet.lang.psi.JetIfExpression -+import org.jetbrains.jet.lang.psi.JetDoWhileExpression -+import org.jetbrains.jet.lang.psi.JetForExpression -+import org.jetbrains.jet.lang.psi.JetExpressionImpl -+//import org.jetbrains.jet.lang.psi.psiUtil.findBlockInExpression -+import org.jetbrains.jet.JetNodeTypes -+import com.intellij.psi.PsiComment -+import com.intellij.psi.PsiElement -+import com.intellij.openapi.fileEditor.FileEditorManager -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiFile -+//import org.jetbrains.jet.lang.psi.psiUtil.getExpressionKind","Commented imports? Are you sure? :) -",Remove unused imports -543,"@@ -0,0 +1,95 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetParameter -+import org.jetbrains.jet.lexer.JetTokens -+ -+public class MakeTypeImplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.implicit.in.lambda"", javaClass()) { -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ throw IllegalStateException(""isApplicableTo(JetExpressionImpl, Editor) should be called instead"") -+ } -+ -+ override fun isApplicableTo(element: JetFunctionLiteralExpression, editor: Editor): Boolean { -+ val openBraceOffset = element.getLeftCurlyBrace().getStartOffset() -+ val closeBraceOffset = element.getRightCurlyBrace()?.getStartOffset() -+ val caretLocation = editor.getCaretModel().getOffset() -+ val arrow = element.getFunctionLiteral().getArrowNode() -+ if (arrow != null && !(openBraceOffset < caretLocation && caretLocation < arrow.getStartOffset() + 2) && -+ caretLocation != closeBraceOffset) return false","Yes, our formatter fails here at the moment, but you still should indent this line manually with 4 spaces -",Please add a license header like the one -544,"@@ -0,0 +1,95 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetParameter -+import org.jetbrains.jet.lexer.JetTokens -+ -+public class MakeTypeImplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.implicit.in.lambda"", javaClass()) { -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ throw IllegalStateException(""isApplicableTo(JetExpressionImpl, Editor) should be called instead"") -+ } -+ -+ override fun isApplicableTo(element: JetFunctionLiteralExpression, editor: Editor): Boolean { -+ val openBraceOffset = element.getLeftCurlyBrace().getStartOffset() -+ val closeBraceOffset = element.getRightCurlyBrace()?.getStartOffset() -+ val caretLocation = editor.getCaretModel().getOffset() -+ val arrow = element.getFunctionLiteral().getArrowNode() -+ if (arrow != null && !(openBraceOffset < caretLocation && caretLocation < arrow.getStartOffset() + 2) && -+ caretLocation != closeBraceOffset) return false -+ else if (arrow == null && caretLocation != openBraceOffset + 1 && caretLocation != closeBraceOffset) return false -+ return hasExplicitReturnType(element) || hasExplicitReceiverType(element) || hasExplicitParamType(element) -+ } -+ -+ override fun applyTo(element: JetFunctionLiteralExpression, editor: Editor) { -+ val functionLiteral = element.getFunctionLiteral() -+ val oldParameterList = functionLiteral.getValueParameterList() -+ -+ if (hasExplicitReturnType(element)) { -+ val childAfterParamList = oldParameterList?.getNextSibling() -+ val arrow = functionLiteral.getArrowNode()?.getPsi() -+ val childBeforeArrow = arrow?.getPrevSibling() -+ functionLiteral.deleteChildRange(childAfterParamList, childBeforeArrow) -+ val whiteSpaceBeforeArrow = JetPsiFactory.createWhiteSpace(element.getProject()) -+ functionLiteral.addBefore(whiteSpaceBeforeArrow, arrow) -+ } -+ -+ if (hasExplicitReceiverType(element)) { -+ val childAfterBrace = functionLiteral.getOpenBraceNode().getPsi()?.getNextSibling() -+ val childBeforeParamList = oldParameterList?.getPrevSibling() -+ functionLiteral.deleteChildRange(childAfterBrace, childBeforeParamList) -+ } -+ -+ if (oldParameterList?.getParameters() != null && hasExplicitParamType(element)) { -+ val parameterString = oldParameterList!!.getParameters().map({parameter -> parameter.getNameIdentifier()!!.getText()!! -+ }).makeString("", "", ""("", "")"")","Formatting got screwed up while you were modifying this code. It should be: - -``` -val ....map({ - parameter -> ... -}).makeString(...) -``` -",Please annotate `@since` with `@since`. -545,"@@ -0,0 +1,95 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetParameter -+import org.jetbrains.jet.lexer.JetTokens -+ -+public class MakeTypeImplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.implicit.in.lambda"", javaClass()) { -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ throw IllegalStateException(""isApplicableTo(JetExpressionImpl, Editor) should be called instead"") -+ } -+ -+ override fun isApplicableTo(element: JetFunctionLiteralExpression, editor: Editor): Boolean { -+ val openBraceOffset = element.getLeftCurlyBrace().getStartOffset() -+ val closeBraceOffset = element.getRightCurlyBrace()?.getStartOffset() -+ val caretLocation = editor.getCaretModel().getOffset() -+ val arrow = element.getFunctionLiteral().getArrowNode() -+ if (arrow != null && !(openBraceOffset < caretLocation && caretLocation < arrow.getStartOffset() + 2) && -+ caretLocation != closeBraceOffset) return false -+ else if (arrow == null && caretLocation != openBraceOffset + 1 && caretLocation != closeBraceOffset) return false -+ return hasExplicitReturnType(element) || hasExplicitReceiverType(element) || hasExplicitParamType(element) -+ } -+ -+ override fun applyTo(element: JetFunctionLiteralExpression, editor: Editor) { -+ val functionLiteral = element.getFunctionLiteral() -+ val oldParameterList = functionLiteral.getValueParameterList() -+ -+ if (hasExplicitReturnType(element)) { -+ val childAfterParamList = oldParameterList?.getNextSibling() -+ val arrow = functionLiteral.getArrowNode()?.getPsi() -+ val childBeforeArrow = arrow?.getPrevSibling() -+ functionLiteral.deleteChildRange(childAfterParamList, childBeforeArrow) -+ val whiteSpaceBeforeArrow = JetPsiFactory.createWhiteSpace(element.getProject()) -+ functionLiteral.addBefore(whiteSpaceBeforeArrow, arrow) -+ } -+ -+ if (hasExplicitReceiverType(element)) { -+ val childAfterBrace = functionLiteral.getOpenBraceNode().getPsi()?.getNextSibling() -+ val childBeforeParamList = oldParameterList?.getPrevSibling() -+ functionLiteral.deleteChildRange(childAfterBrace, childBeforeParamList) -+ } -+ -+ if (oldParameterList?.getParameters() != null && hasExplicitParamType(element)) { -+ val parameterString = oldParameterList!!.getParameters().map({parameter -> parameter.getNameIdentifier()!!.getText()!! -+ }).makeString("", "", ""("", "")"") -+ val newParameterList = JetPsiFactory.createParameterList(element.getProject(), parameterString) -+ oldParameterList.replace(newParameterList) -+ } -+ -+ if (!hasExplicitParamType(element)) { -+ val currentParamList = element.getFunctionLiteral().getValueParameterList() -+ val firstChild = currentParamList?.getFirstChild() -+ if (firstChild?.getNode()?.getElementType() == JetTokens.LPAR) firstChild!!.delete() -+ val lastChild = currentParamList?.getLastChild() -+ if (lastChild?.getNode()?.getElementType() == JetTokens.RPAR) lastChild!!.delete() -+ } -+ } -+ -+ private fun hasExplicitReturnType(element: JetFunctionLiteralExpression): Boolean { -+ return element.hasDeclaredReturnType() -+ } -+ -+ private fun hasExplicitReceiverType(element: JetFunctionLiteralExpression): Boolean { -+ return element.getFunctionLiteral().getReceiverTypeRef() != null -+ } -+ -+ private fun hasExplicitParamType(element: JetFunctionLiteralExpression): Boolean { -+ val parameters = element.getFunctionLiteral().getValueParameterList()?.getParameters() -+ if (parameters == null) return false -+ var numExplicitParams = 0","Better, but shouldn't it be a boolean `hasExplicitParamType`? :) -",Please annotate `@since` with `@since`. -546,"@@ -0,0 +1,95 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetParameter -+import org.jetbrains.jet.lexer.JetTokens -+ -+public class MakeTypeImplicitInLambdaIntention : JetSelfTargetingIntention( -+ ""make.type.implicit.in.lambda"", javaClass()) { -+ override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean { -+ throw IllegalStateException(""isApplicableTo(JetExpressionImpl, Editor) should be called instead"") -+ } -+ -+ override fun isApplicableTo(element: JetFunctionLiteralExpression, editor: Editor): Boolean { -+ val openBraceOffset = element.getLeftCurlyBrace().getStartOffset() -+ val closeBraceOffset = element.getRightCurlyBrace()?.getStartOffset() -+ val caretLocation = editor.getCaretModel().getOffset() -+ val arrow = element.getFunctionLiteral().getArrowNode() -+ if (arrow != null && !(openBraceOffset < caretLocation && caretLocation < arrow.getStartOffset() + 2) && -+ caretLocation != closeBraceOffset) return false -+ else if (arrow == null && caretLocation != openBraceOffset + 1 && caretLocation != closeBraceOffset) return false -+ return hasExplicitReturnType(element) || hasExplicitReceiverType(element) || hasExplicitParamType(element) -+ } -+ -+ override fun applyTo(element: JetFunctionLiteralExpression, editor: Editor) { -+ val functionLiteral = element.getFunctionLiteral() -+ val oldParameterList = functionLiteral.getValueParameterList() -+ -+ if (hasExplicitReturnType(element)) { -+ val childAfterParamList = oldParameterList?.getNextSibling() -+ val arrow = functionLiteral.getArrowNode()?.getPsi() -+ val childBeforeArrow = arrow?.getPrevSibling() -+ functionLiteral.deleteChildRange(childAfterParamList, childBeforeArrow) -+ val whiteSpaceBeforeArrow = JetPsiFactory.createWhiteSpace(element.getProject()) -+ functionLiteral.addBefore(whiteSpaceBeforeArrow, arrow) -+ } -+ -+ if (hasExplicitReceiverType(element)) { -+ val childAfterBrace = functionLiteral.getOpenBraceNode().getPsi()?.getNextSibling() -+ val childBeforeParamList = oldParameterList?.getPrevSibling() -+ functionLiteral.deleteChildRange(childAfterBrace, childBeforeParamList) -+ } -+ -+ if (oldParameterList?.getParameters() != null && hasExplicitParamType(element)) { -+ val parameterString = oldParameterList!!.getParameters().map({parameter -> parameter.getNameIdentifier()!!.getText()!! -+ }).makeString("", "", ""("", "")"") -+ val newParameterList = JetPsiFactory.createParameterList(element.getProject(), parameterString) -+ oldParameterList.replace(newParameterList) -+ } -+ -+ if (!hasExplicitParamType(element)) { -+ val currentParamList = element.getFunctionLiteral().getValueParameterList() -+ val firstChild = currentParamList?.getFirstChild() -+ if (firstChild?.getNode()?.getElementType() == JetTokens.LPAR) firstChild!!.delete() -+ val lastChild = currentParamList?.getLastChild() -+ if (lastChild?.getNode()?.getElementType() == JetTokens.RPAR) lastChild!!.delete() -+ } -+ } -+ -+ private fun hasExplicitReturnType(element: JetFunctionLiteralExpression): Boolean { -+ return element.hasDeclaredReturnType() -+ } -+ -+ private fun hasExplicitReceiverType(element: JetFunctionLiteralExpression): Boolean { -+ return element.getFunctionLiteral().getReceiverTypeRef() != null -+ } -+ -+ private fun hasExplicitParamType(element: JetFunctionLiteralExpression): Boolean { -+ val parameters = element.getFunctionLiteral().getValueParameterList()?.getParameters() -+ if (parameters == null) return false -+ var numExplicitParams = 0 -+ for (param in parameters!!) {","`!!` shouldn't be needed here -",Please annotate `@since` with `@since`. -547,"@@ -0,0 +1,96 @@ -+/* -+ * 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.idea.quickfix -+ -+import com.intellij.openapi.editor.Editor -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiFile -+import org.jetbrains.kotlin.builtins.KotlinBuiltIns -+import org.jetbrains.kotlin.codegen.ExpressionCodegen -+import org.jetbrains.kotlin.idea.caches.resolve.analyze -+import org.jetbrains.kotlin.idea.core.replaced -+import org.jetbrains.kotlin.psi.KtConstantExpression -+import org.jetbrains.kotlin.psi.KtExpression -+import org.jetbrains.kotlin.psi.KtFile -+import org.jetbrains.kotlin.psi.KtPsiFactory -+import org.jetbrains.kotlin.psi.psiUtil.endOffset -+import org.jetbrains.kotlin.resolve.DescriptorUtils -+import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode -+import org.jetbrains.kotlin.types.KotlinType -+ -+private val valueRanges = mapOf( -+ KotlinBuiltIns.FQ_NAMES._byte to Byte.MIN_VALUE.toLong()..Byte.MAX_VALUE.toLong(), -+ KotlinBuiltIns.FQ_NAMES._short to Short.MIN_VALUE.toLong()..Short.MAX_VALUE.toLong(), -+ KotlinBuiltIns.FQ_NAMES._int to Int.MIN_VALUE.toLong()..Int.MAX_VALUE.toLong(), -+ KotlinBuiltIns.FQ_NAMES._long to Long.MIN_VALUE..Long.MAX_VALUE -+) -+ -+class WrongPrimitiveLiteralFix(element: KtConstantExpression, type: KotlinType) : KotlinQuickFixAction(element) { -+ -+ private val typeName = DescriptorUtils.getFqName(type.constructor.declarationDescriptor!!) -+ private val expectedTypeIsFloat = KotlinBuiltIns.isFloat(type) -+ private val expectedTypeIsDouble = KotlinBuiltIns.isDouble(type) -+ private val constValue -+ = ExpressionCodegen.getPrimitiveOrStringCompileTimeConstant(element, element.analyze(BodyResolveMode.PARTIAL))?.value as? Number -+ -+ private val fixedExpression = buildString { -+ if (expectedTypeIsFloat || expectedTypeIsDouble) { -+ append(constValue) -+ if (expectedTypeIsFloat) { -+ append('F') -+ } -+ else if ('.' !in this) { -+ append("".0"") -+ } -+ } -+ else { -+ if (constValue is Float || constValue is Double) { -+ append(constValue.toLong()) -+ } -+ else { -+ append(element.text.takeWhile { it != 'l' && it != 'L' })","I'd rather use `element.text.trimEnd('l', 'L')` -",Remove this file -548,"@@ -0,0 +1,96 @@ -+fun Int.foo(a: Int = 1,","The correct spelling is `extension` :) -",Can you add a case for `a: Int = 2`? -549,"@@ -0,0 +1,98 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetBlockExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetWhileExpression -+import org.jetbrains.jet.lang.psi.JetIfExpression -+import org.jetbrains.jet.lang.psi.JetDoWhileExpression -+import org.jetbrains.jet.lang.psi.JetForExpression -+import org.jetbrains.jet.lang.psi.JetExpressionImpl -+import org.jetbrains.jet.lang.psi.psiUtil.findBlockInExpression -+import org.jetbrains.jet.JetNodeTypes -+import org.jetbrains.jet.lang.psi.psiUtil.getExpressionType -+import com.intellij.psi.PsiComment -+import com.intellij.psi.PsiElement -+import java.util.ArrayList -+import com.intellij.openapi.fileEditor.FileEditorManager -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiFile -+ -+ -+public class RemoveBracesIntention : JetSelfTargetingIntention(""remove.braces"", javaClass()) { -+ private var expressionType: String? = """" -+ private var caretLocation: Int = 1 -+ -+ override fun isAvailable(project: Project, editor: Editor, file: PsiFile): Boolean { -+ caretLocation = editor.getCaretModel().getOffset() -+ return getTarget(editor, file) != null -+ } -+ -+ override fun isApplicableTo(element: JetExpressionImpl): Boolean { -+ expressionType = element.getExpressionType(element) -+ if (expressionType == null) return false -+ -+ if (expressionType == ""else"") { -+ val elseLocation = (element as JetIfExpression).getElse()!!.getParent()!!.getTextOffset() - 5 -+ if (caretLocation < elseLocation) { -+ expressionType = ""if"" -+ } -+ } -+ -+ val jetBlockElement = element.findBlockInExpression(element, expressionType) -+ if (jetBlockElement == null) return false -+ -+ if (jetBlockElement!!.getStatements().size == 1) { -+ setText(""Remove braces from '$expressionType' statement"") -+ return true -+ } -+ return false -+ } -+ -+ override fun applyTo(element: JetExpressionImpl, editor: Editor) { -+ val jetBlockElement = element.findBlockInExpression(element, expressionType) -+ val firstStatement = jetBlockElement!!.getStatements().first() -+ -+ val comments = handleComment(jetBlockElement) -+ if (comments != null) { -+ //TODO - output comments on the line above the control statement -+ } -+ val newElement = jetBlockElement.replace(JetPsiFactory.createExpression(element.getProject(), firstStatement.getText())) -+ -+ if (expressionType == ""do...while"") { -+ newElement.getParent()!!.addAfter(JetPsiFactory.createNewLine(element.getProject()), newElement) -+ } -+ } -+ -+ fun handleComment(element: JetBlockExpression): ArrayList? {","With this function name, it's hard to guess what it does and what does it return. What about ""extractComments""? -It return `ArrayList`, while just `List` would be enough. -","Rather than introduce a new class, can " -550,"@@ -0,0 +1,98 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetBlockExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetWhileExpression -+import org.jetbrains.jet.lang.psi.JetIfExpression -+import org.jetbrains.jet.lang.psi.JetDoWhileExpression -+import org.jetbrains.jet.lang.psi.JetForExpression -+import org.jetbrains.jet.lang.psi.JetExpressionImpl -+import org.jetbrains.jet.lang.psi.psiUtil.findBlockInExpression -+import org.jetbrains.jet.JetNodeTypes -+import org.jetbrains.jet.lang.psi.psiUtil.getExpressionType -+import com.intellij.psi.PsiComment -+import com.intellij.psi.PsiElement -+import java.util.ArrayList -+import com.intellij.openapi.fileEditor.FileEditorManager -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiFile -+ -+ -+public class RemoveBracesIntention : JetSelfTargetingIntention(""remove.braces"", javaClass()) { -+ private var expressionType: String? = """" -+ private var caretLocation: Int = 1 -+ -+ override fun isAvailable(project: Project, editor: Editor, file: PsiFile): Boolean { -+ caretLocation = editor.getCaretModel().getOffset() -+ return getTarget(editor, file) != null -+ } -+ -+ override fun isApplicableTo(element: JetExpressionImpl): Boolean { -+ expressionType = element.getExpressionType(element) -+ if (expressionType == null) return false -+ -+ if (expressionType == ""else"") { -+ val elseLocation = (element as JetIfExpression).getElse()!!.getParent()!!.getTextOffset() - 5 -+ if (caretLocation < elseLocation) { -+ expressionType = ""if"" -+ } -+ } -+ -+ val jetBlockElement = element.findBlockInExpression(element, expressionType) -+ if (jetBlockElement == null) return false -+ -+ if (jetBlockElement!!.getStatements().size == 1) { -+ setText(""Remove braces from '$expressionType' statement"") -+ return true -+ } -+ return false -+ } -+ -+ override fun applyTo(element: JetExpressionImpl, editor: Editor) { -+ val jetBlockElement = element.findBlockInExpression(element, expressionType) -+ val firstStatement = jetBlockElement!!.getStatements().first() -+ -+ val comments = handleComment(jetBlockElement) -+ if (comments != null) { -+ //TODO - output comments on the line above the control statement -+ } -+ val newElement = jetBlockElement.replace(JetPsiFactory.createExpression(element.getProject(), firstStatement.getText())) -+ -+ if (expressionType == ""do...while"") { -+ newElement.getParent()!!.addAfter(JetPsiFactory.createNewLine(element.getProject()), newElement) -+ } -+ } -+ -+ fun handleComment(element: JetBlockExpression): ArrayList? { -+ val comments = ArrayList() -+ var sibling = element.getFirstChild() -+ if (sibling == null) return null -+ sibling = sibling?.getNextSibling()","This indent blows minds. I thought that this assignment relates to if. -Why safe call here? `sibling` is not null before assignment here. -","Rather than introduce a new class, can " -551,"@@ -0,0 +1,98 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetBlockExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetWhileExpression -+import org.jetbrains.jet.lang.psi.JetIfExpression -+import org.jetbrains.jet.lang.psi.JetDoWhileExpression -+import org.jetbrains.jet.lang.psi.JetForExpression -+import org.jetbrains.jet.lang.psi.JetExpressionImpl -+import org.jetbrains.jet.lang.psi.psiUtil.findBlockInExpression -+import org.jetbrains.jet.JetNodeTypes -+import org.jetbrains.jet.lang.psi.psiUtil.getExpressionType -+import com.intellij.psi.PsiComment -+import com.intellij.psi.PsiElement -+import java.util.ArrayList -+import com.intellij.openapi.fileEditor.FileEditorManager -+import com.intellij.openapi.project.Project -+import com.intellij.psi.PsiFile -+ -+ -+public class RemoveBracesIntention : JetSelfTargetingIntention(""remove.braces"", javaClass()) { -+ private var expressionType: String? = """" -+ private var caretLocation: Int = 1 -+ -+ override fun isAvailable(project: Project, editor: Editor, file: PsiFile): Boolean { -+ caretLocation = editor.getCaretModel().getOffset() -+ return getTarget(editor, file) != null -+ } -+ -+ override fun isApplicableTo(element: JetExpressionImpl): Boolean { -+ expressionType = element.getExpressionType(element) -+ if (expressionType == null) return false -+ -+ if (expressionType == ""else"") { -+ val elseLocation = (element as JetIfExpression).getElse()!!.getParent()!!.getTextOffset() - 5 -+ if (caretLocation < elseLocation) { -+ expressionType = ""if"" -+ } -+ } -+ -+ val jetBlockElement = element.findBlockInExpression(element, expressionType) -+ if (jetBlockElement == null) return false -+ -+ if (jetBlockElement!!.getStatements().size == 1) { -+ setText(""Remove braces from '$expressionType' statement"") -+ return true -+ } -+ return false -+ } -+ -+ override fun applyTo(element: JetExpressionImpl, editor: Editor) { -+ val jetBlockElement = element.findBlockInExpression(element, expressionType) -+ val firstStatement = jetBlockElement!!.getStatements().first() -+ -+ val comments = handleComment(jetBlockElement) -+ if (comments != null) { -+ //TODO - output comments on the line above the control statement -+ } -+ val newElement = jetBlockElement.replace(JetPsiFactory.createExpression(element.getProject(), firstStatement.getText())) -+ -+ if (expressionType == ""do...while"") { -+ newElement.getParent()!!.addAfter(JetPsiFactory.createNewLine(element.getProject()), newElement) -+ } -+ } -+ -+ fun handleComment(element: JetBlockExpression): ArrayList? { -+ val comments = ArrayList() -+ var sibling = element.getFirstChild() -+ if (sibling == null) return null -+ sibling = sibling?.getNextSibling() -+ -+ while (sibling != null) { -+ if (sibling is PsiComment) { -+ comments.add(sibling as PsiComment) -+ } -+ sibling = sibling?.getNextSibling()","Another redundant safe call. -","Rather than introduce a new class, can " -552,"@@ -0,0 +1,98 @@ -+class A(val a: Int = 1, -+ val b: Int = 2, -+ val c: Int = 3, -+ val d: Int = 4, -+ val e: Int = 5, -+ val f: Int = 6, -+ val g: Int = 7, -+ val h: Int = 8, -+ val i: Int = 9, -+ val j: Int = 10, -+ val k: Int = 11, -+ val l: Int = 12, -+ val m: Int = 13, -+ val n: Int = 14, -+ val o: Int = 15, -+ val p: Int = 16, -+ val q: Int = 17, -+ val r: Int = 18, -+ val s: Int = 19, -+ val t: Int = 20, -+ val u: Int = 21, -+ val v: Int = 22, -+ val w: Int = 23, -+ val x: Int = 24, -+ val y: Int = 25, -+ val z: Int = 26, -+ val aa: Int = 27, -+ val bb: Int = 28, -+ val cc: Int = 29, -+ val dd: Int = 30, -+ val ee: Int = 31, -+ val ff: Int = 32, -+ val gg: Int = 33, -+ val hh: Int = 34, -+ val ii: Int = 35, -+ val jj: Int = 36, -+ val kk: Int = 37, -+ val ll: Int = 38, -+ val mm: Int = 39, -+ val nn: Int = 40, -+ val oo: Int = 41, -+ val pp: Int = 42, -+ val qq: Int = 43, -+ val rr: Int = 44, -+ val ss: Int = 45, -+ val tt: Int = 46, -+ val uu: Int = 47, -+ val vv: Int = 48, -+ val ww: Int = 49, -+ val xx: Int = 50, -+ val yy: Int = 51, -+ val zz: Int = 52, -+ val aaa: Int = 53, -+ val bbb: Int = 54, -+ val ccc: Int = 55, -+ val ddd: Int = 56, -+ val eee: Int = 57, -+ val fff: Int = 58, -+ val ggg: Int = 59, -+ val hhh: Int = 60, -+ val iii: Int = 61, -+ val jjj: Int = 62, -+ val kkk: Int = 63, -+ val lll: Int = 64, -+ val mmm: Int = 65, -+ val nnn: Int = 66, -+ val ooo: Int = 67, -+ val ppp: Int = 68, -+ val qqq: Int = 69, -+ val rrr: Int = 70) { -+ override fun toString(): String { -+ return ""$a $b $c $d $e $f $g $h $i $j $k $l $m $n $o $p $q $r $s $t $u $v $w $x $y $z $aa $bb $cc $dd $ee $ff $gg $hh $ii $jj $kk "" + -+ ""$ll $mm $nn $oo $pp $qq $rr $ss $tt $uu $vv $ww $xx $yy $zz $aaa $bbb $ccc $ddd $eee $fff $ggg $hhh $iii $jjj $kkk $lll "" + -+ ""$mmm $nnn $ooo $ppp $qqq $rrr"" -+ } -+} -+ -+fun box(): String { -+ val test1 = A(5, f = 3, w = 1, aa = 71, nn = 2, qq = 15, ww = 97, aaa = 261258, iii = 3, nnn = 8, rrr = 7).toString() -+ val test2 = A().toString() -+ val test3 = A(70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, -+ 40, 39, 38, 37, 36, jj = 35, kk = 34, ll = 33, mm = 32, nn = 31, oo = 30, pp = 29, qq = 28, rr = 27, ss = 26, tt = 25, -+ uu = 24, vv = 23, ww = 22, xx = 21, yy = 20, zz = 19, aaa = 18, bbb = 17, ccc = 16, ddd = 15, eee = 14, fff = 13, -+ ggg = 12, hhh = 11, iii = 10, jjj = 9, kkk = 8, lll = 7, mmm = 6, nnn = 5, ooo = 4, ppp = 3, qqq = 2, rrr = 1).toString() -+ if (test1 != ""5 2 3 4 5 3 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 24 25 26 71 28 29 30 31 32 33 34 35 36 37 38 39 2 41 42 15 "" + -+ ""44 45 46 47 48 97 50 51 52 261258 54 55 56 57 58 59 60 3 62 63 64 65 8 67 68 69 7"") { -+ return test1 -+ } -+ if (test2 != ""1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 "" + -+ ""43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70"") { -+ return test2 -+ } -+ if (test3 != ""70 69 68 67 66 65 64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 "" + -+ ""31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1"") { -+ return test3 -+ } -+ return ""OK""","Unfortunately no test checks the introduced behavior in `FunctionCodegen#generateConstructorWithoutParametersIfNeeded()`. - -This test looks almost as if it does, but `A()` here is only a syntactic sugar for invoking the `$default` method :) - -To test precisely the synthetic no-args constructor we generate for a class whose constructor's arguments are all default, you could either invoke it from Java or call it reflectively via `newInstance` (I recommend the latter). -",I think this is missing a `val s: Int = -553,"@@ -0,0 +1,99 @@ -+/* -+ * Copyright 2010-2014 JetBrains s.r.o. -+ * -+ * Licensed under the Apache License, Version 2.0 (the ""License""); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an ""AS IS"" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package org.jetbrains.jet.plugin.intentions -+ -+import com.intellij.openapi.editor.Editor -+import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression -+import org.jetbrains.jet.lang.psi.JetCallExpression -+import org.jetbrains.jet.lang.psi.JetExpression -+import org.jetbrains.jet.lang.psi.JetPsiFactory -+import org.jetbrains.jet.lang.psi.JetValueArgument -+import org.jetbrains.jet.lang.psi.JetValueArgumentList -+import org.jetbrains.jet.lang.psi.JetNamedArgumentImpl -+import org.jetbrains.jet.lang.psi.JetValueArgumentName -+import org.jetbrains.jet.plugin.references.JetSimpleNameReference -+import org.jetbrains.jet.lang.psi.JetBinaryExpression -+import org.jetbrains.jet.lang.psi.JetPostfixExpression -+import org.jetbrains.jet.lang.psi.JetTypeArgumentList -+ -+public class ReplaceGetCallWithArrayAccessIntention : JetSelfTargetingIntention(""replace.get.call.with.array.access"", javaClass()) { -+ override fun isApplicableTo(element: JetExpression): Boolean { -+ fun methodCallCheck(expression: JetDotQualifiedExpression): Boolean { -+ val selector = expression.getSelectorExpression() -+ val receiver = expression.getReceiverExpression() -+ -+ if (selector is JetCallExpression && !(receiver is JetPostfixExpression)) { -+ val callee = selector.getCalleeExpression() -+ val arguments = selector.getValueArgumentList() -+ val typeArguments = selector.getTypeArgumentList() -+ -+ return arguments != null -+ && typeArguments == null -+ && !arguments.getArguments().any { (arg): Boolean -> arg.getArgumentName() != null }","Specifying return type in function literal is redundant here. Explicit parameter can be also omitted (""it"" name will be auto-generated for it). -",missing a license header -554,"@@ -0,0 +1,99 @@ -+/* -+ * 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.inspections -+ -+import com.intellij.codeInspection.* -+import com.intellij.openapi.project.Project -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.* -+import org.jetbrains.kotlin.psi.psiUtil.getCallNameExpression -+ -+class KotlinRedundantOverrideInspection : AbstractKotlinInspection(), CleanupLocalInspectionTool { -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession) = -+ object : KtVisitorVoid() { -+ override fun visitNamedFunction(function: KtNamedFunction) { -+ super.visitNamedFunction(function) -+ if (!function.hasModifier(KtTokens.OVERRIDE_KEYWORD)) return -+ -+ val bodyExpression = function.bodyExpression -+ bodyExpression ?: return -+ -+ val body = if (bodyExpression is KtDotQualifiedExpression) { -+ bodyExpression -+ } -+ else { -+ if (bodyExpression.children.size != 1) { -+ return -+ } -+ bodyExpression.children[0]",You could use `singleOrNull() ?: return` here.,This file needs to be renamed. -555,"@@ -0,0 +1,99 @@ -+/* -+ * 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.inspections -+ -+import com.intellij.codeInspection.* -+import com.intellij.openapi.project.Project -+import org.jetbrains.kotlin.lexer.KtTokens -+import org.jetbrains.kotlin.psi.* -+import org.jetbrains.kotlin.psi.psiUtil.getCallNameExpression -+ -+class KotlinRedundantOverrideInspection : AbstractKotlinInspection(), CleanupLocalInspectionTool { -+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession) = -+ object : KtVisitorVoid() { -+ override fun visitNamedFunction(function: KtNamedFunction) { -+ super.visitNamedFunction(function) -+ if (!function.hasModifier(KtTokens.OVERRIDE_KEYWORD)) return -+ -+ val bodyExpression = function.bodyExpression -+ bodyExpression ?: return -+ -+ val body = if (bodyExpression is KtDotQualifiedExpression) { -+ bodyExpression -+ } -+ else { -+ if (bodyExpression.children.size != 1) { -+ return -+ } -+ bodyExpression.children[0] -+ } -+ -+ val qualifiedExpression = if (body is KtReturnExpression) { -+ val returnedExpression = body.returnedExpression -+ returnedExpression ?: return -+ returnedExpression as? KtDotQualifiedExpression ?: return -+ } -+ else { -+ body as? KtDotQualifiedExpression ?: return -+ } -+ -+ if (qualifiedExpression.receiverExpression !is KtSuperExpression) return -+ -+ val superSelectorExpression = qualifiedExpression.selectorExpression -+ val superCallElement = superSelectorExpression as? KtCallElement ?: return -+ -+ if (!isSameFunctionName(superSelectorExpression, function)) return",I can use `superCallElement` for the argument. I will fix it.,This file needs to be renamed. -556,"@@ -1,11 +1,11 @@ - - - -- -+ ","Changes like this in meta-information should be carefully reviewed before committing, because they can easily break compilation or workflow for other developers. -",Is this the right place for this? I'm n -557,"@@ -1,15 +1,15 @@ - package kotlin - - /** -- * Creates a tuple of type [[Pair]] from this and *that* which can be useful for creating [[Map]] literals -- * with less noise, for example -- -- * @includeFunctionBody ../../test/collections/MapTest.kt createUsingTo -+ * Creates a tuple of type [Pair] from this and [that]. -+ * -+ * This can be useful for creating [Map] literals with less noise, for example: -+ * @sample test.collections.MapTest.createUsingTo - */ - public fun A.to(that: B): Pair = Pair(this, that) - - /** --Run function f -+ * Runs the specified function.","Runs -> Calls? -",This should be `@sample` instead of `@i -558,"@@ -1,3 +1,19 @@ -+/*","It's added by IDEA's pre-commit action. Really shouldn't for generated files. -",Please remove this file. -559,"@@ -1,3 +1,3 @@ - package test - --fun lll(a: Int) = a -+fun lll(a: kotlin.Int) = a",Here we have `kotlin.` added too,I'm tempted to keep this as `Int` for c -560,"@@ -1,4 +1,4 @@ - package test - - // extra parameter is to make sure generic signature is not erased --fun doNothing(array: IntArray, ignore: java.util.List) = array -+fun doNothing(array: kotlin.IntArray, ignore: java.util.List) = array",And here we have `kotlin.` too,Why not just use `kotlin.IntArray`? -561,"@@ -1,4 +1,4 @@ - package test - - // extra parameter is to preserve generic signature --fun anyany(a: Any, ignore: java.util.List) = a -+fun anyany(a: kotlin.Any, ignore: java.util.List) = a",Unclear. Why should you have `kotlin.` here and how it works without it?,I tried removing `Any` from `kotlin -562,"@@ -1,4 +1,5 @@ - package org.junit - -+@Deprecated(""Use 'Test' from kotlin.test package"", replaceWith = ReplaceWith(""Test"", imports = ""kotlin.test.Test""))",👍 ,Why do you need to replace the impo -563,"@@ -1,6 +1,10 @@ - // ""Change 'foo' function return type to '([ERROR : NoSuchType]) -> Int'"" ""false"" -+// ACTION: Disable 'Make Types Implicit In Lambda' -+// ACTION: Edit intention settings -+// ACTION: Make types implicit in lambda","Note that this test is now failing again due to obvious reasons :) -",Perhaps add a note here that types -564,"@@ -1,7 +1,6 @@ - fun foo() { -- val a: kotlin.test.Asserter? -- if () { -- a = null -+ val a = if () {","It's not OK that you're losing the variable type here. -",The `else` clause is unnecessary he -565,"@@ -1,72 +0,0 @@ --/* -- * Copyright 2010-2015 JetBrains s.r.o. -- * -- * Licensed under the Apache License, Version 2.0 (the ""License""); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an ""AS IS"" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --package org.jetbrains.kotlin.idea.quickfix -- --import org.jetbrains.kotlin.psi.* --import kotlin.platform.* --import org.jetbrains.kotlin.diagnostics.* --import com.intellij.codeInsight.intention.* --import org.jetbrains.kotlin.idea.* --import com.intellij.openapi.project.* --import com.intellij.openapi.editor.* --import com.intellij.psi.* --import org.jetbrains.kotlin.idea.project.PluginJetFilesProvider --import org.jetbrains.kotlin.idea.quickfix.quickfixUtil.createIntentionFactory --import org.jetbrains.kotlin.idea.quickfix.quickfixUtil.createIntentionForFirstParentOfType --import org.jetbrains.kotlin.lexer.JetTokens --import org.jetbrains.kotlin.psi.psiUtil.* --import java.util.ArrayList -- -- --public class AddInitKeywordFix(element: JetClassInitializer) : JetIntentionAction(element) { -- override fun getText() = JetBundle.message(""add.init.keyword"") -- -- override fun getFamilyName() = JetBundle.message(""add.init.keyword.family"") -- -- override fun invoke(project: Project, editor: Editor?, file: JetFile) { -- addInitKeyword(element) -- } -- -- companion object Factory : JetSingleIntentionActionFactory() { -- override fun createAction(diagnostic: Diagnostic) = diagnostic.createIntentionForFirstParentOfType(::AddInitKeywordFix) -- -- public fun createWholeProjectFixFactory(): JetSingleIntentionActionFactory = createIntentionFactory { -- JetWholeProjectForEachElementOfTypeFix.createByPredicate( -- predicate = { !it.hasInitKeyword() }, -- taskProcessor = { addInitKeyword(it) }, -- modalTitle = JetBundle.message(""add.init.keyword.in.whole.project.modal.title""), -- name = JetBundle.message(""add.init.keyword.in.whole.project""), -- familyName = JetBundle.message(""add.init.keyword.in.whole.project.family"") -- ) -- } -- -- private fun addInitKeyword(element: JetClassInitializer) { -- if (element.hasInitKeyword()) return -- -- val psiFactory = JetPsiFactory(element) -- val initKeyword = psiFactory.createInitKeyword()","JetPsiFactory.createInitKeyword became unused -",Why did you remove this file? -566,"@@ -1,8 +1,9 @@ - object A { - @JvmStatic fun main(args: Array) { -- println(Void.TYPE) -- println(Integer.TYPE) -- println(java.lang.Double.TYPE) -+ println(Unit::class.javaPrimitiveType)","This doesn't actually work: `Unit` has no `javaPrimitiveType`. For `void.class`, the previous variant of the code should be used. -","I believe this line can be removed," -567,"@@ -10,21 +10,34 @@ import kotlin.jvm.internal.Intrinsic - * - * Example: - * -- * throws(javaClass()) -- * fun readFile(name: String): String {...} -+ * ``` -+ * throws(javaClass()) -+ * fun readFile(name: String): String {...} -+ * ``` - * - * will be translated to - * -- * String readFile(String name) throws IOException {...} -+ * ``` -+ * String readFile(String name) throws IOException {...} -+ * ``` - */ - Retention(RetentionPolicy.SOURCE) - public annotation class throws(public vararg val exceptionClasses: Class) - -+/** -+ * Returns the runtime Java class of this object. -+ */ - [Intrinsic(""kotlin.javaClass.property"")] public val T.javaClass : Class - get() = (this as java.lang.Object).getClass() as Class - -+/** -+ * Returns the Java class for the specified type. -+ */ - [Intrinsic(""kotlin.javaClass.function"")] public fun javaClass(): Class = null as Class - -+/** -+ * Executes the given function [block] while holding the monitor of the given object [lock].","Somewhere I saw you called it ""semaphore"", and here calling ""monitor"" -",Minor typo: `the runtime` -> `the r -568,"@@ -10,6 +10,12 @@ class BasicAssertionsTest { - } - - @Test -+ fun testAssertSame() {","`test` prefix reminds me old days of `JUnit`, where it was obligatory to run any test :-) - -Could you tell me why there is doubled `kotlin` and `test` packages in path: `kotlin/libraries/kotlin.test/common/src/test/kotlin/kotlin/test/tests/`? Just wondering.",Don't we have a `@Rule` for that? -569,"@@ -10,6 +10,12 @@ package kotlin.text - public inline fun buildString(builderAction: StringBuilder.() -> Unit): String = StringBuilder().apply(builderAction).toString() - - /** -+ * Builds new string by populating newly created [StringBuilder] initialized with the given capacity using provided [builderAction] and then converting it to [String]. -+ */","Will fix formatting upon rebase. -",This method should return `StringBu -570,"@@ -10,6 +10,12 @@ package kotlin.text - public inline fun buildString(builderAction: StringBuilder.() -> Unit): String = StringBuilder().apply(builderAction).toString() - - /** -+ * Builds new string by populating newly created [StringBuilder] initialized with the given capacity using provided [builderAction] and then converting it to [String]. -+ */ -+@kotlin.internal.InlineOnly -+inline fun buildString(length : Int, builderAction: StringBuilder.() -> Unit): String = StringBuilder(length).apply(builderAction).toString()","Constructor parameter is called `capacity` so it should have the same name here. -Also there should be no space before `:` in parameter definition. -",I'm not convinced the `@kotlin.inte -571,"@@ -10,9 +10,9 @@ import java.util.* - import java.util.Collections // TODO: it's temporary while we have java.util.Collections in js - - /** -- * Appends the string from all the elements separated using the *separator* and using the given *prefix* and *postfix* if supplied -- * If a collection could be huge you can specify a non-negative value of *limit* which will only show a subset of the collection then it will -- * a special *truncated* separator (which defaults to ""..."") -+ * Appends the string from all the elements separated using [separator] and using the given [prefix] and *postfix* if supplied.","Linkify `postfix` -",why not also append using `*separat -572,"@@ -10,9 +10,9 @@ import java.util.* - import java.util.Collections // TODO: it's temporary while we have java.util.Collections in js - - /** -- * Appends the string from all the elements separated using the *separator* and using the given *prefix* and *postfix* if supplied -- * If a collection could be huge you can specify a non-negative value of *limit* which will only show a subset of the collection then it will -- * a special *truncated* separator (which defaults to ""..."") -+ * Appends the string from all the elements separated using [separator] and using the given [prefix] and *postfix* if supplied. -+ * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] -+ * elements will be appended, followed by the [truncated] string (which defaults to ""..."").","Ideally `trucated` should default to ""…"", not ""..."" -",[limit] instead of [separator] ? -573,"@@ -100,65 +181,143 @@ public class Byte private () : Number, Comparable { - * On the JVM, non-nullable values of this type are represented as values of the primitive type `char`. - */ - public class Char private () : Comparable { -- class object {} -+ default object {} - -+/** -+ * Compares this value with the specified value for order. -+ * Returns zero if this value is equal to the specified other value, a negative number if its less than other, -+ * or a positive number if its greater than other. -+ */ - public fun compareTo(other: Byte): Int -+/** -+ * Compares this value with the specified value for order. -+ * Returns zero if this value is equal to the specified other value, a negative number if its less than other, -+ * or a positive number if its greater than other. -+ */ - public override fun compareTo(other: Char): Int -+/** -+ * Compares this value with the specified value for order. -+ * Returns zero if this value is equal to the specified other value, a negative number if its less than other, -+ * or a positive number if its greater than other. -+ */ - public fun compareTo(other: Short): Int -+/** -+ * Compares this value with the specified value for order. -+ * Returns zero if this value is equal to the specified other value, a negative number if its less than other, -+ * or a positive number if its greater than other. -+ */ - public fun compareTo(other: Int): Int -+/** -+ * Compares this value with the specified value for order. -+ * Returns zero if this value is equal to the specified other value, a negative number if its less than other, -+ * or a positive number if its greater than other. -+ */ - public fun compareTo(other: Long): Int -+/** -+ * Compares this value with the specified value for order. -+ * Returns zero if this value is equal to the specified other value, a negative number if its less than other, -+ * or a positive number if its greater than other. -+ */ - public fun compareTo(other: Float): Int -+/** -+ * Compares this value with the specified value for order. -+ * Returns zero if this value is equal to the specified other value, a negative number if its less than other, -+ * or a positive number if its greater than other. -+ */ - public fun compareTo(other: Double): Int - -+ /** Adds the two values. */ - public fun plus(other: Byte): Int -+ /** Adds the two values. */ - public fun plus(other: Short): Int -+ /** Adds the two values. */ - public fun plus(other: Int): Int -+ /** Adds the two values. */ - public fun plus(other: Long): Long -+ /** Adds the two values. */ - public fun plus(other: Float): Float -+ /** Adds the two values. */ - public fun plus(other: Double): Double - -+ /** Subtracts the other value from this value. */ - public fun minus(other: Byte): Int -+ /** Subtracts the other value from this value. */ - public fun minus(other: Char): Int -+ /** Subtracts the other value from this value. */ - public fun minus(other: Short): Int -+ /** Subtracts the other value from this value. */ - public fun minus(other: Int): Int -+ /** Subtracts the other value from this value. */ - public fun minus(other: Long): Long -+ /** Subtracts the other value from this value. */ - public fun minus(other: Float): Float -+ /** Subtracts the other value from this value. */ - public fun minus(other: Double): Double - -+ /** Multiplies the two values. */ - public fun times(other: Byte): Int -+ /** Multiplies the two values. */ - public fun times(other: Short): Int -+ /** Multiplies the two values. */ - public fun times(other: Int): Int -+ /** Multiplies the two values. */ - public fun times(other: Long): Long -+ /** Multiplies the two values. */ - public fun times(other: Float): Float -+ /** Multiplies the two values. */ - public fun times(other: Double): Double - -+ /** Divides this value by the other value. */ - public fun div(other: Byte): Int -+ /** Divides this value by the other value. */ - public fun div(other: Short): Int -+ /** Divides this value by the other value. */ - public fun div(other: Int): Int -+ /** Divides this value by the other value. */ - public fun div(other: Long): Long -+ /** Divides this value by the other value. */ - public fun div(other: Float): Float -+ /** Divides this value by the other value. */ - public fun div(other: Double): Double - -+ /** Calculates the remainder of dividing this value by the other value. */ - public fun mod(other: Byte): Int -+ /** Calculates the remainder of dividing this value by the other value. */ - public fun mod(other: Short): Int -+ /** Calculates the remainder of dividing this value by the other value. */ - public fun mod(other: Int): Int -+ /** Calculates the remainder of dividing this value by the other value. */ - public fun mod(other: Long): Long -+ /** Calculates the remainder of dividing this value by the other value. */ - public fun mod(other: Float): Float -+ /** Calculates the remainder of dividing this value by the other value. */ - public fun mod(other: Double): Double - -+ /** Increments this value. */ - public fun inc(): Char -+ /** Decrements this value. */ - public fun dec(): Char -+ /** Returns this value. */ - public fun plus(): Int -+ /** Returns the negative of this value. */ - public fun minus(): Int - -+ /** Creates a range from this value to the specified [other] value. */ - public fun rangeTo(other: Char): CharRange","We don't have other overloads for rangeTo, like in other types? -","What does ""a negative number if its" -574,"@@ -100,65 +181,143 @@ public class Byte private () : Number, Comparable { - * On the JVM, non-nullable values of this type are represented as values of the primitive type `char`. - */ - public class Char private () : Comparable { -- class object {} -+ default object {} - -+/** -+ * Compares this value with the specified value for order. -+ * Returns zero if this value is equal to the specified other value, a negative number if its less than other, -+ * or a positive number if its greater than other. -+ */ - public fun compareTo(other: Byte): Int -+/** -+ * Compares this value with the specified value for order. -+ * Returns zero if this value is equal to the specified other value, a negative number if its less than other, -+ * or a positive number if its greater than other. -+ */ - public override fun compareTo(other: Char): Int -+/** -+ * Compares this value with the specified value for order. -+ * Returns zero if this value is equal to the specified other value, a negative number if its less than other, -+ * or a positive number if its greater than other. -+ */ - public fun compareTo(other: Short): Int -+/** -+ * Compares this value with the specified value for order. -+ * Returns zero if this value is equal to the specified other value, a negative number if its less than other, -+ * or a positive number if its greater than other. -+ */ - public fun compareTo(other: Int): Int -+/** -+ * Compares this value with the specified value for order. -+ * Returns zero if this value is equal to the specified other value, a negative number if its less than other, -+ * or a positive number if its greater than other. -+ */ - public fun compareTo(other: Long): Int -+/** -+ * Compares this value with the specified value for order. -+ * Returns zero if this value is equal to the specified other value, a negative number if its less than other, -+ * or a positive number if its greater than other. -+ */ - public fun compareTo(other: Float): Int -+/** -+ * Compares this value with the specified value for order. -+ * Returns zero if this value is equal to the specified other value, a negative number if its less than other, -+ * or a positive number if its greater than other. -+ */ - public fun compareTo(other: Double): Int - -+ /** Adds the two values. */ - public fun plus(other: Byte): Int -+ /** Adds the two values. */ - public fun plus(other: Short): Int -+ /** Adds the two values. */ - public fun plus(other: Int): Int -+ /** Adds the two values. */ - public fun plus(other: Long): Long -+ /** Adds the two values. */ - public fun plus(other: Float): Float -+ /** Adds the two values. */ - public fun plus(other: Double): Double - -+ /** Subtracts the other value from this value. */ - public fun minus(other: Byte): Int -+ /** Subtracts the other value from this value. */ - public fun minus(other: Char): Int -+ /** Subtracts the other value from this value. */ - public fun minus(other: Short): Int -+ /** Subtracts the other value from this value. */ - public fun minus(other: Int): Int -+ /** Subtracts the other value from this value. */ - public fun minus(other: Long): Long -+ /** Subtracts the other value from this value. */ - public fun minus(other: Float): Float -+ /** Subtracts the other value from this value. */ - public fun minus(other: Double): Double - -+ /** Multiplies the two values. */ - public fun times(other: Byte): Int -+ /** Multiplies the two values. */ - public fun times(other: Short): Int -+ /** Multiplies the two values. */ - public fun times(other: Int): Int -+ /** Multiplies the two values. */ - public fun times(other: Long): Long -+ /** Multiplies the two values. */ - public fun times(other: Float): Float -+ /** Multiplies the two values. */ - public fun times(other: Double): Double - -+ /** Divides this value by the other value. */ - public fun div(other: Byte): Int -+ /** Divides this value by the other value. */ - public fun div(other: Short): Int -+ /** Divides this value by the other value. */ - public fun div(other: Int): Int -+ /** Divides this value by the other value. */ - public fun div(other: Long): Long -+ /** Divides this value by the other value. */ - public fun div(other: Float): Float -+ /** Divides this value by the other value. */ - public fun div(other: Double): Double - -+ /** Calculates the remainder of dividing this value by the other value. */ - public fun mod(other: Byte): Int -+ /** Calculates the remainder of dividing this value by the other value. */ - public fun mod(other: Short): Int -+ /** Calculates the remainder of dividing this value by the other value. */ - public fun mod(other: Int): Int -+ /** Calculates the remainder of dividing this value by the other value. */ - public fun mod(other: Long): Long -+ /** Calculates the remainder of dividing this value by the other value. */ - public fun mod(other: Float): Float -+ /** Calculates the remainder of dividing this value by the other value. */ - public fun mod(other: Double): Double - -+ /** Increments this value. */ - public fun inc(): Char -+ /** Decrements this value. */ - public fun dec(): Char -+ /** Returns this value. */ - public fun plus(): Int -+ /** Returns the negative of this value. */ - public fun minus(): Int - -+ /** Creates a range from this value to the specified [other] value. */ - public fun rangeTo(other: Char): CharRange - -+ /** Returns the value of this character as a `name`. */","As a name? -","What does ""a negative number if its" -575,"@@ -105,8 +105,19 @@ public KotlinTypeInfo visitIfExpression(KtIfExpression ifExpression, ExpressionT - - LexicalWritableScope thenScope = newWritableScopeImpl(context, LexicalScopeKind.THEN, components.overloadChecker); - LexicalWritableScope elseScope = newWritableScopeImpl(context, LexicalScopeKind.ELSE, components.overloadChecker); -- DataFlowInfo thenInfo = components.dataFlowAnalyzer.extractDataFlowInfoFromCondition(condition, true, context).and(conditionDataFlowInfo); -- DataFlowInfo elseInfo = components.dataFlowAnalyzer.extractDataFlowInfoFromCondition(condition, false, context).and(conditionDataFlowInfo); -+ DataFlowInfo basicThenInfo = components.dataFlowAnalyzer.extractDataFlowInfoFromCondition(condition, true, context).and(conditionDataFlowInfo); -+ DataFlowInfo thenInfoFromES = components.effectSystem.getConditionalInfoForThenBranch(",I'd expect here some language feature check.,Similar blocks of code found in 2 l -576,"@@ -107,29 +106,38 @@ protected ExitCode doExecute( - Project project = environmentForJS.getProject(); - List sourcesFiles = environmentForJS.getSourceFiles(); - -- if (arguments.verbose) { -- reportCompiledSourcesList(messageCollector, sourcesFiles); -+ if (arguments.outputFile == null) { -+ messageSeverityCollector.report(CompilerMessageSeverity.ERROR, ""Specify output file via -output"", CompilerMessageLocation.NO_LOCATION); -+ return ExitCode.INTERNAL_ERROR; - } - -- if (arguments.outputFile == null) { -- messageCollector.report(CompilerMessageSeverity.ERROR, ""Specify output file via -output"", CompilerMessageLocation.NO_LOCATION); -+ if (messageSeverityCollector.anyReported(CompilerMessageSeverity.ERROR)) { - return ExitCode.INTERNAL_ERROR; - } - -+ if (sourcesFiles.isEmpty()) { -+ messageSeverityCollector.report(CompilerMessageSeverity.ERROR, ""No source files"", CompilerMessageLocation.NO_LOCATION); -+ return COMPILATION_ERROR;","Maybe we should have another exit code for such cases? e.g. `ILLEGAL_ARGUMENTS_ERROR`. - -//cc @udalov -","Maybe ""Specify an output file via -output""?" -577,"@@ -110,7 +149,10 @@ fun createContainerForLazyResolveWithJava( - useImpl() - } - }.apply { -- get().initialize(bindingTrace, get()) -+ if (useJavac) -+ get().initialize(bindingTrace, get())",I'd write here `JavacBasedClassFinder`. The current name is too close to just `JavaClassFinder`.,Do we still need to pass in the `JavacClass -578,"@@ -111,7 +114,9 @@ interface ReplEvalAction { - - sealed class ReplEvalResult : Serializable { - class ValueResult(val value: Any?) : ReplEvalResult() { -- override fun toString(): String = ""Result: $value"" -+ val type = LastInferredTypeHolder.inferredType.get()",I think you can obtain this type from `compileResult` at `GenericReplEvaluator.eval` and pass to `ValueResult`'s constructor here,Please don't make any changes to the `Value -579,"@@ -112,9 +112,18 @@ class MemberVisibilityCanPrivateInspection : AbstractKotlinInspection() { - else -> ""Property"" - } - val nameElement = (declaration as? PsiNameIdentifierOwner)?.nameIdentifier ?: return -- holder.registerProblem(declaration.visibilityModifier() ?: nameElement, -+ val visibilityModifier = declaration.visibilityModifier() -+ val fix = object : AddModifierFix(modifierListOwner, KtTokens.PRIVATE_KEYWORD) {","I would do this as a general fix to AddModifierFix (which already has special logic for handling modality modifiers), not as a single-case override here.",Any reason why you didn't use `RegisterProb -580,"@@ -112,9 +112,20 @@ void parseFile() { - parseTopLevelDeclaration(); - } - -+ checkUnclosedBlockComment(); - fileMarker.done(KT_FILE); - } - -+ private void checkUnclosedBlockComment() { -+ if (TokenSet.create(BLOCK_COMMENT, DOC_COMMENT).contains(myBuilder.rawLookup(-1))) { -+ int startOffset = myBuilder.rawTokenTypeStart(-1); -+ int endOffset = myBuilder.rawTokenTypeStart(0); -+ if (!myBuilder.getOriginalText().subSequence(startOffset, endOffset).toString().endsWith(""*/"")) {","This may materialize a huge file as a single string (in case of this file being commented entirely) - -We could probably use other means, such as: -- changing the lexer to emit a special token type on unfinished comments -- using the CharSequence API to only materialize the last two characters as String, and not the entire text -",end of `myBuilder.rawLookup(-1)` could be e -581,"@@ -112,9 +112,20 @@ void parseFile() { - parseTopLevelDeclaration(); - } - -+ checkUnclosedBlockComment(); - fileMarker.done(KT_FILE); - } - -+ private void checkUnclosedBlockComment() { -+ if (TokenSet.create(BLOCK_COMMENT, DOC_COMMENT).contains(myBuilder.rawLookup(-1))) { -+ int startOffset = myBuilder.rawTokenTypeStart(-1); -+ int endOffset = myBuilder.rawTokenTypeStart(0); -+ if (!myBuilder.getOriginalText().subSequence(startOffset, endOffset).toString().endsWith(""*/"")) { -+ error(""Unclosed comment"");","This error is placed before the comment, in Java it is at the end of the file -",end of `myBuilder.rawLookup()` could be ext -582,"@@ -114,15 +116,28 @@ class KotlinQuickDocumentationProvider : AbstractDocumentationProvider() { - return null - } - -- private fun renderKotlinDeclaration(declaration: KtDeclaration, quickNavigation: Boolean): String { -+ private fun renderKotlinDeclaration(declaration: KtExpression, quickNavigation: Boolean): String { - val context = declaration.analyze(BodyResolveMode.PARTIAL) -- var declarationDescriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, declaration] -+ val declarationDescriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, declaration] - - if (declarationDescriptor == null) { - LOG.info(""Failed to find descriptor for declaration "" + declaration.getElementTextWithContext()) - return ""No documentation available"" - } - -+ return renderKotlin(context, declarationDescriptor, quickNavigation) -+ } -+ -+ private fun renderKotlinImplicitLambdaParameter(element: KtReferenceExpression, quickNavigation: Boolean): String? { -+ val context = element.analyze(BodyResolveMode.PARTIAL) -+ val target = element.mainReference.resolveToDescriptors(context).singleOrNull() as? ValueParameterDescriptor? ?: return null -+ context.get(BindingContext.AUTO_CREATED_IT, target)","This line doesn't do anything -",Rename the method to `renderKotlinDeclarati -583,"@@ -114,15 +116,28 @@ class KotlinQuickDocumentationProvider : AbstractDocumentationProvider() { - return null - } - -- private fun renderKotlinDeclaration(declaration: KtDeclaration, quickNavigation: Boolean): String { -+ private fun renderKotlinDeclaration(declaration: KtExpression, quickNavigation: Boolean): String { - val context = declaration.analyze(BodyResolveMode.PARTIAL) -- var declarationDescriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, declaration] -+ val declarationDescriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, declaration] - - if (declarationDescriptor == null) { - LOG.info(""Failed to find descriptor for declaration "" + declaration.getElementTextWithContext()) - return ""No documentation available"" - } - -+ return renderKotlin(context, declarationDescriptor, quickNavigation) -+ } -+ -+ private fun renderKotlinImplicitLambdaParameter(element: KtReferenceExpression, quickNavigation: Boolean): String? { -+ val context = element.analyze(BodyResolveMode.PARTIAL) -+ val target = element.mainReference.resolveToDescriptors(context).singleOrNull() as? ValueParameterDescriptor? ?: return null -+ context.get(BindingContext.AUTO_CREATED_IT, target) -+ return renderKotlin(context, target, quickNavigation) -+ } -+ -+ private fun renderKotlin(context: BindingContext, declarationDescriptor: DeclarationDescriptor, quickNavigation: Boolean): String { -+ @Suppress(""NAME_SHADOWING"") -+ var declarationDescriptor = declarationDescriptor","This doesn't seem to be needed, either -",Rename the method to `renderKotlinDeclarati -584,"@@ -115,9 +116,73 @@ class KotlinCodeFragmentFactory: CodeFragmentFactory() { - } - }) - -+ if (contextElement != null && contextElement !is KtElement) {","Now such variables are skipped during text rendering, so it doesn't matter if they are present in resulting map (this map is used only to get values for kotlin variables that are present in resulting text) -",Why do we need the `!is KtElement` check he -585,"@@ -115,9 +116,73 @@ class KotlinCodeFragmentFactory: CodeFragmentFactory() { - } - }) - -+ if (contextElement != null && contextElement !is KtElement) { -+ codeFragment.putCopyableUserData(KtCodeFragment.FAKE_CONTEXT_FOR_JAVA_FILE, { -+ val emptyFile = createFakeFileWithJavaContextElement("""", contextElement) -+ -+ val debuggerContext = DebuggerManagerEx.getInstanceEx(project).context -+ val debuggerSession = debuggerContext.debuggerSession -+ if ((debuggerSession == null || debuggerContext.suspendContext == null) && !ApplicationManager.getApplication().isUnitTestMode) { -+ LOG.warn(""Couldn't create fake context element for java file, debugger isn't paused on breakpoint"") -+ return@putCopyableUserData emptyFile -+ } -+ -+ // TODO: 'this' is unavailable -+ val visibleVariables = getVisibleLocalVariables(contextElement, debuggerContext) -+ if (visibleVariables == null) { -+ LOG.warn(""Couldn't get a list of local variables for ${debuggerContext.sourcePosition.file.name}:${debuggerContext.sourcePosition.line}"") -+ return@putCopyableUserData emptyFile -+ } -+ -+ val fakeFunctionText = ""fun _java_locals_debug_fun_() {\n"" + -+ visibleVariables.entries.associate { it.key.name() to it.value }.kotlinVariablesAsText(project) + -+ ""}"" -+ -+ val fakeFile = createFakeFileWithJavaContextElement(fakeFunctionText, contextElement) -+ val fakeFunction = fakeFile.declarations.firstOrNull() as? KtFunction -+ val fakeContext = (fakeFunction?.bodyExpression as? KtBlockExpression)?.statements?.lastOrNull() -+ -+ return@putCopyableUserData wrapContextIfNeeded(project, contextElement, fakeContext) ?: emptyFile -+ }) -+ } -+ - return codeFragment - } - -+ private fun getVisibleLocalVariables(contextElement: PsiElement?, debuggerContext: DebuggerContextImpl): Map? { -+ val semaphore = Semaphore() -+ semaphore.down() -+ -+ var visibleVariables: Map? = null -+ -+ val worker = object : DebuggerCommandImpl() { -+ override fun action() {","I've replaced it with codeFragment.getContentElement().statements.lastOrNull() to make this line clearer -",Move `.kotlinVariablesAsText()` to a consta -586,"@@ -116,13 +128,35 @@ private static String execCompiler( - List argumentsList = ArgumentUtils.convertArgumentsToStringList(arguments); - argumentsList.addAll(StringUtil.split(additionalArguments, "" "")); - -+ String[] argsArray = ArrayUtil.toStringArray(argumentsList); -+ -+ // trying the daemon first -+ if (incrementalCaches != null && KotlinCompilerClient.Companion.isDaemonEnabled()) { -+ File libPath = CompilerRunnerUtil.getLibPath(environment.getKotlinPaths(), messageCollector); -+ // TODO: it may be a good idea to cache the compilerId, since making it means calculating digest over jar(s) and if \\ -+ // the lifetime of JPS process is small anyway, we can neglect the probability of changed compiler -+ CompilerId compilerId = CompilerId.makeCompilerId(new File(libPath, ""kotlin-compiler.jar"")); -+ DaemonOptions daemonOptions = new DaemonOptions(); -+ DaemonLaunchingOptions daemonLaunchingOptions = new DaemonLaunchingOptions(); -+ KotlinCompilerClient.Companion.configureDaemonLaunchingOptions(daemonLaunchingOptions); -+ // TODO: find proper stream to report daemon connection progress -+ CompileService daemon = KotlinCompilerClient.Companion.connectToCompileService(compilerId, daemonLaunchingOptions, daemonOptions, System.out, true, true); -+ if (daemon != null) { -+ Integer res = KotlinCompilerClient.Companion.incrementalCompile(daemon, argsArray, incrementalCaches, out); -+ return res.toString(); -+ } -+ } -+ -+ // otherwise fallback to in-process -+ - Object rc = CompilerRunnerUtil.invokeExecMethod( -- compilerClassName, ArrayUtil.toStringArray(argumentsList), environment, messageCollector, out -+ compilerClassName, argsArray, environment, messageCollector, out - ); - - // exec() returns an ExitCode object, class of which is loaded with a different class loader, - // so we take it's contents through reflection - return getReturnCodeFromObject(rc); -+","Extra empty line. -",Is there a way to write this into a single -587,"@@ -1162,3 +1162,77 @@ public fun CharSequence.lineSequence(): Sequence = splitToSequence(""\r\n - * * Splits this char sequence to a list of lines delimited by any of the following character sequences: CRLF, LF or CR. - */ - public fun CharSequence.lines(): List = lineSequence().toList() -+ -+/** -+ * For each i in [0, length), this function computes -+ * the length of the longest suffix of a substring of pattern from 0 to i -+ * that is also a prefix of the pattern itself. -+ */ -+private fun computePrefixFunction(pattern: CharSequence): IntArray { -+ val resultTable = IntArray(pattern.length) -+ -+ var matches = 0 -+ for (i in 1..pattern.length - 1) { -+ while (matches > 0 && pattern[matches] != pattern[i]) { -+ matches = resultTable[matches] -+ } -+ -+ if (pattern[matches] == pattern[i]) { -+ matches++ -+ } -+ resultTable[i] = matches -+ } -+ -+ return resultTable -+} -+ -+/** -+ * Returns a list of indices where the pattern occurs in this String. This method -+ * searches character by character and thus does not support regular expressions -+ * as input for the pattern. -+ * -+ * @param [pattern] The pattern to look for in this String. Regular expressions -+ * are not supported -+ * @param [ignoreCase] If true, characters are matched even if one is upper and the other is -+ * lower case -+ * -+ * @return A list of indices where the supplied [pattern] starts in the text. -+ */ -+public fun CharSequence.occurrencesOf(pattern: CharSequence, ignoreCase: Boolean = false): Sequence { -+ -+ if (isEmpty() || pattern.isEmpty()) {","`if (pattern.isEmpty() || pattern.length > this.length)` ? -",This should either be `var resultTable = pa -588,"@@ -1162,3 +1162,77 @@ public fun CharSequence.lineSequence(): Sequence = splitToSequence(""\r\n - * * Splits this char sequence to a list of lines delimited by any of the following character sequences: CRLF, LF or CR. - */ - public fun CharSequence.lines(): List = lineSequence().toList() -+ -+/** -+ * For each i in [0, length), this function computes -+ * the length of the longest suffix of a substring of pattern from 0 to i -+ * that is also a prefix of the pattern itself. -+ */ -+private fun computePrefixFunction(pattern: CharSequence): IntArray { -+ val resultTable = IntArray(pattern.length) -+ -+ var matches = 0 -+ for (i in 1..pattern.length - 1) { -+ while (matches > 0 && pattern[matches] != pattern[i]) { -+ matches = resultTable[matches] -+ } -+ -+ if (pattern[matches] == pattern[i]) { -+ matches++ -+ } -+ resultTable[i] = matches -+ } -+ -+ return resultTable -+} -+ -+/** -+ * Returns a list of indices where the pattern occurs in this String. This method -+ * searches character by character and thus does not support regular expressions -+ * as input for the pattern. -+ * -+ * @param [pattern] The pattern to look for in this String. Regular expressions -+ * are not supported -+ * @param [ignoreCase] If true, characters are matched even if one is upper and the other is -+ * lower case -+ * -+ * @return A list of indices where the supplied [pattern] starts in the text. -+ */ -+public fun CharSequence.occurrencesOf(pattern: CharSequence, ignoreCase: Boolean = false): Sequence { -+ -+ if (pattern.isEmpty() || pattern.length > this.length) { -+ return emptySequence()","I believe this should be consistent with the result of `Regex("""").findAll(input = ""...."")`, i.e. a match in every position. -",This should either be `CharSequence.of(patt -589,"@@ -1162,3 +1162,84 @@ public fun CharSequence.lineSequence(): Sequence = splitToSequence(""\r\n - * * Splits this char sequence to a list of lines delimited by any of the following character sequences: CRLF, LF or CR. - */ - public fun CharSequence.lines(): List = lineSequence().toList() -+ -+/** -+ * For each i in [0, length), this function computes -+ * the length of the longest suffix of a substring of pattern from 0 to i -+ * that is also a prefix of the pattern itself. -+ */ -+private fun computePrefixFunction(pattern: CharSequence): IntArray { -+ val resultTable = IntArray(pattern.length) -+ -+ var matches = 0 -+ for (i in 1..pattern.length - 1) { -+ while (matches > 0 && pattern[matches] != pattern[i]) { -+ matches = resultTable[matches] -+ } -+ -+ if (pattern[matches] == pattern[i]) { -+ matches++ -+ } -+ resultTable[i] = matches -+ } -+ -+ return resultTable -+} -+ -+/** -+ * Returns a list of indices where the pattern occurs in this String. This method -+ * searches character by character and thus does not support regular expressions -+ * as input for the pattern. -+ * For a pattern longer than the text, an empty sequence is returned. If the pattern -+ * is empty, all indices are matched. -+ * -+ * @param [pattern] The pattern to look for in this String. Regular expressions -+ * are not supported -+ * @param [ignoreCase] If true, characters are matched even if one is upper and the other is -+ * lower case -+ * @param [matchOverlapping] If true, also match overlapping occurences. -+ * -+ * @return A list of indices where the supplied [pattern] starts in the text. -+ */ -+public fun CharSequence.occurrencesOf(pattern: CharSequence, ignoreCase: Boolean = false, matchOverlapping: Boolean = false): Sequence { -+ -+ if (pattern.length > this.length) { -+ return emptySequence() -+ } -+ -+ if (pattern.isEmpty()) { -+ return indices.asSequence()","It should be `(0..length).asSequence()`, because you need to count an empty match before the first character and empty one after the last characater. -","This should either be `CharSequence.of(0, t" -590,"@@ -1162,3 +1162,84 @@ public fun CharSequence.lineSequence(): Sequence = splitToSequence(""\r\n - * * Splits this char sequence to a list of lines delimited by any of the following character sequences: CRLF, LF or CR. - */ - public fun CharSequence.lines(): List = lineSequence().toList() -+ -+/** -+ * For each i in [0, length), this function computes -+ * the length of the longest suffix of a substring of pattern from 0 to i -+ * that is also a prefix of the pattern itself. -+ */ -+private fun computePrefixFunction(pattern: CharSequence): IntArray { -+ val resultTable = IntArray(pattern.length) -+ -+ var matches = 0 -+ for (i in 1..pattern.length - 1) { -+ while (matches > 0 && pattern[matches] != pattern[i]) { -+ matches = resultTable[matches] -+ } -+ -+ if (pattern[matches] == pattern[i]) { -+ matches++ -+ } -+ resultTable[i] = matches -+ } -+ -+ return resultTable -+} -+ -+/** -+ * Returns a list of indices where the pattern occurs in this String. This method -+ * searches character by character and thus does not support regular expressions -+ * as input for the pattern. -+ * For a pattern longer than the text, an empty sequence is returned. If the pattern -+ * is empty, all indices are matched. -+ * -+ * @param [pattern] The pattern to look for in this String. Regular expressions -+ * are not supported -+ * @param [ignoreCase] If true, characters are matched even if one is upper and the other is -+ * lower case -+ * @param [matchOverlapping] If true, also match overlapping occurences. -+ * -+ * @return A list of indices where the supplied [pattern] starts in the text. -+ */ -+public fun CharSequence.occurrencesOf(pattern: CharSequence, ignoreCase: Boolean = false, matchOverlapping: Boolean = false): Sequence { -+ -+ if (pattern.length > this.length) { -+ return emptySequence() -+ } -+ -+ if (pattern.isEmpty()) { -+ return indices.asSequence() -+ } -+ -+ if (pattern.length == 1) { -+ return indices.asSequence().filter { this[it].equals(pattern[0], ignoreCase) }","We could extract `CharSequence.occurrencesOf(char: Char, ignoreCase)` function from here. -",Please remove this `@return`. -591,"@@ -1162,3 +1162,97 @@ public fun CharSequence.lineSequence(): Sequence = splitToSequence(""\r\n - * * Splits this char sequence to a list of lines delimited by any of the following character sequences: CRLF, LF or CR. - */ - public fun CharSequence.lines(): List = lineSequence().toList() -+ -+/** -+ * For each i in [0, length), this function computes -+ * the length of the longest suffix of a substring of pattern from 0 to i -+ * that is also a prefix of the pattern itself. -+ */ -+private fun computePrefixFunction(pattern: CharSequence): IntArray {","I'm not sure the prefix function is computed correctly. For the following example ""ABCDABD"" it returns [0,0,0,0,1,2,0], while according to the [reference](https://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm#Worked_example_of_the_table-building_algorithm) it should be [-1,0,0,0,0,1,2]. - -Also it loops infinitely on the input ""AAABAAB"". -","`[0, length]` -> `[0, length]`" -592,"@@ -1162,3 +1162,97 @@ public fun CharSequence.lineSequence(): Sequence = splitToSequence(""\r\n - * * Splits this char sequence to a list of lines delimited by any of the following character sequences: CRLF, LF or CR. - */ - public fun CharSequence.lines(): List = lineSequence().toList() -+ -+/** -+ * For each i in [0, length), this function computes -+ * the length of the longest suffix of a substring of pattern from 0 to i -+ * that is also a prefix of the pattern itself. -+ */ -+private fun computePrefixFunction(pattern: CharSequence): IntArray { -+ val resultTable = IntArray(pattern.length) -+ -+ var matches = 0 -+ for (i in 1..pattern.length - 1) { -+ while (matches > 0 && pattern[matches] != pattern[i]) { -+ matches = resultTable[matches - 1] -+ } -+ -+ if (pattern[matches] == pattern[i]) { -+ matches++ -+ } -+ resultTable[i] = matches -+ } -+ -+ return resultTable -+} -+ -+/** -+ * Returns a sequence of indices where the char occurs in this CharSequence. -+ * -+ * @param [char] The character to look for in the string -+ * @param [ignoreCase] If true, characters are matched even if one is upper and the other is -+ * lower case -+ * -+ * @return A list of indices where the supplied [char] occurs in the text. -+ */ -+public fun CharSequence.occurrencesOf(char: Char, ignoreCase: Boolean = false): Sequence { -+ return indices.asSequence().filter { this[it].equals(char, ignoreCase) } -+} -+ -+/** -+ * Returns a sequence of indices where the pattern occurs in this CharSequence. This method -+ * searches character by character and thus does not support regular expressions -+ * as input for the pattern. -+ * For a pattern longer than the text, an empty sequence is returned. If the pattern -+ * is empty, all indices plus an empty occurrence at the end are matched. -+ * -+ * @param [pattern] The pattern to look for in this String. Regular expressions -+ * are not supported -+ * @param [ignoreCase] If true, characters are matched even if one is upper and the other is -+ * lower case -+ * @param [matchOverlapping] If true, also match overlapping occurrences. -+ * -+ * @return A list of indices where the supplied [pattern] starts in the text. -+ */ -+public fun CharSequence.occurrencesOf(pattern: CharSequence, ignoreCase: Boolean = false, matchOverlapping: Boolean = false): Sequence { -+ -+ if (pattern.length > this.length) { -+ return emptySequence() -+ } -+ -+ if (pattern.isEmpty()) { -+ return (0..length).asSequence() -+ } -+ -+ if (pattern.length == 1) { -+ return occurrencesOf(pattern[0], ignoreCase) -+ } -+ -+ // Non-trivial pattern matching, perform computation -+ // using Knuth-Morris-Pratt -+ -+ val prefixFunction = computePrefixFunction(pattern) -+ -+ var i = 0 -+ var matches = 0 -+ return generateSequence { -+ while (i < length) { -+ while (matches > 0 && !pattern[matches].equals(this[i], ignoreCase)) { -+ matches = prefixFunction[matches - 1] -+ } -+ -+ if (pattern[matches].equals(this[i], ignoreCase)) { -+ matches++ -+ }","This approach requires two character comparisons per position when `matches > 0`. Is it possible to restructure the loop body? Also applies to `computePrefixFunction`. -",This should either be `var resultTable = Lists.asSequence().filter(pattern => pattern[i] !== pattern[i])` or something similar. -593,"@@ -117,7 +117,7 @@ and find classes or functions which are not documented very well and submit a pa - In particular it'd be great if all functions included a nice example of how to use it such as for the - hashMapOf() function. - This is implemented using the @sample --macro to include code from a test function. This serves as a double win; the API gets better documented with nice examples to help new users and the code gets more test coverage. -+macro to include code from a test function. The benefits of this approach are twofold; First, the API's documentations is improved via beneficial examples that help new users and second, the code coverage is increased.","> documentations is - -Not sure if it's consistent: either ""documentations are"" or ""documentation is"" -",nit: can we add a space after `:` to make it clear that this is a new line? -594,"@@ -117,9 +118,8 @@ public object KotlinCompilerRunner { - val stream = ByteArrayOutputStream() - val out = PrintStream(stream) - --// Uncomment after resolving problems with parallel compilation and tests --// if (System.getProperty(KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY) == null) --// System.setProperty(KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY, """") -+ if (java.lang.Boolean.parseBoolean(System.getProperty(GlobalOptions.COMPILE_PARALLEL_OPTION, ""false"")))","use `String#toBoolean()` -",Remove this line. -595,"@@ -118,17 +119,33 @@ private static Integer doExec(@NotNull CompileContext context, @NotNull Compiler - context.addMessage(CompilerMessageCategory.ERROR, ""K2JSCompiler does not support multiple module source roots."", null, -1, -1); - return -1; - } -- String[] commandLineArgs = constructArguments(context.getProject(), context.getModuleOutputDirectory(module), roots[0]); -+ -+ VirtualFile outDir = context.getModuleOutputDirectory(module); -+ String outFile = outDir == null ? null : K2JSRunnerUtils.constructPathToGeneratedFile(context.getProject(), outDir.getPath()); -+ -+ String[] commandLineArgs = constructArguments(context.getProject(), outFile, roots[0]); - Object rc = invokeExecMethod(environment, out, context, commandLineArgs, ""org.jetbrains.jet.cli.js.K2JSCompiler""); -+ -+ if (outDir != null) { -+ outDir.refresh(false, true);","Can you please tell me what this is about? -","You could use `K2JSRunnerUtils.constructPathToGeneratedFile(context.getProject(), outDir.getPath());` here instead." -596,"@@ -1191,14 +1191,14 @@ public inline fun Iterable.takeWhile(predicate: (T) -> Boolean): List - } - - /** -- * Returns a stream containing first elements satisfying the given *predicate* -+ * Returns a stream containing first elements satisfying the given [predicate] - */ - public fun Stream.takeWhile(predicate: (T) -> Boolean): Stream { - return TakeWhileStream(this, predicate) - } - - /** -- * Returns a list containing first elements satisfying the given *predicate* -+ * Returns a string containing the first characters that satisfy the given [predicate]","""the first characters"", do not need ""the"" -","This is a list, not a string." -597,"@@ -12,7 +12,7 @@ public fun Enumeration.iterator(): Iterator = object : Iterator { - } - - /** -- * Returns the given iterator itself. This allows to use an instance of iterator in a ranged for-loop -+ * Returns the given iterator itself. This allows to use an instance of iterator in a ranged for-loop.","""ranged for-loop"" -> ""`for` loop"" -",Unused import `ranged for-loop` -598,"@@ -120,6 +129,39 @@ fun JetElement.wrapInBlock(): JetBlockExpression { - block.appendElement(this) - return block - } -+ -+fun JetExpressionImpl.findBlockInExpression(element: JetExpressionImpl, expressionType: String?): JetBlockExpression? {","Why are this and the following functions extensions, but you don't use `this` in them and require call sites to pass same value twice? -","woops, will add this in my next PR" -599,"@@ -120,6 +129,39 @@ fun JetElement.wrapInBlock(): JetBlockExpression { - block.appendElement(this) - return block - } -+ -+fun JetExpressionImpl.findBlockInExpression(element: JetExpressionImpl, expressionType: String?): JetBlockExpression? { -+ val bodyNode = when (expressionType) { -+ ""if"" -> element.getNode().findChildByType(JetNodeTypes.THEN) -+ ""else"" -> element.getNode().findChildByType(JetNodeTypes.ELSE) -+ else -> element.getNode().findChildByType(JetNodeTypes.BODY) -+ } -+ if (bodyNode?.getPsi()?.getFirstChild() is JetBlockExpression) { -+ return bodyNode!!.getPsi()!!.getFirstChild() as JetBlockExpression -+ } -+ return null","Use the power of Kotlin :) Four lines can be replaced with `return bodyNode?.getPsi()?.getFirstChild() as? JetBlockExpression` -",Please annotate `expressionType` with `@Nullable`. -600,"@@ -120,6 +129,39 @@ fun JetElement.wrapInBlock(): JetBlockExpression { - block.appendElement(this) - return block - } -+ -+fun JetExpressionImpl.findBlockInExpression(element: JetExpressionImpl, expressionType: String?): JetBlockExpression? { -+ val bodyNode = when (expressionType) { -+ ""if"" -> element.getNode().findChildByType(JetNodeTypes.THEN) -+ ""else"" -> element.getNode().findChildByType(JetNodeTypes.ELSE) -+ else -> element.getNode().findChildByType(JetNodeTypes.BODY) -+ } -+ if (bodyNode?.getPsi()?.getFirstChild() is JetBlockExpression) { -+ return bodyNode!!.getPsi()!!.getFirstChild() as JetBlockExpression -+ } -+ return null -+} -+ -+fun JetExpressionImpl.getExpressionType(element: JetExpressionImpl): String? {","""Expression type"" phrase usually means different thing, so this usage of it is misleading. Better to replace ""type"" word with ""kind"". Don't forget that you have this phrase in several other places. -Also, it's better to use enumeration instead of strings, because it's more type-safe. Enumeration can be named `ExpressionBlockKind` or something like this. -",Please annotate `expressionType` with `@Nullable`. -601,"@@ -121,17 +164,16 @@ public open class KotlinCompile(): AbstractCompile() { - args.noOptimize = kotlinOptions.noOptimize - args.noCallAssertions = kotlinOptions.noCallAssertions - args.noParamAssertions = kotlinOptions.noParamAssertions -+ } - -- val messageCollector = GradleMessageCollector(getLogger()) -- getLogger().debug(""Calling compiler"") -- val exitCode = compiler.exec(messageCollector, Services.EMPTY, args) -- -- when (exitCode) { -- ExitCode.COMPILATION_ERROR -> throw GradleException(""Compilation error. See log for more details"") -- ExitCode.INTERNAL_ERROR -> throw GradleException(""Internal compiler error. See log for more details"") -- else -> {} -- } -+ private fun getJavaSourceRoots(): HashSet = getSource()","May be `List`? -",Any particular reason why this is not using the `RemoteExecutor`? -602,"@@ -121,17 +164,16 @@ public open class KotlinCompile(): AbstractCompile() { - args.noOptimize = kotlinOptions.noOptimize - args.noCallAssertions = kotlinOptions.noCallAssertions - args.noParamAssertions = kotlinOptions.noParamAssertions -+ } - -- val messageCollector = GradleMessageCollector(getLogger()) -- getLogger().debug(""Calling compiler"") -- val exitCode = compiler.exec(messageCollector, Services.EMPTY, args) -- -- when (exitCode) { -- ExitCode.COMPILATION_ERROR -> throw GradleException(""Compilation error. See log for more details"") -- ExitCode.INTERNAL_ERROR -> throw GradleException(""Internal compiler error. See log for more details"") -- else -> {} -- } -+ private fun getJavaSourceRoots(): HashSet = getSource() -+ .filter { isJava(it) } -+ .map { findSrcDirRoot(it) } -+ .filter { it != null }","May be replaced with `filterNotNull` -",Remove this empty line. -603,"@@ -122,3 +124,47 @@ class KotlinEnterHandler: EnterHandlerDelegateAdapter() { - return false - } - } -+ -+class KotlinConvertToBodyEnterHandler : EnterHandlerDelegateAdapter() { -+ override fun preprocessEnter(file: PsiFile, editor: Editor, -+ caretOffset: Ref, caretAdvance: Ref, dataContext: DataContext, -+ originalHandler: EditorActionHandler?): EnterHandlerDelegate.Result { -+ if (file !is KtFile) return EnterHandlerDelegate.Result.Continue -+ if (!KotlinEditorOptions.getInstance().isEnableSmartConvertToBody) return EnterHandlerDelegate.Result.Continue -+ if (!EnterAfterUnmatchedBraceHandler.isAfterUnmatchedLBrace(editor, caretOffset.get(), -+ file.fileType)) return EnterHandlerDelegate.Result.Continue -+ -+ val document = editor.document -+ -+ //Let's check if it's special convert to body case.",This comments doesn't explain anything and can be dropped safely.,Let's not check if it's special convert to body. -604,"@@ -122,3 +124,47 @@ class KotlinEnterHandler: EnterHandlerDelegateAdapter() { - return false - } - } -+ -+class KotlinConvertToBodyEnterHandler : EnterHandlerDelegateAdapter() { -+ override fun preprocessEnter(file: PsiFile, editor: Editor, -+ caretOffset: Ref, caretAdvance: Ref, dataContext: DataContext, -+ originalHandler: EditorActionHandler?): EnterHandlerDelegate.Result { -+ if (file !is KtFile) return EnterHandlerDelegate.Result.Continue -+ if (!KotlinEditorOptions.getInstance().isEnableSmartConvertToBody) return EnterHandlerDelegate.Result.Continue -+ if (!EnterAfterUnmatchedBraceHandler.isAfterUnmatchedLBrace(editor, caretOffset.get(), -+ file.fileType)) return EnterHandlerDelegate.Result.Continue -+ -+ val document = editor.document -+ -+ //Let's check if it's special convert to body case. -+ val prevOffset = caretOffset.get() - 1 -+ if (document.isTextAt(prevOffset, ""{"")) {",Please consider inverting `if`.,"In this case, we don't know if the editor is a KtFile or not, so we don't need this check." -605,"@@ -122,3 +124,47 @@ class KotlinEnterHandler: EnterHandlerDelegateAdapter() { - return false - } - } -+ -+class KotlinConvertToBodyEnterHandler : EnterHandlerDelegateAdapter() { -+ override fun preprocessEnter(file: PsiFile, editor: Editor, -+ caretOffset: Ref, caretAdvance: Ref, dataContext: DataContext, -+ originalHandler: EditorActionHandler?): EnterHandlerDelegate.Result { -+ if (file !is KtFile) return EnterHandlerDelegate.Result.Continue -+ if (!KotlinEditorOptions.getInstance().isEnableSmartConvertToBody) return EnterHandlerDelegate.Result.Continue -+ if (!EnterAfterUnmatchedBraceHandler.isAfterUnmatchedLBrace(editor, caretOffset.get(), -+ file.fileType)) return EnterHandlerDelegate.Result.Continue -+ -+ val document = editor.document -+ -+ //Let's check if it's special convert to body case. -+ val prevOffset = caretOffset.get() - 1 -+ if (document.isTextAt(prevOffset, ""{"")) { -+ document.commit(file.project) -+ val element = file.findElementAt(prevOffset) -+ if (element != null && element.matchParents( -+ KtFunctionLiteral::class.java, -+ KtLambdaExpression::class.java, -+ KtDeclarationWithBody::class.java -+ )) { -+ val declaration = element.parent.parent.parent as KtDeclarationWithBody -+ if (!declaration.hasDeclaredReturnType()) return EnterHandlerDelegate.Result.Continue",I think this restriction leaves the majority of use-cases out of scope. Can we overcome it? I'm not sure it all worth it without the solution.,Please rename this class to `KtDeclarationToBodyEnterHandler` -606,"@@ -122,3 +124,47 @@ class KotlinEnterHandler: EnterHandlerDelegateAdapter() { - return false - } - } -+ -+class KotlinConvertToBodyEnterHandler : EnterHandlerDelegateAdapter() { -+ override fun preprocessEnter(file: PsiFile, editor: Editor, -+ caretOffset: Ref, caretAdvance: Ref, dataContext: DataContext, -+ originalHandler: EditorActionHandler?): EnterHandlerDelegate.Result { -+ if (file !is KtFile) return EnterHandlerDelegate.Result.Continue -+ if (!KotlinEditorOptions.getInstance().isEnableSmartConvertToBody) return EnterHandlerDelegate.Result.Continue -+ if (!EnterAfterUnmatchedBraceHandler.isAfterUnmatchedLBrace(editor, caretOffset.get(), -+ file.fileType)) return EnterHandlerDelegate.Result.Continue -+ -+ val document = editor.document -+ -+ //Let's check if it's special convert to body case. -+ val prevOffset = caretOffset.get() - 1 -+ if (document.isTextAt(prevOffset, ""{"")) { -+ document.commit(file.project) -+ val element = file.findElementAt(prevOffset) -+ if (element != null && element.matchParents( -+ KtFunctionLiteral::class.java, -+ KtLambdaExpression::class.java, -+ KtDeclarationWithBody::class.java -+ )) { -+ val declaration = element.parent.parent.parent as KtDeclarationWithBody -+ if (!declaration.hasDeclaredReturnType()) return EnterHandlerDelegate.Result.Continue -+ val equals = declaration.equalsToken -+ if (equals != null) { -+ val startOffset =",Will it work with comments? Maybe it would be better to check for '=' and extend it with spaces from left and right.,Please rename this class to `KtDeclarationToBodyEnterHandler` -607,"@@ -124,21 +128,71 @@ class ConvertTwoComparisonsToRangeCheckIntention : SelfTargetingOffsetIndependen - // To avoid possible side effects - if (!min.isSimple() || !max.isSimple()) return null - -+ val valContext = value.analyze()",You don't need to call `analyze()` multiple times; calling it once will return a `BindingContext` with information about all the expressions.,Why is this needed? The parameter `val` doesn't seem to be used. -608,"@@ -124,21 +128,71 @@ class ConvertTwoComparisonsToRangeCheckIntention : SelfTargetingOffsetIndependen - // To avoid possible side effects - if (!min.isSimple() || !max.isSimple()) return null - -+ val valContext = value.analyze() -+ val minContext = min.analyze() -+ val maxContext = max.analyze() -+ val valType = value.getType(valContext) -+ val minType = min.getType(minContext) -+ val maxType = max.getType(maxContext) -+ -+ if (valType == null || minType == null || maxType == null) return null -+ -+ if (!valType.isComparable()) return null -+ -+ var minVal = min -+ var maxVal = max -+ -+ if (minType != valType || maxType != valType) { -+ //numbers can be compared to numbers of different types -+ if (valType.isPrimitiveNumberType() && minType.isPrimitiveNumberType() && maxType.isPrimitiveNumberType()) { -+ //char is comparable to chars only -+ if (KotlinBuiltIns.isChar(valType) || KotlinBuiltIns.isChar(minType) || KotlinBuiltIns.isChar(maxType)) return null -+ -+ if (valType.isFloatingPoint()) { -+ if (minType.isInteger()) -+ minVal = KtPsiFactory(minVal).createExpression(getDoubleConstant(min, minType, minContext) ?: return null) -+ if (maxType.isInteger()) -+ maxVal = KtPsiFactory(maxVal).createExpression(getDoubleConstant(max, maxType, maxContext) ?: return null) -+ } -+ } else { -+ return null -+ } -+ } -+ - if (incrementMinByOne || decrementMaxByOne) { -- if (!value.getType(value.analyze()).isValidTypeForIncrementDecrementByOne()) return null -+ if (!valType.isValidTypeForIncrementDecrementByOne()) return null - } - -- val minText = if (incrementMinByOne) min.getChangeBy(1) else min.text -- val maxText = if (decrementMaxByOne) max.getChangeBy(-1) else max.text -+ val minText = if (incrementMinByOne) minVal.getChangeBy(1) else minVal.text -+ val maxText = if (decrementMaxByOne) maxVal.getChangeBy(-1) else maxVal.text - return RangeExpressionData(value, minText ?: return null, maxText ?: return null) - } - -- private fun KotlinType?.isValidTypeForIncrementDecrementByOne(): Boolean { -- this ?: return false -+ private fun getDoubleConstant(intExpr: KtExpression, type: KotlinType, context: BindingContext): String? { -+ val intConst = ConstantExpressionEvaluator.getConstant(intExpr, context)?.getValue(type) ?: return null -+ return (intConst as? Number)?.toDouble()?.toString() -+ } -+ -+ private fun KotlinType.isComparable(): Boolean {","`DescriptorUtils.isSubtypeOfClass(this, expression.builtIns.getComparable())`","If min and max are non-comparable, then min and max should be nullable." -609,"@@ -126,32 +254,100 @@ public trait MutableSet : Set, MutableCollection { - override fun clear(): Unit - } - -+/** -+ * A collection that holds pairs of objects (keys and values) and supports efficiently retrieving -+ * the value corresponding to each key. Map keys are unique; the map holds only one value for each key. -+ * Methods in this trait support only read-only access to the map; read-write access is supported through -+ * the [MutableMap] trait. -+ */ - public trait Map { - // Query Operations -+ /** -+ * Returns the size of the map. -+ */","size is a little bit unclear, may be ""number of key-value"" pairs? -","nit: This is a bit confusing, since the type for the `MutableMap` is no" -610,"@@ -126,32 +254,100 @@ public trait MutableSet : Set, MutableCollection { - override fun clear(): Unit - } - -+/** -+ * A collection that holds pairs of objects (keys and values) and supports efficiently retrieving -+ * the value corresponding to each key. Map keys are unique; the map holds only one value for each key. -+ * Methods in this trait support only read-only access to the map; read-write access is supported through -+ * the [MutableMap] trait. -+ */ - public trait Map { - // Query Operations -+ /** -+ * Returns the size of the map. -+ */ - public fun size(): Int -+ -+ /** -+ * Returns `true` if the map is empty (contains no elements), `false` otherwise. -+ */ - public fun isEmpty(): Boolean -+ -+ /** -+ * Returns `true` if the map contains the specified [key]. -+ */ - public fun containsKey(key: Any?): Boolean -+ -+ /** -+ * Returns `true` if the map maps one or more keys to the specified [value]. -+ */ - public fun containsValue(value: Any?): Boolean -+ -+ /** -+ * Returns the value corresponding to the given [key], or `null` if such a key is not present in the map. -+ */ - public fun get(key: Any?): V? - - // Views -+ /** -+ * Returns a [Set] of all keys in this map. -+ */ - public fun keySet(): Set -+ -+ /** -+ * Returns a [Collection] of all values in this map. -+ */ - public fun values(): Collection","May contain duplicate values -",Should be `Iterable` instead of `Collection` -611,"@@ -128,36 +128,71 @@ private static String execCompiler( - - String[] argsArray = ArrayUtil.toStringArray(argumentsList); - -- // trying the daemon first -- if (incrementalCaches != null && RmiPackage.isDaemonEnabled()) { -- File libPath = CompilerRunnerUtil.getLibPath(environment.getKotlinPaths(), messageCollector); -- // TODO: it may be a good idea to cache the compilerId, since making it means calculating digest over jar(s) and if \\ -- // the lifetime of JPS process is small anyway, we can neglect the probability of changed compiler -- CompilerId compilerId = CompilerId.makeCompilerId(new File(libPath, ""kotlin-compiler.jar"")); -- DaemonOptions daemonOptions = RmiPackage.configureDaemonOptions(); -- DaemonJVMOptions daemonJVMOptions = RmiPackage.configureDaemonLaunchingOptions(true); -- // TODO: find proper stream to report daemon connection progress -- CompileService daemon = KotlinCompilerClient.Companion.connectToCompileService(compilerId, daemonJVMOptions, daemonOptions, System.out, true, true); -- if (daemon != null) { -- Integer res = KotlinCompilerClient.Companion.incrementalCompile(daemon, argsArray, incrementalCaches, out); -- return res.toString(); -- } -- } -+ if (!tryCompileWithDaemon(messageCollector, collector, environment, incrementalCaches, argsArray)) { -+ // otherwise fallback to in-process - -- // otherwise fallback to in-process -+ ByteArrayOutputStream stream = new ByteArrayOutputStream(); -+ PrintStream out = new PrintStream(stream); - -- Object rc = CompilerRunnerUtil.invokeExecMethod( -- compilerClassName, argsArray, environment, messageCollector, out -- ); -+ Object rc = CompilerRunnerUtil.invokeExecMethod( compilerClassName, argsArray, environment, messageCollector, out); - -- // exec() returns an ExitCode object, class of which is loaded with a different class loader, -- // so we take it's contents through reflection -- return getReturnCodeFromObject(rc); -+ // exec() returns an ExitCode object, class of which is loaded with a different class loader, -+ // so we take it's contents through reflection -+ ProcessCompilerOutput(messageCollector, collector, stream, getReturnCodeFromObject(rc)); -+ } - } - catch (Throwable e) { - MessageCollectorUtil.reportException(messageCollector, e); -- return INTERNAL_ERROR; -+ reportInternalCompilerError(messageCollector); -+ } -+ } -+ -+ private static boolean tryCompileWithDaemon( -+ MessageCollector messageCollector, -+ OutputItemsCollector collector, -+ CompilerEnvironment environment, -+ Map incrementalCaches, -+ String[] argsArray -+ ) throws IOException { -+ if (incrementalCaches != null && RmiPackage.isDaemonEnabled()) { -+ File libPath = CompilerRunnerUtil.getLibPath(environment.getKotlinPaths(), messageCollector); -+ // TODO: it may be a good idea to cache the compilerId, since making it means calculating digest over jar(s) and if \\ -+ // the lifetime of JPS process is small anyway, we can neglect the probability of changed compiler -+ CompilerId compilerId = CompilerId.makeCompilerId(new File(libPath, ""kotlin-compiler.jar"")); -+ DaemonOptions daemonOptions = RmiPackage.configureDaemonOptions(); -+ DaemonJVMOptions daemonJVMOptions = RmiPackage.configureDaemonJVMOptions(true); -+ -+ ArrayList daemonReportMessages = new ArrayList(); -+ -+ CompileService daemon = KotlinCompilerClient.connectToCompileService(compilerId, daemonJVMOptions, daemonOptions, new DaemonReportingTargets(null, daemonReportMessages), true, true); -+ -+ for (DaemonReportMessage msg: daemonReportMessages) { -+ if (msg.getCategory() == DaemonReportCategory.EXCEPTION && daemon == null) { -+ messageCollector.report(CompilerMessageSeverity.INFO, -+ ""Falling back to compilation without daemon due to error: "" + msg.getMessage(), -+ CompilerMessageLocation.NO_LOCATION); -+ } -+ else { -+ messageCollector.report(CompilerMessageSeverity.INFO, msg.getMessage(), CompilerMessageLocation.NO_LOCATION); -+ } -+ } -+ -+ if (daemon != null) { -+ ByteArrayOutputStream compilerOut = new ByteArrayOutputStream(); -+ ByteArrayOutputStream daemonOut = new ByteArrayOutputStream(); -+ -+ Integer res = KotlinCompilerClient.incrementalCompile(daemon, argsArray, incrementalCaches, compilerOut, daemonOut); -+ -+ ProcessCompilerOutput(messageCollector, collector, compilerOut, res.toString()); -+ BufferedReader reader = new BufferedReader(new StringReader(daemonOut.toString()));","will we see non-latin characters? it could be significant for error messages with path to files, for example -","It seems like we don't need to pass `collector` here, right? Can we jus" -612,"@@ -13,39 +13,45 @@ public fun InputStream.iterator(): ByteIterator = - public override fun nextByte(): Byte = read().toByte() - } - --/** Creates a buffered input stream */ -+/** -+ * Creates a buffered input stream wrapping this stream. -+ * @param bufferSize the buffer size to use. -+ */ - public fun InputStream.buffered(bufferSize: Int = defaultBufferSize): InputStream - = if (this is BufferedInputStream) - this - else - BufferedInputStream(this, bufferSize) - --/** Creates a reader on an input stream using UTF-8 or specified charset. */ -+/** Creates a reader on this input stream using UTF-8 or the specified [charset]. */","Need to put it in conventions, wording around documenting parameter with default value. -","typo: ""this stream"" -> ""this input stream""" -613,"@@ -13,79 +13,96 @@ class ParsePrimitivesJVMTest { - } - - @test fun toByte() { -- assertEqualsOrFailsNullable(77.toByte(), ""+77"", String::toByte, String::toByteOrNull) -- assertEqualsOrFailsNullable(Byte.MIN_VALUE, ""-128"", String::toByte, String::toByteOrNull) -- assertEqualsOrFailsNullable(null, ""128"", String::toByte, String::toByteOrNull) -+ CompareBehaviourContext(String::toByte, String::toByteOrNull).apply { -+ -+ assertProduce(77.toByte(), ""+77"") -+ assertProduce(Byte.MIN_VALUE, ""-128"") -+ assertProduce(null, ""128"") -+ } - } - - @test fun toShort() { -- assertEqualsOrFailsNullable(77.toShort(), ""77"", String::toShort, String::toShortOrNull) -- assertEqualsOrFailsNullable(Short.MIN_VALUE, ""-32768"", String::toShort, String::toShortOrNull) -- assertEqualsOrFailsNullable(null, ""+32768"", String::toShort, String::toShortOrNull) -+ CompareBehaviourContext(String::toShort, String::toShortOrNull).apply { -+ -+ assertProduce(77.toShort(), ""77"") -+ assertProduce(Short.MIN_VALUE, ""-32768"") -+ assertProduce(null, ""+32768"") -+ } - } - - @test fun toInt() { -- assertEqualsOrFailsNullable(77, ""77"", String::toInt, String::toIntOrNull) -- assertEqualsOrFailsNullable(Int.MAX_VALUE, ""+2147483647"", String::toInt, String::toIntOrNull) -- assertEqualsOrFailsNullable(Int.MIN_VALUE, ""-2147483648"", String::toInt, String::toIntOrNull) -+ CompareBehaviourContext(String::toInt, String::toIntOrNull).apply { -+ -+ assertProduce(77, ""77"") -+ assertProduce(Int.MAX_VALUE, ""+2147483647"") -+ assertProduce(Int.MIN_VALUE, ""-2147483648"") - -- assertEqualsOrFailsNullable(null, ""2147483648"", String::toInt, String::toIntOrNull) -- assertEqualsOrFailsNullable(null, ""-2147483649"", String::toInt, String::toIntOrNull) -- assertEqualsOrFailsNullable(null, ""239239kotlin"", String::toInt, String::toIntOrNull) -+ assertProduce(null, ""2147483648"") -+ assertProduce(null, ""-2147483649"") -+ assertProduce(null, ""239239kotlin"") -+ } - } - - @test fun toLong() { -- assertEqualsOrFailsNullable(77.toLong(), ""77"", String::toLong, String::toLongOrNull) -- assertEqualsOrFailsNullable(Long.MAX_VALUE, ""+9223372036854775807"", String::toLong, String::toLongOrNull) -- assertEqualsOrFailsNullable(Long.MIN_VALUE, ""-9223372036854775808"", String::toLong, String::toLongOrNull) -- -- assertEqualsOrFailsNullable(null, ""9223372036854775808"", String::toLong, String::toLongOrNull) -- assertEqualsOrFailsNullable(null, ""-9223372036854775809"", String::toLong, String::toLongOrNull) -- assertEqualsOrFailsNullable(null, ""922337 75809"", String::toLong, String::toLongOrNull) -- assertEqualsOrFailsNullable(null, ""92233,75809"", String::toLong, String::toLongOrNull) -- assertEqualsOrFailsNullable(null, ""92233`75809"", String::toLong, String::toLongOrNull) -- assertEqualsOrFailsNullable(null, ""-922337KOTLIN775809"", String::toLong, String::toLongOrNull) -+ CompareBehaviourContext(String::toLong, String::toLongOrNull).apply { -+ -+ assertProduce(77.toLong(), ""77"") -+ assertProduce(Long.MAX_VALUE, ""+9223372036854775807"") -+ assertProduce(Long.MIN_VALUE, ""-9223372036854775808"") -+ -+ assertProduce(null, ""9223372036854775808"") -+ assertProduce(null, ""-9223372036854775809"") -+ assertProduce(null, ""922337 75809"") -+ assertProduce(null, ""92233,75809"") -+ assertProduce(null, ""92233`75809"") -+ assertProduce(null, ""-922337KOTLIN775809"") -+ } - } - - @test fun toFloat() { -- assertEqualsOrFailsNullable(77.0f, ""77.0"", String::toFloat, String::toFloatOrNull) -- assertEqualsOrFailsNullable(Float.NEGATIVE_INFINITY, ""-1e39"", String::toFloat, String::toFloatOrNull) -- assertEqualsOrFailsNullable(Float.POSITIVE_INFINITY, ""1000000000000000000000000000000000000000"", -- String::toFloat, String::toFloatOrNull) -+ CompareBehaviourContext(String::toFloat, String::toFloatOrNull).apply { - -- assertEqualsOrFailsNullable(null, ""dark side"", String::toFloat, String::toFloatOrNull) -+ assertProduce(77.0f, ""77.0"") -+ assertProduce(Float.NEGATIVE_INFINITY, ""-1e39"") -+ assertProduce(Float.POSITIVE_INFINITY, ""1000000000000000000000000000000000000000"") -+ assertProduce(null, ""dark side"") -+ } - } - - @test fun toDouble() { -- assertEqualsOrFailsNullable(-77.0, ""-77"", String::toDouble, String::toDoubleOrNull) -- assertEqualsOrFailsNullable(77.0, ""77."", String::toDouble, String::toDoubleOrNull) -- assertEqualsOrFailsNullable(77.0, ""77.0"", String::toDouble, String::toDoubleOrNull) -- assertEqualsOrFailsNullable(-1.77, ""-1.77"", String::toDouble, String::toDoubleOrNull) -- assertEqualsOrFailsNullable(0.77, ""+.77"", String::toDouble, String::toDoubleOrNull) -- assertEqualsOrFailsNullable(-77.0, ""\t-77 \n"", String::toDouble, String::toDoubleOrNull) -- assertEqualsOrFailsNullable(77.0, ""7.7e1"", String::toDouble, String::toDoubleOrNull) -- assertEqualsOrFailsNullable(77.0, ""+770e-1"", String::toDouble, String::toDoubleOrNull) -- -- assertEqualsOrFailsNullable(-Double.NaN, ""-NaN"", String::toDouble, String::toDoubleOrNull) -- assertEqualsOrFailsNullable(Double.POSITIVE_INFINITY, ""+Infinity"", String::toDouble, String::toDoubleOrNull) -- assertEqualsOrFailsNullable((0x77 shl 1).toDouble(), ""0x77p1"", String::toDouble, String::toDoubleOrNull) -- assertEqualsOrFailsNullable(0x77.toDouble(), ""0x.77P8"", String::toDouble, String::toDoubleOrNull) -- -- assertEqualsOrFailsNullable(null, ""7..7"", String::toDouble, String::toDoubleOrNull) -- assertEqualsOrFailsNullable(null, ""0x77e1"", String::toDouble, String::toDoubleOrNull) -- assertEqualsOrFailsNullable(null, ""007 not a number"", String::toDouble, String::toDoubleOrNull) -+ CompareBehaviourContext(String::toDouble, String::toDoubleOrNull).apply { -+ -+ assertProduce(-77.0, ""-77"") -+ assertProduce(77.0, ""77."") -+ assertProduce(77.0, ""77.0"") -+ assertProduce(-1.77, ""-1.77"") -+ assertProduce(0.77, ""+.77"") -+ assertProduce(-77.0, ""\t-77 \n"") -+ assertProduce(77.0, ""7.7e1"") -+ assertProduce(77.0, ""+770e-1"") -+ -+ assertProduce(-Double.NaN, ""-NaN"") -+ assertProduce(Double.POSITIVE_INFINITY, ""+Infinity"") -+ assertProduce((0x77 shl 1).toDouble(), ""0x77p1"") -+ assertProduce(0x77.toDouble(), ""0x.77P8"") -+ -+ assertProduce(null, ""7..7"") -+ assertProduce(null, ""0x77e1"") -+ assertProduce(null, ""007 not a number"") -+ } - } - } - --private inline fun assertEqualsOrFailsNullable(output: T?, -- input: String, -- crossinline converOrFail: (String) -> T, -- crossinline convertOrNull: (String) -> T?) { -- if(output == null) { -- assertFails { converOrFail(input) } -- assertNull (convertOrNull(input) ) -- } else { -- assertEquals(output, converOrFail(input)) -- assertEquals(output, convertOrNull(input)) -+ -+private class CompareBehaviourContext(val convertOrFail: (String) -> T,","`Behaviour` we prefer American English in identifiers :) -",Could you also test that `toShort` returns `String::toShort`? -614,"@@ -13,79 +13,96 @@ class ParsePrimitivesJVMTest { - } - - @test fun toByte() { -- assertEqualsOrFailsNullable(77.toByte(), ""+77"", String::toByte, String::toByteOrNull) -- assertEqualsOrFailsNullable(Byte.MIN_VALUE, ""-128"", String::toByte, String::toByteOrNull) -- assertEqualsOrFailsNullable(null, ""128"", String::toByte, String::toByteOrNull) -+ CompareBehaviourContext(String::toByte, String::toByteOrNull).apply { -+ -+ assertProduce(77.toByte(), ""+77"") -+ assertProduce(Byte.MIN_VALUE, ""-128"") -+ assertProduce(null, ""128"") -+ } - } - - @test fun toShort() { -- assertEqualsOrFailsNullable(77.toShort(), ""77"", String::toShort, String::toShortOrNull) -- assertEqualsOrFailsNullable(Short.MIN_VALUE, ""-32768"", String::toShort, String::toShortOrNull) -- assertEqualsOrFailsNullable(null, ""+32768"", String::toShort, String::toShortOrNull) -+ CompareBehaviourContext(String::toShort, String::toShortOrNull).apply { -+ -+ assertProduce(77.toShort(), ""77"") -+ assertProduce(Short.MIN_VALUE, ""-32768"") -+ assertProduce(null, ""+32768"") -+ } - } - - @test fun toInt() { -- assertEqualsOrFailsNullable(77, ""77"", String::toInt, String::toIntOrNull) -- assertEqualsOrFailsNullable(Int.MAX_VALUE, ""+2147483647"", String::toInt, String::toIntOrNull) -- assertEqualsOrFailsNullable(Int.MIN_VALUE, ""-2147483648"", String::toInt, String::toIntOrNull) -+ CompareBehaviourContext(String::toInt, String::toIntOrNull).apply { -+ -+ assertProduce(77, ""77"") -+ assertProduce(Int.MAX_VALUE, ""+2147483647"") -+ assertProduce(Int.MIN_VALUE, ""-2147483648"") - -- assertEqualsOrFailsNullable(null, ""2147483648"", String::toInt, String::toIntOrNull) -- assertEqualsOrFailsNullable(null, ""-2147483649"", String::toInt, String::toIntOrNull) -- assertEqualsOrFailsNullable(null, ""239239kotlin"", String::toInt, String::toIntOrNull) -+ assertProduce(null, ""2147483648"") -+ assertProduce(null, ""-2147483649"") -+ assertProduce(null, ""239239kotlin"") -+ } - } - - @test fun toLong() { -- assertEqualsOrFailsNullable(77.toLong(), ""77"", String::toLong, String::toLongOrNull) -- assertEqualsOrFailsNullable(Long.MAX_VALUE, ""+9223372036854775807"", String::toLong, String::toLongOrNull) -- assertEqualsOrFailsNullable(Long.MIN_VALUE, ""-9223372036854775808"", String::toLong, String::toLongOrNull) -- -- assertEqualsOrFailsNullable(null, ""9223372036854775808"", String::toLong, String::toLongOrNull) -- assertEqualsOrFailsNullable(null, ""-9223372036854775809"", String::toLong, String::toLongOrNull) -- assertEqualsOrFailsNullable(null, ""922337 75809"", String::toLong, String::toLongOrNull) -- assertEqualsOrFailsNullable(null, ""92233,75809"", String::toLong, String::toLongOrNull) -- assertEqualsOrFailsNullable(null, ""92233`75809"", String::toLong, String::toLongOrNull) -- assertEqualsOrFailsNullable(null, ""-922337KOTLIN775809"", String::toLong, String::toLongOrNull) -+ CompareBehaviourContext(String::toLong, String::toLongOrNull).apply { -+ -+ assertProduce(77.toLong(), ""77"") -+ assertProduce(Long.MAX_VALUE, ""+9223372036854775807"") -+ assertProduce(Long.MIN_VALUE, ""-9223372036854775808"") -+ -+ assertProduce(null, ""9223372036854775808"") -+ assertProduce(null, ""-9223372036854775809"") -+ assertProduce(null, ""922337 75809"") -+ assertProduce(null, ""92233,75809"") -+ assertProduce(null, ""92233`75809"") -+ assertProduce(null, ""-922337KOTLIN775809"") -+ } - } - - @test fun toFloat() { -- assertEqualsOrFailsNullable(77.0f, ""77.0"", String::toFloat, String::toFloatOrNull) -- assertEqualsOrFailsNullable(Float.NEGATIVE_INFINITY, ""-1e39"", String::toFloat, String::toFloatOrNull) -- assertEqualsOrFailsNullable(Float.POSITIVE_INFINITY, ""1000000000000000000000000000000000000000"", -- String::toFloat, String::toFloatOrNull) -+ CompareBehaviourContext(String::toFloat, String::toFloatOrNull).apply { - -- assertEqualsOrFailsNullable(null, ""dark side"", String::toFloat, String::toFloatOrNull) -+ assertProduce(77.0f, ""77.0"") -+ assertProduce(Float.NEGATIVE_INFINITY, ""-1e39"") -+ assertProduce(Float.POSITIVE_INFINITY, ""1000000000000000000000000000000000000000"") -+ assertProduce(null, ""dark side"") -+ } - } - - @test fun toDouble() { -- assertEqualsOrFailsNullable(-77.0, ""-77"", String::toDouble, String::toDoubleOrNull) -- assertEqualsOrFailsNullable(77.0, ""77."", String::toDouble, String::toDoubleOrNull) -- assertEqualsOrFailsNullable(77.0, ""77.0"", String::toDouble, String::toDoubleOrNull) -- assertEqualsOrFailsNullable(-1.77, ""-1.77"", String::toDouble, String::toDoubleOrNull) -- assertEqualsOrFailsNullable(0.77, ""+.77"", String::toDouble, String::toDoubleOrNull) -- assertEqualsOrFailsNullable(-77.0, ""\t-77 \n"", String::toDouble, String::toDoubleOrNull) -- assertEqualsOrFailsNullable(77.0, ""7.7e1"", String::toDouble, String::toDoubleOrNull) -- assertEqualsOrFailsNullable(77.0, ""+770e-1"", String::toDouble, String::toDoubleOrNull) -- -- assertEqualsOrFailsNullable(-Double.NaN, ""-NaN"", String::toDouble, String::toDoubleOrNull) -- assertEqualsOrFailsNullable(Double.POSITIVE_INFINITY, ""+Infinity"", String::toDouble, String::toDoubleOrNull) -- assertEqualsOrFailsNullable((0x77 shl 1).toDouble(), ""0x77p1"", String::toDouble, String::toDoubleOrNull) -- assertEqualsOrFailsNullable(0x77.toDouble(), ""0x.77P8"", String::toDouble, String::toDoubleOrNull) -- -- assertEqualsOrFailsNullable(null, ""7..7"", String::toDouble, String::toDoubleOrNull) -- assertEqualsOrFailsNullable(null, ""0x77e1"", String::toDouble, String::toDoubleOrNull) -- assertEqualsOrFailsNullable(null, ""007 not a number"", String::toDouble, String::toDoubleOrNull) -+ CompareBehaviourContext(String::toDouble, String::toDoubleOrNull).apply { -+ -+ assertProduce(-77.0, ""-77"") -+ assertProduce(77.0, ""77."") -+ assertProduce(77.0, ""77.0"") -+ assertProduce(-1.77, ""-1.77"") -+ assertProduce(0.77, ""+.77"") -+ assertProduce(-77.0, ""\t-77 \n"") -+ assertProduce(77.0, ""7.7e1"") -+ assertProduce(77.0, ""+770e-1"") -+ -+ assertProduce(-Double.NaN, ""-NaN"") -+ assertProduce(Double.POSITIVE_INFINITY, ""+Infinity"") -+ assertProduce((0x77 shl 1).toDouble(), ""0x77p1"") -+ assertProduce(0x77.toDouble(), ""0x.77P8"") -+ -+ assertProduce(null, ""7..7"") -+ assertProduce(null, ""0x77e1"") -+ assertProduce(null, ""007 not a number"") -+ } - } - } - --private inline fun assertEqualsOrFailsNullable(output: T?, -- input: String, -- crossinline converOrFail: (String) -> T, -- crossinline convertOrNull: (String) -> T?) { -- if(output == null) { -- assertFails { converOrFail(input) } -- assertNull (convertOrNull(input) ) -- } else { -- assertEquals(output, converOrFail(input)) -- assertEquals(output, convertOrNull(input)) -+ -+private class CompareBehaviourContext(val convertOrFail: (String) -> T, -+ val convertOrNull: (String) -> T?) { -+ fun assertProduce(output: T?, input: String) { -+ if(output == null) { -+ assertFails { convertOrFail(input) }","Please specify input string in the detail message, i.e. something like ""Expected to fail (or return null) on $input"" -",Could you also test that `toShort` returns `String::toShort`? -615,"@@ -13,8 +13,8 @@ private enum class State { - } - - /** -- * A base class to simplify implementing iterators so that implementations only have to implement [[computeNext()]] -- * to implement the iterator, calling [[done()]] when the iteration is complete. -+ * A base class to simplify implementing iterators so that implementations only have to implement [computeNext]","Warning, using this class has performance penalty compared to plain raw implementation per case, measured with JMH when operation per element is relatively cheap. -",is this change relevant to this PR? -616,"@@ -132,50 +132,34 @@ public inline fun println() { - System.out.println() - } - --// Since System.in can change its value on the course of program running, --// we should always delegate to current value and cannot just pass it to InputStreamReader constructor. --// We could use ""by"" implementation, but we can only use ""by"" with interfaces and InputStream is abstract class. --private val stdin: BufferedReader by lazy { BufferedReader(InputStreamReader(object : InputStream() { -- public override fun read(): Int { -- return System.`in`.read() -- } -- -- public override fun reset() { -- System.`in`.reset() -- } -- -- public override fun read(b: ByteArray): Int { -- return System.`in`.read(b) -- } -- -- public override fun close() { -- System.`in`.close() -- } -- -- public override fun mark(readlimit: Int) { -- System.`in`.mark(readlimit) -- } -- -- public override fun skip(n: Long): Long { -- return System.`in`.skip(n) -- } -- -- public override fun available(): Int { -- return System.`in`.available() -- } -- -- public override fun markSupported(): Boolean { -- return System.`in`.markSupported() -- } -- -- public override fun read(b: ByteArray, off: Int, len: Int): Int { -- return System.`in`.read(b, off, len) -- } --}))} -- - /** - * Reads a line of input from the standard input stream. - * - * @return the line read or `null` if the input stream is redirected to a file and the end of file has been reached. - */ --public fun readLine(): String? = stdin.readLine() -+ -+public fun readLine(): String? { -+ val buffer = StringBuilder() -+ var c = System.`in`.read() -+ if(c < 0) return null -+ buffer.append(c.toChar()) -+ do { -+ c = System.`in`.read() -+ if(c < 0) return buffer.toString() -+ val ch = c.toChar()","Unfortunately, this will work only for US-ASCII encoding. ",Why not use Charset.defaultCharset()? -617,"@@ -132,7 +132,10 @@ map.platform.class.to.kotlin=Change all usages of ''{0}'' in this file to ''{1}' - map.platform.class.to.kotlin.multiple=Change all usages of ''{0}'' in this file to a Kotlin class - map.platform.class.to.kotlin.advertisement=Choose an appropriate Kotlin class - map.platform.class.to.kotlin.family=Change to Kotlin class -- -+create.from.usage.family=Create from usage -+create.method.from.usage=Create method ''{0}'' from usage","In Kotlin, we call them functions, not methods. Please, rename it here and in other code. -",why is this needed? -618,"@@ -132,8 +132,13 @@ class AndroidGradleWrapper { - && variantData.scope.getRenderscriptCompileTask() != null) { - result.add(variantData.scope.getRenderscriptSourceOutputDir()); - } -+ } - -- return result -+ def getExtraSourcesMethod = variantData.getMetaClass().getMetaMethod(""getExtraGeneratedSourceFolders"") -+ if (getExtraSourcesMethod.returnType.metaClass == List.metaClass) { -+ result.addAll(variantData.getExtraGeneratedSourceFolders())","variantData.getExtraGeneratedSourceFolders() is Nullable, so you should check for null, before calling addAll -",Is this the correct logic? Why isn't the return type always a `List, CompilerMessage>() {","Isn't compiler exception logged as error? -",I don't think we need the internal log message here. -620,"@@ -133,15 +138,32 @@ public void execute() throws MojoExecutionException, MojoFailureException { - configureCompilerArguments(arguments, compiler); - printCompilerArgumentsIfDebugEnabled(arguments, compiler); - -- MessageCollector messageCollector = new MavenPluginLogMessageCollector(getLog()); -+ MavenPluginLogMessageCollector messageCollector = new MavenPluginLogMessageCollector(getLog(), true); - - ExitCode exitCode = compiler.exec(messageCollector, Services.EMPTY, arguments); - - switch (exitCode) { - case COMPILATION_ERROR: -- throw new MojoExecutionException(""Compilation error. See log for more details""); - case INTERNAL_ERROR: -- throw new MojoExecutionException(""Internal compiler error. See log for more details""); -+ throw new KotlinCompilationFailureException( -+ CollectionsKt.map(messageCollector.getCollectedErrors(), new Function1, CompilerMessage>() { -+ @Override -+ public CompilerMessage invoke(Pair pair) { -+ String lineContent = pair.getFirst().getLineContent(); -+ int lineContentLength = lineContent == null ? 0 : lineContent.length(); -+ -+ return new CompilerMessage( -+ pair.getFirst().getPath(), -+ CompilerMessage.Kind.ERROR, -+ pair.getFirst().getLine(),","Are they zero-based in `CompilerMessageLocation` ? -",nit: can use `StringUtils.nullToEmpty` here. -621,"@@ -133,16 +137,32 @@ public void execute() throws MojoExecutionException, MojoFailureException { - configureCompilerArguments(arguments, compiler); - printCompilerArgumentsIfDebugEnabled(arguments, compiler); - -- MessageCollector messageCollector = new MavenPluginLogMessageCollector(getLog()); -+ MavenPluginLogMessageCollector messageCollector = new MavenPluginLogMessageCollector(getLog()); - - ExitCode exitCode = compiler.exec(messageCollector, Services.EMPTY, arguments); - -- switch (exitCode) { -- case COMPILATION_ERROR: -- throw new MojoExecutionException(""Compilation error. See log for more details""); -- case INTERNAL_ERROR: -- throw new MojoExecutionException(""Internal compiler error. See log for more details""); -- default: -+ if (exitCode != ExitCode.OK) { -+ throw new KotlinCompilationFailureException( -+ CollectionsKt.map(messageCollector.getCollectedErrors(), new Function1, CompilerMessage>() { -+ @Override -+ public CompilerMessage invoke(Pair pair) { -+ CompilerMessageLocation location = pair.getFirst(); -+ String message = pair.getSecond(); -+ String lineContent = location.getLineContent(); -+ int lineContentLength = lineContent == null ? 0 : lineContent.length(); -+ -+ return new CompilerMessage( -+ location.getPath(), -+ CompilerMessage.Kind.ERROR,","yes, but in this case it looks not so clear that there is -1 and 0 with special meaning -","You can use `Pair.of(location, message)` here." -622,"@@ -133,8 +133,12 @@ private QuickFixes() {} - actions.put(VAL_WITH_SETTER, changeVariableMutabilityFix); - actions.put(VAL_REASSIGNMENT, changeVariableMutabilityFix); - -- actions.put(UNNECESSARY_SAFE_CALL, new ReplaceCallFix(false)); -- actions.put(UNSAFE_CALL, new ReplaceCallFix(true)); -+ actions.put(UNNECESSARY_SAFE_CALL, new ReplaceCallFix(true, false)); -+ actions.put(UNSAFE_CALL, new ReplaceCallFix(true, true)); -+ actions.put(UNSAFE_CALL, new ReplaceCallFix(false, true));","Two booleans in parameters almost always look bad because it's difficult to read such code. It's better to provide static constructors like ReplaceCallFix.toDotCall(), ReplaceCallFix.toQuestionMarkCall(), ReplaceCallFix.toExclamationCall(). Another alternative is to create and pass as parameter some enumeration. -",why is this changed? -623,"@@ -133,8 +133,14 @@ private QuickFixes() {} - actions.put(VAL_WITH_SETTER, changeVariableMutabilityFix); - actions.put(VAL_REASSIGNMENT, changeVariableMutabilityFix); - -- actions.put(UNNECESSARY_SAFE_CALL, new ReplaceCallFix(false)); -- actions.put(UNSAFE_CALL, new ReplaceCallFix(true)); -+ actions.put(UNNECESSARY_SAFE_CALL, ReplaceCallFix.toDotCallFromSafeCall()); -+ actions.put(UNSAFE_CALL, ReplaceCallFix.toSafeCall()); -+ -+ actions.put(UNSAFE_CALL, ReplaceCallFix.toNonNullAssertedCall()); -+ actions.put(UNNECESSARY_NOT_NULL_ASSERTION, ReplaceCallFix.toDotCallFromNonNullAssertedCall()); -+ -+ actions.put(UNNECESSARY_NOT_NULL_ASSERTION, new UnnecessaryNotNullAssertionFix());","Both quick fixes are available for this code snippet: -fun test(value : String) : String { - return value!!.toString() -} - -I suggest to forbid one from UnnecessaryNotNullAssertionFix if warning is in the middle of DOT_QUALIFIED_EXPRESSION. - -By the way, Sergey, what tools do you use for monitoring PSI tree. I don't remember did I tell you about Tools->View PSI structure of current file? -",It seems that this is the only place where the action should be added. -624,"@@ -135,4 +136,23 @@ public static KotlinSingleIntentionActionFactory createFactory() { - } - }; - } -+ -+ public static KotlinSingleIntentionActionFactory createLateInitFactory() {","Please convert this file to Kotlin if you're adding substantial new code to it. (Rename to .kt, commit, then rename back to .java, run J2K, make any changes needed for the project to compile, commit again, then make your changes.)",Would it make sense to rename this factory to createLateInitActionFactory? -625,"@@ -135,4 +136,23 @@ public static KotlinSingleIntentionActionFactory createFactory() { - } - }; - } -+ -+ public static KotlinSingleIntentionActionFactory createLateInitFactory() { -+ return new KotlinSingleIntentionActionFactory() { -+ @Override -+ public KotlinQuickFixAction createAction(@NotNull Diagnostic diagnostic) { -+ PsiElement element = Errors.INAPPLICABLE_LATEINIT_MODIFIER.cast(diagnostic).getPsiElement(); -+ KtProperty property = PsiTreeUtil.getParentOfType(element, KtProperty.class); -+ if (property == null) return null; -+ -+ boolean hasInitializer = property.hasInitializer(); -+ boolean hasGetter = property.getGetter() != null && property.getGetter().getBodyExpression() != null;","The getter and setter checks are not needed. This quickfix should apply to any lateinit property; _late_init means that it's initialized somewhere in the class, and this applies to regular properties with default getters and setters too.",What's the difference between this factory and the one above? -626,"@@ -135,7 +135,7 @@ public inline fun println() { - // Since System.in can change its value on the course of program running, - // we should always delegate to current value and cannot just pass it to InputStreamReader constructor. - // We could use ""by"" implementation, but we can only use ""by"" with interfaces and InputStream is abstract class. --private val stdin: BufferedReader by lazy { BufferedReader(InputStreamReader(object : InputStream() { -+private val stdin: InputStreamReader by lazy { InputStreamReader(object : InputStream() {","If we're not going to buffer contents, `stdin` wrapper isn't required anymore.",Line longer than 120 cols. Please fix. -627,"@@ -137,6 +137,16 @@ - ) - public String[] scriptResolverEnvironment; - -+ // Javac options -+ @Argument(value = ""-Xuse-javac"", description = ""Use Javac analysis"")","Consider something like `""Use javac for analysis of Java source and class files""`",I don't think we should add `-Xuse-javac` to the public API of javac. I do -628,"@@ -139,29 +140,34 @@ public fun File.readLines(charset: Charset = Charsets.UTF_8): List { - return result - } - --/** Creates a buffered reader, or returns self if Reader is already buffered */ -+/** Creates a buffered reader wrapping this Reader, or returns self if Reader is already buffered */","self -> this Reader -",Also mention that returns self. -629,"@@ -139,29 +140,34 @@ public fun File.readLines(charset: Charset = Charsets.UTF_8): List { - return result - } - --/** Creates a buffered reader, or returns self if Reader is already buffered */ -+/** Creates a buffered reader wrapping this Reader, or returns self if Reader is already buffered */ - public fun Reader.buffered(bufferSize: Int = defaultBufferSize): BufferedReader - = if (this is BufferedReader) this else BufferedReader(this, bufferSize) - --/** Creates a buffered writer, or returns self if Writer is already buffered */ -+/** Creates a buffered writer wrapping this Writer, or returns self if Writer is already buffered */","self -> this Writer -","typo ""wrapping"" -> ""writing""" -630,"@@ -139,4 +139,214 @@ The compiler issues warnings specific to `@Nullable`/`@NotNull` in the following - - a `@Nullable` value is assigned to a not-null location (including passing parameters and receivers to functions/properties); - - a nullable value is assigned to a `@NotNull` location; - - a `@NotNull` value is dereferenced with a safe call (`?.`), used in `!!` or on the left-hand side of an elvis operator `?:`; -- - a `@NotNull` value is compared with `null` through `==`, `!=`, `===` or `!==` -\ No newline at end of file -+ - a `@NotNull` value is compared with `null` through `==`, `!=`, `===` or `!==` -+ -+## More precise type information from annotations -+ -+Goals: -+ - Catch more errors related to nullability in case of Java interop -+ - Keep all class hierarchies consistent at all times (no hierarchy errors related to incorrect annotations) -+ - (!) If the code compiled with annotations, it should always compile without annotations (because external annotations may disappear) -+ -+ This process never results in errors. On any mismatch, a bare platform signature is used (and a warning issued). -+ -+### Annotations recognized by the compiler -+ -+- `org.jetbrains.annotations.Nullable` - value may be null/accepts nulls","Why only the JetBrains versions and not also javax.annotations versions? My own code won't benefit if this is the complete list. -",I'm not sure if this is the best way to go about annotating the annotation -631,"@@ -139,4 +139,214 @@ The compiler issues warnings specific to `@Nullable`/`@NotNull` in the following - - a `@Nullable` value is assigned to a not-null location (including passing parameters and receivers to functions/properties); - - a nullable value is assigned to a `@NotNull` location; - - a `@NotNull` value is dereferenced with a safe call (`?.`), used in `!!` or on the left-hand side of an elvis operator `?:`; -- - a `@NotNull` value is compared with `null` through `==`, `!=`, `===` or `!==` -\ No newline at end of file -+ - a `@NotNull` value is compared with `null` through `==`, `!=`, `===` or `!==` -+ -+## More precise type information from annotations -+ -+Goals: -+ - Catch more errors related to nullability in case of Java interop -+ - Keep all class hierarchies consistent at all times (no hierarchy errors related to incorrect annotations) -+ - (!) If the code compiled with annotations, it should always compile without annotations (because external annotations may disappear) -+ -+ This process never results in errors. On any mismatch, a bare platform signature is used (and a warning issued). -+ -+### Annotations recognized by the compiler -+ -+- `org.jetbrains.annotations.Nullable` - value may be null/accepts nulls -+- `org.jetbrains.annotations.NotNull` - value can not be null/passing null leads to an exception -+- `org.jetbrains.annotations.ReadOnly` - only non-mutating methods can be used on this collection/iterable/iterator -+- `org.jetbrains.annotations.Mutable` - only non-mutating methods can be used on this collection/iterable/iterator","This description seems duplicated? -",Please add a note that this value must be null/passing null for the compil -632,"@@ -139,8 +140,8 @@ public boolean isVar() { - - @NotNull - @Override -- public ValueParameterDescriptor copy(@NotNull DeclarationDescriptor newOwner) { -- return new ValueParameterDescriptorImpl(newOwner, index, Lists.newArrayList(getAnnotations()), getName(), getType(), hasDefaultValue, varargElementType); -+ public ValueParameterDescriptor copy(@NotNull DeclarationDescriptor newOwner, @NotNull Name newName) { -+ return new ValueParameterDescriptorImpl(newOwner, index, Lists.newArrayList(getAnnotations()), newName, getType(), declaresDefaultValue(), varargElementType);","I have changed `hasDefaultValue` to `declaresDefaultValue()` - I think that is correct (the constructor parameter is named `declaresDefaultValue`). Besides, `hasDefaultValue` is computed lazily in `hasDefaultValue()` and can be `null` resulting in `NullPointerException` (which, in fact, it does). -",`varargElementType` -> `varargElementType` -633,"@@ -14,48 +14,47 @@ public fun Appendable.appendln(value: CharSequence?): Appendable = append(value) - /** Appends value to the given Appendable and line separator after it. */ - public fun Appendable.appendln(value: Char): Appendable = append(value).append(LINE_SEPARATOR) - --/** Appends line separator to StringBuilder. */ -- -+/** Appends a line separator to this StringBuilder. */ - public fun StringBuilder.appendln(): StringBuilder = append(LINE_SEPARATOR) - --/** Appends value to the given StringBuilder and line separator after it. */ -+/** Appends value to this StringBuilder and line separator after it. */","backtickify value, linkify StringBuilder -","typo: ""this StringBuilder"" -> ""this StringBuilder""" -634,"@@ -14,6 +14,44 @@ public fun File.recurse(block: (File) -> Unit): Unit { - } - - /** -+ * Create an empty directory in the specified directory, using the given prefix and suffix to generate its name. -+ * Prefix shouldn't be shorter than 3 symbols or IllegalArgumentException will be thrown. -+ * -+ * If prefix is not specified then some unspecified name will be used. -+ * If suffix is not specified then "".tmp"" will be used. -+ * If directory is not specified then the default temporary-file directory will be used. -+ * -+ * Returns a file object corresponding to a newly-created directory. -+ * -+ * If some error occurs then IOException is thrown. -+ */ -+public fun createTempDir(prefix: String = ""tmp"", suffix: String? = null, directory: File? = null): File {","I don't really like global functions in stdlib, until absolutely necessary. They pollute global namespace, since they are in the `kotlin` package. Consider creating object to group them into. -",Can you also clarify that these arguments are optional and default values -635,"@@ -14,7 +14,7 @@ fun elements(): List { - doc { f -> ""Returns `true` if [element] is found in the ${f.collection}."" } - typeParam(""@kotlin.internal.OnlyInputTypes T"") - returns(""Boolean"") -- body(Iterables) { f -> -+ body(Iterables) {","Please extract unrelated changes, such as formatting improvement in a separate PR.",Why did you remove the anonymous function? -636,"@@ -14,88 +14,77 @@ import java.util.Collections // TODO: it's temporary while we have java.util.Col - * Returns an ArrayList of all elements - */ - public fun Array.toArrayList(): ArrayList { -- val list = ArrayList(size()) -- for (item in this) list.add(item) -- return list -+ return this.asList().toArrayList() - } - - /** - * Returns an ArrayList of all elements - */ - public fun BooleanArray.toArrayList(): ArrayList { -- val list = ArrayList(size()) -- for (item in this) list.add(item) -- return list -+ return this.asList().toArrayList() - } - - /** - * Returns an ArrayList of all elements - */ - public fun ByteArray.toArrayList(): ArrayList { -- val list = ArrayList(size()) -- for (item in this) list.add(item) -- return list -+ return this.asList().toArrayList() - } - - /** - * Returns an ArrayList of all elements - */ - public fun CharArray.toArrayList(): ArrayList { -- val list = ArrayList(size()) -- for (item in this) list.add(item) -- return list -+ return this.asList().toArrayList() - } - - /** - * Returns an ArrayList of all elements - */ - public fun DoubleArray.toArrayList(): ArrayList { -- val list = ArrayList(size()) -- for (item in this) list.add(item) -- return list -+ return this.asList().toArrayList() - } - - /** - * Returns an ArrayList of all elements - */ - public fun FloatArray.toArrayList(): ArrayList { -- val list = ArrayList(size()) -- for (item in this) list.add(item) -- return list -+ return this.asList().toArrayList() - } - - /** - * Returns an ArrayList of all elements - */ - public fun IntArray.toArrayList(): ArrayList { -- val list = ArrayList(size()) -- for (item in this) list.add(item) -- return list -+ return this.asList().toArrayList() - } - - /** - * Returns an ArrayList of all elements - */ - public fun LongArray.toArrayList(): ArrayList { -- val list = ArrayList(size()) -- for (item in this) list.add(item) -- return list -+ return this.asList().toArrayList() - } - - /** - * Returns an ArrayList of all elements - */ - public fun ShortArray.toArrayList(): ArrayList { -- val list = ArrayList(size()) -- for (item in this) list.add(item) -- return list -+ return this.asList().toArrayList() -+} -+ -+/** -+ * Returns an ArrayList of all elements -+ */ -+public fun Collection.toArrayList(): ArrayList { -+ return ArrayList(this) - } - - /** - * Returns an ArrayList of all elements - */ - public fun Iterable.toArrayList(): ArrayList { -- return toCollection(ArrayList(collectionSizeOrDefault(10))) -+ return toCollection(ArrayList())","Still it makes sense to check an actual type of this `Iterable` and switch to `Collection.toArrayList` in case if this is a collection. -",Can't you use `asList()` on the outer ArrayList? -637,"@@ -141,13 +141,28 @@ public static void checkAnnotationType( - } - } - -+ @Nullable -+ private static T findAncestorOfType(@NotNull PsiElement element, Class ancestorType) {","There is already `getParentOfType`, please use it here",Please annotate `@Nullable`. -638,"@@ -141,6 +183,64 @@ public open class KotlinCompile(): AbstractCompile() { - } - } - -+public open class Kotlin2JsCompile(): AbstractKotlinCompile() { -+ override val compiler = K2JSCompiler() -+ -+ override fun createBlankArgs(): K2JSCompilerArguments = K2JSCompilerArguments() -+ -+ public fun addLibraryFiles(vararg fs: String) { -+ kotlinOptions.libraryFiles = (kotlinOptions.libraryFiles + fs).copyToArray() -+ } -+ -+ public fun addLibraryFiles(vararg fs: File) { -+ val strs = fs.map{it.getPath()}.copyToArray() -+ addLibraryFiles(*strs) -+ } -+ -+ fun outputFile(): String { -+ return if (StringUtils.isEmpty(kotlinOptions.outputFile)) { -+ ""${kotlinDestinationDir}/app.js""","I think outputFile can not be omitted and if it omitted compilation should be failed. -",`map{it.getPath()}` can be replaced by ` just `fs.map(it::getPath).copyToA -639,"@@ -141,6 +183,64 @@ public open class KotlinCompile(): AbstractCompile() { - } - } - -+public open class Kotlin2JsCompile(): AbstractKotlinCompile() { -+ override val compiler = K2JSCompiler() -+ -+ override fun createBlankArgs(): K2JSCompilerArguments = K2JSCompilerArguments() -+ -+ public fun addLibraryFiles(vararg fs: String) { -+ kotlinOptions.libraryFiles = (kotlinOptions.libraryFiles + fs).copyToArray() -+ } -+ -+ public fun addLibraryFiles(vararg fs: File) { -+ val strs = fs.map{it.getPath()}.copyToArray() -+ addLibraryFiles(*strs) -+ } -+ -+ fun outputFile(): String { -+ return if (StringUtils.isEmpty(kotlinOptions.outputFile)) { -+ ""${kotlinDestinationDir}/app.js"" -+ } else { -+ kotlinOptions.outputFile -+ } -+ } -+ -+ public fun sourceMapDestinationDir(): File = File(outputFile()).directory -+ -+ { -+ getOutputs().file(MethodClosure(this, ""outputFile"")) -+ } -+ -+ override fun populateTargetSpecificArgs(args: K2JSCompilerArguments, sources: ArrayList) { -+ args.outputFile = outputFile() -+ args.outputPrefix = kotlinOptions.outputPrefix -+ args.outputPostfix = kotlinOptions.outputPostfix -+ args.libraryFiles = kotlinOptions.libraryFiles -+ args.target = kotlinOptions.target -+ args.sourceMap = kotlinOptions.sourceMap -+ -+ val outputDir = File(args.outputFile).directory -+ if (!outputDir.exists()) { -+ if (!outputDir.mkdirs()) { -+ throw GradleException(""Failed to create output directory ${outputDir} or one of its ancestors"") -+ } -+ } -+ } -+} -+ -+public open class RewritePathsInSourceMap(): DefaultTask() { -+ var sourceMapPath: () -> String = {""""} -+ var sourceRootDir: () -> String = {""""} -+ -+ [TaskAction] fun rewrite() { -+ val file = File(sourceMapPath()) -+ val text = file.readText(""UTF-8"")","charset parameter may be omitted -- UTF-8 will by use by default -",Please rename this to `createOutputDir` to make it clear what this is doin -640,"@@ -141,7 +185,63 @@ public open class KotlinCompile(): AbstractCompile() { - } - } - --public open class KDoc(): SourceTask() { -+public open class Kotlin2JsCompile() : AbstractKotlinCompile() { -+ override val compiler = K2JSCompiler() -+ -+ override fun createBlankArgs(): K2JSCompilerArguments = K2JSCompilerArguments() -+ -+ public fun addLibraryFiles(vararg fs: String) {","I think we should extract all libraries from dependencies instead. -",The `K2JSCompiler` has nothing to do with this PR. -641,"@@ -141,7 +185,63 @@ public open class KotlinCompile(): AbstractCompile() { - } - } - --public open class KDoc(): SourceTask() { -+public open class Kotlin2JsCompile() : AbstractKotlinCompile() { -+ override val compiler = K2JSCompiler() -+ -+ override fun createBlankArgs(): K2JSCompilerArguments = K2JSCompilerArguments() -+ -+ public fun addLibraryFiles(vararg fs: String) { -+ kotlinOptions.libraryFiles = (kotlinOptions.libraryFiles + fs).copyToArray() -+ } -+ -+ public fun addLibraryFiles(vararg fs: File) { -+ val strs = fs.map { it.getPath() }.copyToArray() -+ addLibraryFiles(*strs) -+ } -+ -+ fun outputFile(): String? = kotlinOptions.outputFile -+ -+ public fun sourceMapDestinationDir(): File = File(outputFile()).directory -+ -+ { -+ getOutputs().file(MethodClosure(this, ""outputFile"")) -+ } -+ -+ override fun populateTargetSpecificArgs(args: K2JSCompilerArguments) { -+ args.outputFile = outputFile() -+ args.outputPrefix = kotlinOptions.outputPrefix -+ args.outputPostfix = kotlinOptions.outputPostfix -+ args.libraryFiles = kotlinOptions.libraryFiles -+ args.target = kotlinOptions.target -+ args.sourceMap = kotlinOptions.sourceMap -+ -+ if (args.outputFile == null) { -+ throw GradleException(""${getName()}.kotlinOptions.outputFile must be set to a string."") -+ } -+ -+ val outputDir = File(args.outputFile).directory -+ if (!outputDir.exists()) { -+ if (!outputDir.mkdirs()) { -+ throw GradleException(""Failed to create output directory ${outputDir} or one of its ancestors"") -+ } -+ } -+ } -+} -+ -+public open class RewritePathsInSourceMap() : DefaultTask() {","Ideally it should be fixed in compiler as part of [KT-4078](https://youtrack.jetbrains.com/issue/KT-4078). You can just add TODO comment that this hack should be dropped after KT-4078 will be fixed or fix it :) -",Reword the name to indicate that this is a map fil -642,"@@ -142,7 +176,7 @@ public inline fun > Map.mapKeysTo(destinatio - } - - /** -- * Puts all the entries into this [[MutableMap]] with the first value in the pair being the key and the second the value -+ * Puts all the entries into this [MutableMap] with the first value in the pair being the key and the second the value","""Puts given values"", and again value vs component for Pair. -",Not sure this is correct. It should be like `with -643,"@@ -144,8 +146,14 @@ fun createKeywordConstructLookupElement( - val beforeCaret = tailBeforeCaret.indentLinesAfterFirst(newIndent) - val afterCaret = tailAfterCaret.indentLinesAfterFirst(newIndent) - -- insertionContext.document.insertString(offset, beforeCaret + afterCaret) -- insertionContext.editor.moveCaret(offset + beforeCaret.length) -+ val element = insertionContext.file.findElementAt(offset)?.getNextSiblingIgnoringWhitespaceAndComments(true)","Why getNextSiblingIgnoringWhitespaceAndComments() is needed? I expect that it is for 'for' keyword completion, but at least one test needed for it. -I also think that there shouldn't be comments skipping.",Refactor repeated use of `insertionContext.file` i -644,"@@ -144,8 +146,14 @@ fun createKeywordConstructLookupElement( - val beforeCaret = tailBeforeCaret.indentLinesAfterFirst(newIndent) - val afterCaret = tailAfterCaret.indentLinesAfterFirst(newIndent) - -- insertionContext.document.insertString(offset, beforeCaret + afterCaret) -- insertionContext.editor.moveCaret(offset + beforeCaret.length) -+ val element = insertionContext.file.findElementAt(offset)?.getNextSiblingIgnoringWhitespaceAndComments(true) -+ -+ if (element != null && beforeCaret.trimStart().startsWith(insertionContext.document.getText(TextRange.from(element.startOffset, 1)))) {",I think it will be more safe to use == instead of startsWith(),"Please don't remove the `moveCaret` method, it's n" -645,"@@ -145,10 +145,22 @@ private static JetElement overrideFunction(Project project, JetFile file, Simple - StringBuilder bodyBuilder = new StringBuilder(""override fun ""); - bodyBuilder.append(descriptor.getName()); - bodyBuilder.append(""(""); -+ boolean isAbstractFun = descriptor.getModality() == Modality.ABSTRACT; -+ StringBuilder delegationBuilder = new StringBuilder();","It's not very critical now, but I think that your decision to barter flat and simple structure of this method to one more iteration over parameters collection was a bad deal. Now it's really difficult to understand the logic of filling StringBuilder variables. -",`isAbstractFun` -> `isAbstract` -646,"@@ -15,6 +15,7 @@ public abstract class Mine : java.util.AbstractList { - public open /*fake_override*/ fun clear(): kotlin.Unit - public open /*fake_override*/ fun contains(/*0*/ T!): kotlin.Boolean - public open /*fake_override*/ fun containsAll(/*0*/ kotlin.collections.Collection): kotlin.Boolean -+ public open /*fake_override*/ fun forEach(/*0*/ java.util.function.Consumer!): kotlin.Unit","You'd better not to change existing tests, but to create a new test group with the same test data and your flag enabled.",You might be able to use `java.util.function.Consu -647,"@@ -151,7 +185,7 @@ public fun MutableMap.putAll(vararg values: Pair): Unit { - } - - /** -- * Puts all the entries into this [[MutableMap]] with the first value in the pair being the key and the second the value -+ * Puts all the entries into this [MutableMap] with the first value in the pair being the key and the second the value","""Puts elements of the given collection"" -",Not sure this is correct. It should be like `with -648,"@@ -152,13 +152,14 @@ class ClassBodyConverter(private val psiClass: PsiClass, - ): Member? { - when (member) { - is PsiMethod -> { -- memberToPropertyInfo[member]?.let { propertyInfo -> -- if (propertyInfo.field != null) return null // just drop the method, property will be generated when converting the field -- return if (member == propertyInfo.getMethod || propertyInfo.getMethod == null) -- converter.convertProperty(propertyInfo, classKind) -- else -- null // drop the method, property will be generated when converting the field or the getter -- } -+ if (!member.hasModifierProperty(PsiModifier.NATIVE))","This doesn't seem to be a correct check. This is valid Kotlin: - -``` kotlin -val foo: Int = 0 - external get -``` -",Does this mean that we don't convert the getter to -649,"@@ -1520,6 +1520,15 @@ - language=""kotlin"" - /> - -+ - -+ diagnosticFactory -+ ) { -+ // If is not a property, then it must have no modifier -+ if (parameter.getValOrVarNode() == null) { -+ checkParameterHasNoModifier(trace, parameter, diagnosticFactory); -+ } -+ } -+ -+ public static void checkParameterHasNoModifier( -+ @NotNull BindingTrace trace, -+ @NotNull JetParameter parameter, -+ @NotNull DiagnosticFactory1 diagnosticFactory -+ ) { -+ JetModifierList modifiers = parameter.getModifierList(); -+ if (modifiers != null) { -+ ASTNode node = modifiers.getNode().getFirstChildNode(); -+ -+ while (node != null) { -+ IElementType elementType = node.getElementType(); -+ -+ if (elementType != JetTokens.VARARG_KEYWORD && elementType instanceof JetKeywordToken) { -+ trace.report(diagnosticFactory.on(node.getPsi(), (JetKeywordToken) elementType)); -+ break;","fun foo(public abstract x: Int) //abstract should also highlighted as error -",Nit: I would prefer `checkConstructorParameterHasN -652,"@@ -158,6 +157,7 @@ protected void blackBox() { - Method method = aClass.getMethod(""box""); - String r = (String) method.invoke(null); - assertEquals(""OK"", r); -+ System.out.println(generateToText());","I beleive this was commited erroneously. -",This looks like a debug statement. -653,"@@ -16,10 +16,25 @@ - - package kotlin - -+/** -+ * Represents a sequence of numbers or characters with a given start value, end value and step. -+ * This class is intended to be used in 'for' loops, and the JVM backend suggests efficient -+ * bytecode generation for it. Progressions with a step of -1 can be created through the -+ * `downTo` method on classes representing primitive types.","Link to `downTo` method. -",The enum value is `-1` and the enum value is `-1`. -654,"@@ -16,10 +16,25 @@ - - package kotlin - -+/** -+ * Represents a sequence of numbers or characters with a given start value, end value and step. -+ * This class is intended to be used in 'for' loops, and the JVM backend suggests efficient -+ * bytecode generation for it. Progressions with a step of -1 can be created through the -+ * `downTo` method on classes representing primitive types. -+ */ - public trait Progression : Iterable { -+ /** -+ * The start value of a progression. -+ */ - public val start: N - -+ /** -+ * The end value of the progression (inclusive).","start ""a progression"", end ""the progression"" -",Would be good to mention that `step` must be a pri -655,"@@ -16,10 +16,25 @@ - - package kotlin - -+/** -+ * The root of the Kotlin class hierarchy. Every Kotlin class has [Any] as a superclass. -+ */ - public open class Any { -+ /** -+ * Indicates whether some other object is ""equal to"" this one. Implementations must follow -+ * the same contract as the [Java equals() method](http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals%28java.lang.Object%29).","Referencing Java in such a way doesn't make it look like a standard library for a _language_, which is targeting different platforms. E.g. for JS it may be different contract. -",Would it be possible to add a link to the docs for -656,"@@ -16,10 +16,25 @@ - - package kotlin - -+/** -+ * The root of the Kotlin class hierarchy. Every Kotlin class has [Any] as a superclass. -+ */ - public open class Any { -+ /** -+ * Indicates whether some other object is ""equal to"" this one. Implementations must follow -+ * the same contract as the [Java equals() method](http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals%28java.lang.Object%29). -+ * Note that the `==` operator in Kotlin code is translated into a null-safe call to [equals].","Expand ""null-safe call"". I would read it as ""a?.equals(b)"" which is wrong, because expression type for `==` is `Boolean`, not `Boolean?` -",Note that `==` operator in Kotlin is translated into `==`. -657,"@@ -16,10 +16,25 @@ - - package kotlin - -+/** -+ * The root of the Kotlin class hierarchy. Every Kotlin class has [Any] as a superclass. -+ */ - public open class Any { -+ /** -+ * Indicates whether some other object is ""equal to"" this one. Implementations must follow -+ * the same contract as the [Java equals() method](http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals%28java.lang.Object%29). -+ * Note that the `==` operator in Kotlin code is translated into a null-safe call to [equals]. -+ */ - public open fun equals(other: Any?): Boolean - -+ /** -+ * Returns a hash code value for the object. Implementations must follow the same contract -+ * as the [Java hashCode() method](http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#hashCode%28%29).","Same note about Java-ism. -",Note that `equals(Object)` is translated into `equals(Obje -658,"@@ -16,10 +16,30 @@ - - package kotlin - -+/** -+ * Marks the annotated class as a data class. Data classes have automatically generated","""When processing data class, compiler will generate""... -",This file has nothing to do with the PR. -659,"@@ -16,11 +16,17 @@ - - package org.jetbrains.jet.plugin.refactoring.rename; - --import org.jetbrains.jet.JetTestUtils; --import org.jetbrains.jet.test.TestMetadata; -+import junit.framework.Assert; -+import junit.framework.Test; -+import junit.framework.TestSuite; - - import java.io.File; - import java.util.regex.Pattern; -+import org.jetbrains.jet.JetTestUtils; -+import org.jetbrains.jet.test.InnerTestClasses; -+import org.jetbrains.jet.test.TestMetadata; -+ -+import org.jetbrains.jet.plugin.refactoring.rename.AbstractRenameTest;","Changes in this file shouldn't have been included in your pull request -",Please remove this unnecessary import. -660,"@@ -16,13 +16,31 @@ - - package kotlin - -+/** -+ * Returns true if the receiver and the [other] object are the same object instance, or if they -+ * are both null. -+ */ - public fun Any?.identityEquals(other: Any?): Boolean // = this === other - -+/** -+ * Returns true if the receiver and the [other] object are ""equal"" to each other, or if they are","Link to Any.equals() on ""equal"" would be good, to refer to explanation of equality. -","If the [other] object are the same object instance, then i" -661,"@@ -16,13 +16,44 @@ - - package kotlin - -+/** -+ * Represents an array (specifically, a Java array when targeting the JVM platform). -+ * Array instances can be created using the [array] and [arrayOfNulls] standard -+ * library functions. -+ * See [Kotlin language documentation](http://kotlinlang.org/docs/reference/basic-types.html#arrays) -+ * for more information on arrays. -+ */ - public class Array private (): Cloneable { -+ /** -+ * Returns the array element at the specified [index]. This method can be called using the -+ * brackets notation:","We usually call it ""index operator"", I think, not ""brackets notation"". -",nit: remove the period after `arrayOfNulls` -662,"@@ -16,13 +16,44 @@ - - package kotlin - -+/** -+ * Represents an array (specifically, a Java array when targeting the JVM platform). -+ * Array instances can be created using the [array] and [arrayOfNulls] standard -+ * library functions. -+ * See [Kotlin language documentation](http://kotlinlang.org/docs/reference/basic-types.html#arrays) -+ * for more information on arrays. -+ */ - public class Array private (): Cloneable { -+ /** -+ * Returns the array element at the specified [index]. This method can be called using the -+ * brackets notation: -+ * ``` -+ * val = arr[index]","bad example, ""val"" is keyword. -",@jkwatson What do you think about this new sentence? `This -663,"@@ -16,13 +16,44 @@ - - package kotlin - -+/** -+ * Represents an array (specifically, a Java array when targeting the JVM platform). -+ * Array instances can be created using the [array] and [arrayOfNulls] standard -+ * library functions. -+ * See [Kotlin language documentation](http://kotlinlang.org/docs/reference/basic-types.html#arrays) -+ * for more information on arrays. -+ */ - public class Array private (): Cloneable { -+ /** -+ * Returns the array element at the specified [index]. This method can be called using the -+ * brackets notation: -+ * ``` -+ * val = arr[index] -+ * ``` -+ */ - public fun get(index: Int): T -+ -+ /** -+ * Sets the array element at the specified [index] to the specified [value]. This method can -+ * be called using the brackets notation: -+ * ``` -+ * arr[index] = val","Same here for ""brackets"" and ""val"" -","Nit: should be `arr`, not `arr`." -664,"@@ -16,13 +16,44 @@ - - package kotlin - -+/** -+ * Represents an array (specifically, a Java array when targeting the JVM platform). -+ * Array instances can be created using the [array] and [arrayOfNulls] standard -+ * library functions. -+ * See [Kotlin language documentation](http://kotlinlang.org/docs/reference/basic-types.html#arrays) -+ * for more information on arrays. -+ */ - public class Array private (): Cloneable { -+ /** -+ * Returns the array element at the specified [index]. This method can be called using the -+ * brackets notation: -+ * ``` -+ * val = arr[index] -+ * ``` -+ */ - public fun get(index: Int): T -+ -+ /** -+ * Sets the array element at the specified [index] to the specified [value]. This method can -+ * be called using the brackets notation: -+ * ``` -+ * arr[index] = val -+ * ``` -+ */ - public fun set(index: Int, value: T): Unit - -+ /** -+ * Returns the length of the array.","""Returns number of elements in the array"". Method called ""size"" shouldn't be described with word ""length"" -",Could you add a link to the JIRA issue and add a link to t -665,"@@ -16,14 +16,9 @@ - - package org.jetbrains.kotlin.resolve.descriptorUtil - --import org.jetbrains.kotlin.descriptors.DeclarationDescriptor - import org.jetbrains.kotlin.descriptors.annotations.Annotated - import org.jetbrains.kotlin.name.FqName - --private val HIDDEN_ANNOTATION_FQ_NAME = FqName(""kotlin.HiddenDeclaration"") -- --public fun DeclarationDescriptor.isAnnotatedAsHidden(): Boolean = annotations.findAnnotation(HIDDEN_ANNOTATION_FQ_NAME) != null -- - private val NO_INFER_ANNOTATION_FQ_NAME = FqName(""kotlin.NoInfer"")","I think this whole file should be moved to `frontend`... -",Add a TODO to remove this once the annotation is removed. -666,"@@ -16,18 +16,25 @@ - - package kotlin.script.templates.standard - -+// discuss -+// -+// These are some 'basic' script templates -+// Should we keep them here?","I think we should do the following with these: -* `SimpleScriptTemplate` -> remove (script with args can be always used instead of it) -* `kotlin.script.templates.standard.ScriptTemplateWithArgs` -> rename and move to `kotlin.script.templates.StandardScriptTemplate` -* `kotlin.script.templates.standard.ScriptTemplateWithBindings` -> move to `kotlin.script.templates.ScriptTemplateWithBindings`",How about: `// Keep them in the 'basic' script template` ? -667,"@@ -16,26 +16,66 @@ - - package kotlin - -+/** -+ * An iterator over a collection. Allows to sequentially access the elements in a collection.","Not necessary ""in a collection"". -","This isn't a collection, it's a collection of elements." -668,"@@ -16,26 +16,66 @@ - - package kotlin - -+/** -+ * An iterator over a collection. Allows to sequentially access the elements in a collection. -+ */ - public trait Iterator { -+ /** -+ * Returns the next element in the iteration. -+ */ - public fun next(): T -+ -+ /** -+ * Returns `true` if the iteration has more elements. -+ */ - public fun hasNext(): Boolean - } - -+/** -+ * An iterator over a mutable collection. Provides the ability to remove elements while iterating. -+ * @see MutableCollection.iterator -+ */ - public trait MutableIterator : Iterator { -+ /** -+ * Removes from the underlying collection the last element returned by this iterator. -+ */ - public fun remove(): Unit - } - -+/** -+ * An iterator over a collection that supports indexed access. -+ * @see List.listIterator -+ */ - public trait ListIterator : Iterator { - // Query Operations - override fun next(): T","Do we need overrides here? -","Is there a reason for this trait to be immutable? If not, " -669,"@@ -16,29 +16,26 @@ - - package org.jetbrains.kotlin.idea.codeInsight.surroundWith - --import com.intellij.openapi.project.Project - import com.intellij.psi.PsiElement - import com.intellij.psi.PsiReference - import com.intellij.psi.search.LocalSearchScope - import com.intellij.psi.search.SearchScope - import com.intellij.psi.search.searches.ReferencesSearch - import com.intellij.psi.util.PsiUtilCore --import org.jetbrains.kotlin.descriptors.VariableDescriptor --import org.jetbrains.kotlin.idea.caches.resolve.* -+import org.jetbrains.kotlin.idea.caches.resolve.analyze - import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils --import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers - import org.jetbrains.kotlin.idea.core.ShortenReferences -+import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers - import org.jetbrains.kotlin.psi.* - import org.jetbrains.kotlin.resolve.BindingContext - import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode - import org.jetbrains.kotlin.types.KotlinType ++// JVM_IR_TEMPLATES ++// 1 ISTORE 2\s+L5",Thank you! Seems it's best to transform this test in future to debug one according to #2730,"Would it make sense to replace the hard-coded ""0"" with ""1ISTORE 0\s+L5""?" +225,"@@ -1,11 +1,11 @@ + + + +- ++ ","Changes like this in meta-information should be carefully reviewed before committing, because they can easily break compilation or workflow for other developers. +",Is this the right place for this? I'm not sure what the right place for +226,"@@ -1,11 +1,20 @@ +-// IGNORE_BACKEND: JVM_IR +-fun box() : String { - --import java.util.ArrayList -+import java.util.* - - object MoveDeclarationsOutHelper {","This `object` serves no purpose; the contents of the file should simply be top-level functions -",Could you make sure the imports are sorted alphabetically? -670,"@@ -16,40 +16,112 @@ - - package kotlin - -+/** -+ * Classes that inherit from this trait can be represented as a sequence of elements that can -+ * be iterated over. -+ */ - public trait Iterable {","doc for `T`? -",This is not true. The `out T` type is `Iterable` -671,"@@ -16,6 +16,11 @@ - - package kotlin.script.extensions - -+// discuss -+ -+// Is this an appropriate place to put this class?","This doesn't look like an appropriate place. If I understand correctly, it has nothing to do with scripts, so putting it into package `kotlin.script.extensions` is risky. As soon as we decide to publish it as a supported compiler plugin, we'll have to move it to another package and artifact, causing incompatibilities, so maybe it'd be better to do this earlier.",Why did you put this here instead of in `scripts/`? -672,"@@ -16,8 +16,18 @@ - - package kotlin - -+/** -+ * Annotates the parameter of a function annotates as [inline] and forbids inlining of","Typo: ""annotates as [inline]"" -> ""annotated as [inline]"" -","Perhaps should be ""annotates the parameter of a function as [inline] and forbids inlining of the parameter.""" -673,"@@ -16,8 +16,18 @@ - - package kotlin - -+/** -+ * Annotates the parameter of a function annotates as [inline] and forbids inlining of -+ * function literals passed as arguments for this parameter. -+ */ - public annotation class noinline - -+/**","Add cross-reference to other annotations, like `noinline` -",nit: typo ininlining -674,"@@ -161,6 +162,13 @@ object KotlinToJVMBytecodeCompiler { - ProgressIndicatorAndCompilationCanceledStatus.checkCanceled() - writeOutput(state.configuration, state.factory, null) - } -+ -+ if (chunk.size == 1 && projectConfiguration.getBoolean(JVMConfigurationKeys.USE_JAVAC)) {","If the chunk contains multiple modules and `-Xuse-javac` has been specified, maybe we should report a warning saying that we won't in fact use javac for compilation","I think we can remove this check. It's sufficient to check for ""chunk.size == 1"" when we have ""USE_JAVAC""" -675,"@@ -161,6 +162,14 @@ object KotlinToJVMBytecodeCompiler { - ProgressIndicatorAndCompilationCanceledStatus.checkCanceled() - writeOutput(state.configuration, state.factory, null) - } -+ -+ if (chunk.size == 1) { -+ val javacWrapper = JavacWrapper.getInstance(environment.project) -+ if (projectConfiguration[JVMConfigurationKeys.USE_JAVAC]!!) {",@baratynskiy Please use `getBoolean(...)` instead of `get(...)!!`,Remove the `!` -676,"@@ -162,4 +162,8 @@ change.function.signature.family=Change function signature - change.function.signature.chooser.title=Choose signature - change.function.signature.action=Change function signature - remove.unnecessary.parentheses=Remove unnecessary parentheses --remove.unnecessary.parentheses.family=Remove Unnecessary Parentheses -\ No newline at end of file -+remove.unnecessary.parentheses.family=Remove Unnecessary Parentheses -+add.function.to.supertype.family=Add Function to Supertype","While I know it's technically not 100% correct and maybe ""Add Function to _Superclassifier_"" would be a more accurate name for this quickfix I still want to stick with the name ""Add Function to Supertype"". In my opinion the user would be confused by using word ""superclassifier"". I can change the name though if you disagree. -",Why not just add this to `add.function.family`? -677,"@@ -1629,70 +1629,70 @@ public fun Stream.lastIndexOf(element: T): Int { - } - - /** -- * Returns last element, or null if collection is empty -+ * Returns the last element, or null if the collection is empty - */ - public fun Array.lastOrNull(): T? { - return if (isEmpty()) null else this[size() - 1] - } - - /** -- * Returns last element, or null if collection is empty -+ * Returns the last element, or null if the collection is empty - */ - public fun BooleanArray.lastOrNull(): Boolean? { - return if (isEmpty()) null else this[size() - 1] - } - - /** -- * Returns last element, or null if collection is empty -+ * Returns the last element, or null if the collection is empty - */ - public fun ByteArray.lastOrNull(): Byte? { - return if (isEmpty()) null else this[size() - 1] - } - - /** -- * Returns last element, or null if collection is empty -+ * Returns the last element, or null if the collection is empty - */ - public fun CharArray.lastOrNull(): Char? { - return if (isEmpty()) null else this[size() - 1] - } - - /** -- * Returns last element, or null if collection is empty -+ * Returns the last element, or null if the collection is empty - */ - public fun DoubleArray.lastOrNull(): Double? { - return if (isEmpty()) null else this[size() - 1] - } - - /** -- * Returns last element, or null if collection is empty -+ * Returns the last element, or null if the collection is empty - */ - public fun FloatArray.lastOrNull(): Float? { - return if (isEmpty()) null else this[size() - 1] - } - - /** -- * Returns last element, or null if collection is empty -+ * Returns the last element, or null if the collection is empty - */ - public fun IntArray.lastOrNull(): Int? { - return if (isEmpty()) null else this[size() - 1] - } ++class C() {",Please keep old test and add new one,Just remove the `ignore_backends: true` here. +227,"@@ -1,12 +1,13 @@ + package org.jetbrains.idl2k - /** -- * Returns last element, or null if collection is empty -+ * Returns the last element, or null if the collection is empty - */ - public fun LongArray.lastOrNull(): Long? { - return if (isEmpty()) null else this[size() - 1] - } +-import org.antlr.v4.runtime.ANTLRFileStream +-import kotlin.collections.HashSet ++import org.antlr.v4.runtime.CharStreams + import java.io.File + import java.io.IOException + import java.net.URL ++import java.nio.charset.StandardCharsets + import java.util.ArrayList + import java.util.LinkedHashMap ++import kotlin.collections.HashSet",import looks redundant,Could you please explain why this change is needed? +228,"@@ -1,13 +1,16 @@ + // IGNORE_BACKEND: JVM_IR + fun box() : String { +- 230?.toByte()?.hashCode() +- 9.hashCode() ++ // Just hard enough that the test won't get optimized away at compile time.",Were there any issues with this tests involving constant folding?,"I'm not sure that this is a good idea, as the result of `toByte()` can r" +229,"@@ -1,3 +1,19 @@ ++/*","It's added by IDEA's pre-commit action. Really shouldn't for generated files. +",Please remove this file. +230,"@@ -1,3 +1,3 @@ + package test - /** -- * Returns last element, or null if collection is empty -+ * Returns the last element, or null if the collection is empty","Back-tick quote ""null""? -",minor: I think the last element is not necessarily the last element in the collection. -678,"@@ -163,16 +217,341 @@ public open class KotlinCompile() : AbstractKotlinCompile, isIncrementalRequested: Boolean, modified: List, removed: List, cachesBaseDir: File) { -+ -+ if (experimentalIncremental) { -+ // TODO: consider other ways to pass incremental flag to compiler/builder -+ System.setProperty(""kotlin.incremental.compilation"", ""true"") -+ // TODO: experimental should be removed as soon as it becomes standard -+ System.setProperty(""kotlin.incremental.compilation.experimental"", ""true"") -+ } -+ -+ val targetType = ""java-production"" -+ val moduleName = args.moduleName -+ val targets = listOf(TargetId(moduleName, targetType)) -+ val outputDir = File(args.destination) -+ val caches = hashMapOf() -+ val lookupStorage = LookupStorage(File(cachesBaseDir, ""lookups"")) -+ val lookupTracker = LookupTrackerImpl(LookupTracker.DO_NOTHING) -+ var currentRemoved = removed -+ val allGeneratedFiles = hashSetOf>() -+ val compiledSourcesSet = hashSetOf() -+ -+ fun getOrCreateIncrementalCache(target: TargetId): GradleIncrementalCacheImpl {","It seems more like just ""createIncrementalCache"" -",What do you think about adding a new flag to `kotlin.generated.compilation` like `kotlin.incremental.compila -679,"@@ -163,16 +217,341 @@ public open class KotlinCompile() : AbstractKotlinCompile) = array ++fun doNothing(array: kotlin.IntArray, ignore: java.util.List) = array",And here we have `kotlin.` too,Why not just use `kotlin.IntArray`? +238,"@@ -1,4 +1,4 @@ + package test -+ override fun callCompiler(args: K2JVMCompilerArguments, sources: List, isIncrementalRequested: Boolean, modified: List, removed: List, cachesBaseDir: File) { -+ -+ if (experimentalIncremental) { -+ // TODO: consider other ways to pass incremental flag to compiler/builder -+ System.setProperty(""kotlin.incremental.compilation"", ""true"") -+ // TODO: experimental should be removed as soon as it becomes standard -+ System.setProperty(""kotlin.incremental.compilation.experimental"", ""true"") -+ } -+ -+ val targetType = ""java-production"" -+ val moduleName = args.moduleName -+ val targets = listOf(TargetId(moduleName, targetType)) -+ val outputDir = File(args.destination) -+ val caches = hashMapOf() -+ val lookupStorage = LookupStorage(File(cachesBaseDir, ""lookups"")) -+ val lookupTracker = LookupTrackerImpl(LookupTracker.DO_NOTHING) -+ var currentRemoved = removed -+ val allGeneratedFiles = hashSetOf>() -+ val compiledSourcesSet = hashSetOf() -+ -+ fun getOrCreateIncrementalCache(target: TargetId): GradleIncrementalCacheImpl { -+ val cacheDir = File(cachesBaseDir, ""increCache.${target.name}"") -+ cacheDir.mkdirs() -+ return GradleIncrementalCacheImpl(targetDataRoot = cacheDir, targetOutputDir = outputDir, target = target) -+ } -+ -+ fun getIncrementalCache(it: TargetId) = caches.getOrPut(it, { getOrCreateIncrementalCache(it) }) -+ -+ fun PsiClass.findLookupSymbols(): Iterable { -+ val fqn = qualifiedName.orEmpty() -+ return listOf(LookupSymbol(name.orEmpty(), if (fqn == name) """" else fqn.removeSuffix(""."" + name!!))) + -+ methods.map { LookupSymbol(it.name, fqn) } + -+ fields.map { LookupSymbol(it.name.orEmpty(), fqn) } + -+ innerClasses.flatMap { it.findLookupSymbols() } -+ } -+ -+ fun Iterable.files(filesFilter: (File) -> Boolean = { true }, logAction: (LookupSymbol, Iterable) -> Unit = { l,fs -> }): Iterable =","1. Formatting is unusual to our codebase (surrounding ""->"" with spaces). -2. logAction is the same for both call-sites -3. filesFiler is almost the same for call-sites. Could be replaced with excludedFiles: Set -","this is not the right way to do it. these arguments are not the same as the `kotlin.extra.compilation` flag," -680,"@@ -163,16 +217,341 @@ public open class KotlinCompile() : AbstractKotlinCompile) = a ++fun anyany(a: kotlin.Any, ignore: java.util.List) = a",Unclear. Why should you have `kotlin.` here and how it works without it?,I tried removing `Any` from `kotlin.Any` but not replacing it with `kotl +239,"@@ -1,4 +1,4 @@ +-// ""Change type of overriden property 'A.x' to '(Int) -> Int'"" ""false"" ++// ""Change type of overridden property 'A.x' to '(Int) -> Int'"" ""false""",Isn't this a part of our testdata markup? @mglukhikh ,Does this need a full stop at the end of the sentence? +240,"@@ -1,4 +1,4 @@ +-// WITH_RUNTIME ++// RUNTIME_WITH_FULL_JDK",Don't understand why it's needed,can we rename this to RUNTIME_WITH_RUNTIME_WITH_JDK ? +241,"@@ -1,4 +1,5 @@ + // !LANGUAGE: +InlineClasses ++// IGNORE_BACKEND: JVM_IR",What happens here?,Why is this needed? +242,"@@ -1,4 +1,5 @@ + // IGNORE_BACKEND_FIR: JVM_IR ++// IGNORE_BACKEND: JVM_IR","This test should not have passed. It is checking that no delegate field is created for interface delegation. It is doing so based on the name of the field, and therefore it now correctly fails because we do not have that optimization.",Should this be `IGNORE_BACKEND_IRR`? +243,"@@ -1,4 +1,5 @@ + package org.junit -+ override fun callCompiler(args: K2JVMCompilerArguments, sources: List, isIncrementalRequested: Boolean, modified: List, removed: List, cachesBaseDir: File) { -+ -+ if (experimentalIncremental) { -+ // TODO: consider other ways to pass incremental flag to compiler/builder -+ System.setProperty(""kotlin.incremental.compilation"", ""true"") -+ // TODO: experimental should be removed as soon as it becomes standard -+ System.setProperty(""kotlin.incremental.compilation.experimental"", ""true"") -+ } -+ -+ val targetType = ""java-production"" -+ val moduleName = args.moduleName -+ val targets = listOf(TargetId(moduleName, targetType)) -+ val outputDir = File(args.destination) -+ val caches = hashMapOf() -+ val lookupStorage = LookupStorage(File(cachesBaseDir, ""lookups"")) -+ val lookupTracker = LookupTrackerImpl(LookupTracker.DO_NOTHING) -+ var currentRemoved = removed -+ val allGeneratedFiles = hashSetOf>() -+ val compiledSourcesSet = hashSetOf() -+ -+ fun getOrCreateIncrementalCache(target: TargetId): GradleIncrementalCacheImpl { -+ val cacheDir = File(cachesBaseDir, ""increCache.${target.name}"") -+ cacheDir.mkdirs() -+ return GradleIncrementalCacheImpl(targetDataRoot = cacheDir, targetOutputDir = outputDir, target = target) -+ } -+ -+ fun getIncrementalCache(it: TargetId) = caches.getOrPut(it, { getOrCreateIncrementalCache(it) }) -+ -+ fun PsiClass.findLookupSymbols(): Iterable { -+ val fqn = qualifiedName.orEmpty() -+ return listOf(LookupSymbol(name.orEmpty(), if (fqn == name) """" else fqn.removeSuffix(""."" + name!!))) + -+ methods.map { LookupSymbol(it.name, fqn) } + -+ fields.map { LookupSymbol(it.name.orEmpty(), fqn) } + -+ innerClasses.flatMap { it.findLookupSymbols() } -+ } -+ -+ fun Iterable.files(filesFilter: (File) -> Boolean = { true }, logAction: (LookupSymbol, Iterable) -> Unit = { l,fs -> }): Iterable = -+ flatMap { lookup -> -+ val files = lookupStorage.get(lookup).map(::File).filter(filesFilter) -+ if (files.any()) { -+ logAction(lookup, files) -+ } -+ files -+ } -+ -+ fun dirtyLookupSymbolsFromRemovedKotlinFiles(): List {","I don't think these lookups can useful: -- for JPS a processing of removed classes is done in `clearCacheForRemovedClasses`; that method uses proto from caches for dirty fqnames; -- current implementation can only return lookups of classes. ++@Deprecated(""Use 'Test' from kotlin.test package"", replaceWith = ReplaceWith(""Test"", imports = ""kotlin.test.Test""))",👍 ,Why do you need to replace the import here? +244,"@@ -1,4 +1,7 @@ + // KJS_WITH_FULL_RUNTIME ++// TODO: muted automatically, investigate should it be ran for JVM_IR or not","Do you understand why these two tests are now failing. If so, can you replace this auto mute comment with an actual comment explaining what is going on?",Maybe `TODO(guomingz): investigate should it be run f +245,"@@ -1,5 +1,3 @@ +-// IGNORE_BACKEND: JVM_IR +-// WITH_RUNTIME","Please return `WITH_RUNTIME` in these tests: +* `boxAgainstJava/sam/differentFqNames.kt` +* `boxAgainstJava/sam/samConstructorGenericSignature.kt` +* `boxAgainstJava/sam/adapters/inheritedOverriddenAdapter.kt` -So I suggest to remove this function. -","this is not the right way to do it. these arguments are not the same as the `kotlin.extra.compilation` flag," -681,"@@ -163,16 +217,341 @@ public open class KotlinCompile() : AbstractKotlinCompile, isIncrementalRequested: Boolean, modified: List, removed: List, cachesBaseDir: File) { -+ -+ if (experimentalIncremental) { -+ // TODO: consider other ways to pass incremental flag to compiler/builder -+ System.setProperty(""kotlin.incremental.compilation"", ""true"") -+ // TODO: experimental should be removed as soon as it becomes standard -+ System.setProperty(""kotlin.incremental.compilation.experimental"", ""true"") -+ } -+ -+ val targetType = ""java-production"" -+ val moduleName = args.moduleName -+ val targets = listOf(TargetId(moduleName, targetType)) -+ val outputDir = File(args.destination) -+ val caches = hashMapOf() -+ val lookupStorage = LookupStorage(File(cachesBaseDir, ""lookups"")) -+ val lookupTracker = LookupTrackerImpl(LookupTracker.DO_NOTHING) -+ var currentRemoved = removed -+ val allGeneratedFiles = hashSetOf>() -+ val compiledSourcesSet = hashSetOf() -+ -+ fun getOrCreateIncrementalCache(target: TargetId): GradleIncrementalCacheImpl { -+ val cacheDir = File(cachesBaseDir, ""increCache.${target.name}"") -+ cacheDir.mkdirs() -+ return GradleIncrementalCacheImpl(targetDataRoot = cacheDir, targetOutputDir = outputDir, target = target) -+ } -+ -+ fun getIncrementalCache(it: TargetId) = caches.getOrPut(it, { getOrCreateIncrementalCache(it) }) -+ -+ fun PsiClass.findLookupSymbols(): Iterable { -+ val fqn = qualifiedName.orEmpty() -+ return listOf(LookupSymbol(name.orEmpty(), if (fqn == name) """" else fqn.removeSuffix(""."" + name!!))) + -+ methods.map { LookupSymbol(it.name, fqn) } + -+ fields.map { LookupSymbol(it.name.orEmpty(), fqn) } + -+ innerClasses.flatMap { it.findLookupSymbols() } -+ } -+ -+ fun Iterable.files(filesFilter: (File) -> Boolean = { true }, logAction: (LookupSymbol, Iterable) -> Unit = { l,fs -> }): Iterable = -+ flatMap { lookup -> -+ val files = lookupStorage.get(lookup).map(::File).filter(filesFilter) -+ if (files.any()) { -+ logAction(lookup, files) -+ } -+ files -+ } -+ -+ fun dirtyLookupSymbolsFromRemovedKotlinFiles(): List { -+ val removedKotlinFiles = removed.filter { it.isKotlinFile() } -+ return if (removedKotlinFiles.isNotEmpty()) -+ targets.flatMap { getIncrementalCache(it).classesBySources(removedKotlinFiles).map { LookupSymbol(it.fqNameForClassNameWithoutDollars.shortName().toString(), it.packageFqName.toString()) } } -+ else listOf() -+ } -+ -+ fun dirtyLookupSymbolsFromModifiedJavaFiles(): List { -+ val modifiedJavaFiles = modified.filter { it.isJavaFile() } -+ return (if (modifiedJavaFiles.any()) { -+ val rootDisposable = Disposer.newDisposable() -+ val configuration = CompilerConfiguration() -+ val environment = KotlinCoreEnvironment.createForProduction(rootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES) -+ val project = environment.project -+ val psiFileFactory = PsiFileFactory.getInstance(project) as PsiFileFactoryImpl -+ modifiedJavaFiles.flatMap { -+ val javaFile = psiFileFactory.createFileFromText(it.nameWithoutExtension, Language.findLanguageByID(""JAVA"")!!, it.readText()) -+ if (javaFile is PsiJavaFile) -+ javaFile.classes.flatMap { it.findLookupSymbols() } -+ else listOf() -+ } -+ } else listOf()) -+ } -+ -+ fun dirtyKotlinSourcesFromGradle(): List { -+ // TODO: handle classpath changes similarly - compare with cashed version (likely a big change, may be costly, some heuristics could be considered) -+ val modifiedKotlinFiles = modified.filter { it.isKotlinFile() } -+ val lookupSymbols = -+ dirtyLookupSymbolsFromModifiedJavaFiles() + -+ dirtyLookupSymbolsFromRemovedKotlinFiles() -+ // TODO: add dirty lookups from modified kotlin files to reduce number of steps needed -+ -+ if (lookupSymbols.any()) { -+ val kotlinModifiedFilesSet = modifiedKotlinFiles.toHashSet() -+ return modifiedKotlinFiles + -+ lookupSymbols.files( -+ filesFilter = { it !in kotlinModifiedFilesSet }, -+ logAction = { lookup, files -> -+ logger.kotlinInfo(""changes in ${lookup.name} (${lookup.scope}) causes recompilation of ${files.joinToString { projectRelativePath(it) }}"") -+ }) -+ } -+ return modifiedKotlinFiles -+ } -+ -+ fun isClassPathChanged(): Boolean { -+ // TODO: that doesn't look to wise - join it first and then split here, consider storing it somewhere in between -+ val classpath = args.classpath.split(File.pathSeparator).map { File(it) }.toHashSet() -+ val changedClasspath = modified.filter { classpath.contains(it) } -+ return changedClasspath.any() -+ } -+ -+ fun allCachesVersions() = allCachesVersions(cachesBaseDir, listOf(cachesBaseDir)) -+ -+ fun calculateSourcesToCompile(): Pair, Boolean> { -+ -+ if (!experimentalIncremental || -+ !isIncrementalRequested || -+ // TODO: more precise will be not to rebuild unconditionally on classpath changes, but retrieve lookup info and try to find out which sources are affected by cp changes -+ isClassPathChanged() || -+ // so far considering it not incremental TODO: store java files in the cache and extract removed symbols from it here -+ removed.any { it.isJavaFile() } -+ ) { -+ logger.kotlinInfo(if (!isIncrementalRequested) ""clean caches on rebuild"" else ""classpath changed, rebuilding all kotlin files"") -+ targets.forEach { getIncrementalCache(it).clean() } -+ lookupStorage.clean() -+ return Pair(sources, false) -+ } -+ val actions = if (isIncrementalRequested) allCachesVersions().map { it.checkVersion() } -+ else listOf(CacheVersion.Action.REBUILD_ALL_KOTLIN) -+ // TODO: find out whether these flags should be emulated too -+// val hasKotlin = HasKotlinMarker(dataManager) -+// val rebuildAfterCacheVersionChanged = RebuildAfterCacheVersionChangeMarker(dataManager) -+ -+ for (status in actions.distinct().sorted()) { -+ when (status) { -+ CacheVersion.Action.REBUILD_ALL_KOTLIN -> { -+ logger.kotlinInfo(""Kotlin global lookup map format changed, rebuilding all kotlin files"") -+ targets.forEach { getIncrementalCache(it).clean() } -+ lookupStorage.clean() -+ return Pair(sources, false) -+ } -+ CacheVersion.Action.REBUILD_CHUNK -> { -+ logger.kotlinInfo(""Clearing caches for "" + targets.joinToString { it.name }) -+ targets.forEach { getIncrementalCache(it).clean() } -+ } -+ CacheVersion.Action.CLEAN_NORMAL_CACHES -> { -+ logger.kotlinInfo(""Clearing caches for all targets"") -+ targets.forEach { getIncrementalCache(it).clean() } -+ } -+ CacheVersion.Action.CLEAN_EXPERIMENTAL_CACHES -> { -+ logger.kotlinInfo(""Clearing experimental caches for all targets"") -+ targets.forEach { getIncrementalCache(it).cleanExperimental() } -+ } -+ CacheVersion.Action.CLEAN_DATA_CONTAINER -> { -+ logger.kotlinInfo(""Clearing lookup cache"") -+ lookupStorage.clean() -+ dataContainerCacheVersion(cachesBaseDir).clean() -+ } -+ else -> { -+ assert(status == CacheVersion.Action.DO_NOTHING) { ""Unknown version status $status"" } -+ } -+ } -+ } -+ val dirtyFiles = dirtyKotlinSourcesFromGradle().distinct() -+ // first dirty files should be found and only then caches cleared -+ val removedKotlinFiles = removed.filter { it.isKotlinFile() } -+ targets.forEach { getIncrementalCache(it).let { -+ it.markOutputClassesDirty(removedKotlinFiles) -+ it.removeClassfilesBySources(removedKotlinFiles) -+ }} -+ return Pair(dirtyFiles, true) -+ } -+ -+ fun cleanupOnError() { -+ val outputDirFile = File(args.destination!!) -+ -+ assert(outputDirFile.exists()) -+ val generatedRelPaths = allGeneratedFiles.map { it.outputFile.toRelativeString(outputDirFile) } -+ logger.kotlinInfo(""deleting output on error: ${generatedRelPaths.joinToString()}"") -+ -+ allGeneratedFiles.forEach { it.outputFile.delete() } -+ generatedRelPaths.forEach { File(destinationDir, it).delete() } -+ } -+ -+ fun processCompilerExitCode(exitCode: ExitCode) { -+ if (exitCode != ExitCode.OK) { -+ cleanupOnError() -+ } -+ when (exitCode) { -+ ExitCode.COMPILATION_ERROR -> throw GradleException(""Compilation error. See log for more details"") -+ ExitCode.INTERNAL_ERROR -> throw GradleException(""Internal compiler error. See log for more details"") -+ ExitCode.SCRIPT_EXECUTION_ERROR -> throw GradleException(""Script execution error. See log for more details"") -+ ExitCode.OK -> logger.kotlinInfo(""Compilation succeeded"") -+ } -+ } -+ -+ fun outputRelativePath(f: File) = f.toRelativeString(outputDir) -+ -+ -+ if (!experimentalIncremental) { -+ anyClassesCompiled = true -+ processCompilerExitCode(compileNotIncremental(sources, outputDir, args)) -+ return -+ } -+ logger.warn(""Using experimental kotlin incremental compilation"") -+ -+ anyClassesCompiled = false -+ -+ // TODO: decide what to do if no files are considered dirty - rebuild or skip the module -+ var (sourcesToCompile, isIncrementalDecided) = calculateSourcesToCompile() -+ -+ if (isIncrementalDecided) { -+ // TODO: process as list here, merge into string later -+ args.classpath = args.classpath + File.pathSeparator + outputDir.absolutePath -+ } -+ -+ while (sourcesToCompile.any()) { -+ logger.kotlinInfo(""compile iteration: ${sourcesToCompile.joinToString{ projectRelativePath(it) }}"") -+ -+ val (exitCode, generatedFiles) = compileChanged(","What's the point in using named arguments here? -","this is not the right way to do it. these arguments are not the same as the `kotlin.extra.compilation` flag," -682,"@@ -163,16 +217,341 @@ public open class KotlinCompile() : AbstractKotlinCompile Int'"" ""false"" ++// ACTION: Disable 'Make Types Implicit In Lambda' ++// ACTION: Edit intention settings ++// ACTION: Make types implicit in lambda","Note that this test is now failing again due to obvious reasons :) +",Perhaps add a note here that types implicit in lambda +250,"@@ -1,6 +1,6 @@ + // !LANGUAGE: +AllowContractsForCustomFunctions +UseCallsInPlaceEffect +ReadDeserializedContracts + // !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts +-// IGNORE_BACKEND: JVM_IR, NATIVE, JS_IR",Could you also please unmute JS_IR tests? ,Was this intended to be committed with the other chan +251,"@@ -1,6 +1,7 @@ + // !LANGUAGE: +FunctionTypesWithBigArity","What happens to this test? +Do we not want to support this kind of code any more? +If so, the test should probably just be removed.",I do not think we should edit this file. +252,"@@ -1,6 +1,8 @@ + class A { + companion object { +- private var r: Int = 1; ++ private var r: Int = 1 ++ // Custom getter is needed, otherwise no need to generate getTest",I think this test is no longer necessary and can be safely deleted instead,"Not sure why this is needed. Custom getter is needed," +253,"@@ -1,7 +1,6 @@ + // Even before any IR lowerings, the type of `when` is determined to be + // Unit even though the outer `if` still returns `Int?`. This results + // in a ClassCastException when that Unit is converted into a Number. +-// IGNORE_BACKEND: JVM_IR",The comment above is probably also not needed after this change?,Are you sure this is safe to remove? The problem seem +254,"@@ -1,7 +1,6 @@ + fun foo() { +- val a: kotlin.test.Asserter? +- if () { +- a = null ++ val a = if () {","It's not OK that you're losing the variable type here. +","The `else` clause is unnecessary here, because you al" +255,"@@ -1,7 +1,7 @@ + fun foo() { +- Loop@ while (true) { ++ Loop@ loop@ while (true) {",If we already have a label let's not add another one,I don't understand this change. +256,"@@ -1,8 +1,8 @@ + class A +-fun box() { ++fun box(u: Int) {",and this?,what is this type annotation for? +257,"@@ -1,8 +1,9 @@ + object A { + @JvmStatic fun main(args: Array) { +- println(Void.TYPE) +- println(Integer.TYPE) +- println(java.lang.Double.TYPE) ++ println(Unit::class.javaPrimitiveType)","This doesn't actually work: `Unit` has no `javaPrimitiveType`. For `void.class`, the previous variant of the code should be used. +",I believe this line can be remove +258,"@@ -1,8 +1,9 @@ +-// IGNORE_BACKEND: JVM_IR + // IGNORE_BACKEND: JS_IR + // TODO: muted automatically, investigate should it be ran for JS or not + // IGNORE_BACKEND: JS, NATIVE + ++// FULL_JDK",Why FULL_JDK directive is required? Current backend works withoit it,This seems to be the only real ch +259,"@@ -10,6 +10,12 @@ class BasicAssertionsTest { } -+ override fun callCompiler(args: K2JVMCompilerArguments, sources: List, isIncrementalRequested: Boolean, modified: List, removed: List, cachesBaseDir: File) { -+ -+ if (experimentalIncremental) { -+ // TODO: consider other ways to pass incremental flag to compiler/builder -+ System.setProperty(""kotlin.incremental.compilation"", ""true"") -+ // TODO: experimental should be removed as soon as it becomes standard -+ System.setProperty(""kotlin.incremental.compilation.experimental"", ""true"") -+ } -+ -+ val targetType = ""java-production"" -+ val moduleName = args.moduleName -+ val targets = listOf(TargetId(moduleName, targetType)) -+ val outputDir = File(args.destination) -+ val caches = hashMapOf() -+ val lookupStorage = LookupStorage(File(cachesBaseDir, ""lookups"")) -+ val lookupTracker = LookupTrackerImpl(LookupTracker.DO_NOTHING) -+ var currentRemoved = removed -+ val allGeneratedFiles = hashSetOf>() -+ val compiledSourcesSet = hashSetOf() -+ -+ fun getOrCreateIncrementalCache(target: TargetId): GradleIncrementalCacheImpl { -+ val cacheDir = File(cachesBaseDir, ""increCache.${target.name}"") -+ cacheDir.mkdirs() -+ return GradleIncrementalCacheImpl(targetDataRoot = cacheDir, targetOutputDir = outputDir, target = target) -+ } -+ -+ fun getIncrementalCache(it: TargetId) = caches.getOrPut(it, { getOrCreateIncrementalCache(it) }) -+ -+ fun PsiClass.findLookupSymbols(): Iterable { -+ val fqn = qualifiedName.orEmpty() -+ return listOf(LookupSymbol(name.orEmpty(), if (fqn == name) """" else fqn.removeSuffix(""."" + name!!))) + -+ methods.map { LookupSymbol(it.name, fqn) } + -+ fields.map { LookupSymbol(it.name.orEmpty(), fqn) } + -+ innerClasses.flatMap { it.findLookupSymbols() } -+ } -+ -+ fun Iterable.files(filesFilter: (File) -> Boolean = { true }, logAction: (LookupSymbol, Iterable) -> Unit = { l,fs -> }): Iterable = -+ flatMap { lookup -> -+ val files = lookupStorage.get(lookup).map(::File).filter(filesFilter) -+ if (files.any()) { -+ logAction(lookup, files) -+ } -+ files -+ } -+ -+ fun dirtyLookupSymbolsFromRemovedKotlinFiles(): List { -+ val removedKotlinFiles = removed.filter { it.isKotlinFile() } -+ return if (removedKotlinFiles.isNotEmpty()) -+ targets.flatMap { getIncrementalCache(it).classesBySources(removedKotlinFiles).map { LookupSymbol(it.fqNameForClassNameWithoutDollars.shortName().toString(), it.packageFqName.toString()) } } -+ else listOf() -+ } -+ -+ fun dirtyLookupSymbolsFromModifiedJavaFiles(): List { -+ val modifiedJavaFiles = modified.filter { it.isJavaFile() } -+ return (if (modifiedJavaFiles.any()) { -+ val rootDisposable = Disposer.newDisposable() -+ val configuration = CompilerConfiguration() -+ val environment = KotlinCoreEnvironment.createForProduction(rootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES) -+ val project = environment.project -+ val psiFileFactory = PsiFileFactory.getInstance(project) as PsiFileFactoryImpl -+ modifiedJavaFiles.flatMap { -+ val javaFile = psiFileFactory.createFileFromText(it.nameWithoutExtension, Language.findLanguageByID(""JAVA"")!!, it.readText()) -+ if (javaFile is PsiJavaFile) -+ javaFile.classes.flatMap { it.findLookupSymbols() } -+ else listOf() -+ } -+ } else listOf()) -+ } -+ -+ fun dirtyKotlinSourcesFromGradle(): List { -+ // TODO: handle classpath changes similarly - compare with cashed version (likely a big change, may be costly, some heuristics could be considered) -+ val modifiedKotlinFiles = modified.filter { it.isKotlinFile() } -+ val lookupSymbols = -+ dirtyLookupSymbolsFromModifiedJavaFiles() + -+ dirtyLookupSymbolsFromRemovedKotlinFiles() -+ // TODO: add dirty lookups from modified kotlin files to reduce number of steps needed -+ -+ if (lookupSymbols.any()) { -+ val kotlinModifiedFilesSet = modifiedKotlinFiles.toHashSet() -+ return modifiedKotlinFiles + -+ lookupSymbols.files( -+ filesFilter = { it !in kotlinModifiedFilesSet }, -+ logAction = { lookup, files -> -+ logger.kotlinInfo(""changes in ${lookup.name} (${lookup.scope}) causes recompilation of ${files.joinToString { projectRelativePath(it) }}"") -+ }) -+ } -+ return modifiedKotlinFiles -+ } -+ -+ fun isClassPathChanged(): Boolean { -+ // TODO: that doesn't look to wise - join it first and then split here, consider storing it somewhere in between -+ val classpath = args.classpath.split(File.pathSeparator).map { File(it) }.toHashSet() -+ val changedClasspath = modified.filter { classpath.contains(it) } -+ return changedClasspath.any() -+ } -+ -+ fun allCachesVersions() = allCachesVersions(cachesBaseDir, listOf(cachesBaseDir)) -+ -+ fun calculateSourcesToCompile(): Pair, Boolean> { -+ -+ if (!experimentalIncremental || -+ !isIncrementalRequested || -+ // TODO: more precise will be not to rebuild unconditionally on classpath changes, but retrieve lookup info and try to find out which sources are affected by cp changes -+ isClassPathChanged() || -+ // so far considering it not incremental TODO: store java files in the cache and extract removed symbols from it here -+ removed.any { it.isJavaFile() } -+ ) { -+ logger.kotlinInfo(if (!isIncrementalRequested) ""clean caches on rebuild"" else ""classpath changed, rebuilding all kotlin files"") -+ targets.forEach { getIncrementalCache(it).clean() } -+ lookupStorage.clean() -+ return Pair(sources, false) -+ } -+ val actions = if (isIncrementalRequested) allCachesVersions().map { it.checkVersion() } -+ else listOf(CacheVersion.Action.REBUILD_ALL_KOTLIN) -+ // TODO: find out whether these flags should be emulated too -+// val hasKotlin = HasKotlinMarker(dataManager) -+// val rebuildAfterCacheVersionChanged = RebuildAfterCacheVersionChangeMarker(dataManager) -+ -+ for (status in actions.distinct().sorted()) { -+ when (status) { -+ CacheVersion.Action.REBUILD_ALL_KOTLIN -> { -+ logger.kotlinInfo(""Kotlin global lookup map format changed, rebuilding all kotlin files"") -+ targets.forEach { getIncrementalCache(it).clean() } -+ lookupStorage.clean() -+ return Pair(sources, false) -+ } -+ CacheVersion.Action.REBUILD_CHUNK -> { -+ logger.kotlinInfo(""Clearing caches for "" + targets.joinToString { it.name }) -+ targets.forEach { getIncrementalCache(it).clean() } -+ } -+ CacheVersion.Action.CLEAN_NORMAL_CACHES -> { -+ logger.kotlinInfo(""Clearing caches for all targets"") -+ targets.forEach { getIncrementalCache(it).clean() } -+ } -+ CacheVersion.Action.CLEAN_EXPERIMENTAL_CACHES -> { -+ logger.kotlinInfo(""Clearing experimental caches for all targets"") -+ targets.forEach { getIncrementalCache(it).cleanExperimental() } -+ } -+ CacheVersion.Action.CLEAN_DATA_CONTAINER -> { -+ logger.kotlinInfo(""Clearing lookup cache"") -+ lookupStorage.clean() -+ dataContainerCacheVersion(cachesBaseDir).clean() -+ } -+ else -> { -+ assert(status == CacheVersion.Action.DO_NOTHING) { ""Unknown version status $status"" } -+ } -+ } -+ } -+ val dirtyFiles = dirtyKotlinSourcesFromGradle().distinct() -+ // first dirty files should be found and only then caches cleared -+ val removedKotlinFiles = removed.filter { it.isKotlinFile() } -+ targets.forEach { getIncrementalCache(it).let { -+ it.markOutputClassesDirty(removedKotlinFiles) -+ it.removeClassfilesBySources(removedKotlinFiles) -+ }} -+ return Pair(dirtyFiles, true) -+ } -+ -+ fun cleanupOnError() { -+ val outputDirFile = File(args.destination!!) -+ -+ assert(outputDirFile.exists()) -+ val generatedRelPaths = allGeneratedFiles.map { it.outputFile.toRelativeString(outputDirFile) } -+ logger.kotlinInfo(""deleting output on error: ${generatedRelPaths.joinToString()}"") -+ -+ allGeneratedFiles.forEach { it.outputFile.delete() } -+ generatedRelPaths.forEach { File(destinationDir, it).delete() } -+ } -+ -+ fun processCompilerExitCode(exitCode: ExitCode) { -+ if (exitCode != ExitCode.OK) { -+ cleanupOnError() -+ } -+ when (exitCode) { -+ ExitCode.COMPILATION_ERROR -> throw GradleException(""Compilation error. See log for more details"") -+ ExitCode.INTERNAL_ERROR -> throw GradleException(""Internal compiler error. See log for more details"") -+ ExitCode.SCRIPT_EXECUTION_ERROR -> throw GradleException(""Script execution error. See log for more details"") -+ ExitCode.OK -> logger.kotlinInfo(""Compilation succeeded"") -+ } -+ } -+ -+ fun outputRelativePath(f: File) = f.toRelativeString(outputDir) -+ -+ -+ if (!experimentalIncremental) { -+ anyClassesCompiled = true -+ processCompilerExitCode(compileNotIncremental(sources, outputDir, args)) -+ return -+ } -+ logger.warn(""Using experimental kotlin incremental compilation"") -+ -+ anyClassesCompiled = false -+ -+ // TODO: decide what to do if no files are considered dirty - rebuild or skip the module -+ var (sourcesToCompile, isIncrementalDecided) = calculateSourcesToCompile() -+ -+ if (isIncrementalDecided) { -+ // TODO: process as list here, merge into string later -+ args.classpath = args.classpath + File.pathSeparator + outputDir.absolutePath -+ } -+ -+ while (sourcesToCompile.any()) { -+ logger.kotlinInfo(""compile iteration: ${sourcesToCompile.joinToString{ projectRelativePath(it) }}"") -+ -+ val (exitCode, generatedFiles) = compileChanged( -+ targets = targets, -+ sourcesToCompile = sourcesToCompile, -+ outputDir = outputDir, -+ args = args, -+ getIncrementalCache = ::getIncrementalCache, -+ lookupTracker = lookupTracker) -+ -+ allGeneratedFiles.addAll(generatedFiles) -+ // save versions? -+ -+ val changes = updateIncrementalCaches( -+ targets = targets, -+ generatedFiles = generatedFiles, -+ compiledWithErrors = exitCode != ExitCode.OK, -+ getIncrementalCache = { caches[it]!! }) -+ -+// lookupTracker.lookups.entrySet().forEach { -+// logger.kotlinDebug(""lookups to ${it.key.name}:${it.key.scope} from ${it.value.joinToString { projectRelativePath(it) }}"") -+// } -+ -+ lookupStorage.update(lookupTracker, sourcesToCompile, currentRemoved) -+ -+ allCachesVersions().forEach { it.saveIfNeeded() }","I believe saving versions should be after the loop. -","this is not the right way to do it. these arguments are not the same as the `kotlin.extra.compilation` flag," -683,"@@ -163,16 +217,341 @@ public open class KotlinCompile() : AbstractKotlinCompile Unit): String = StringBuilder().apply(builderAction).toString() -+ override fun callCompiler(args: K2JVMCompilerArguments, sources: List, isIncrementalRequested: Boolean, modified: List, removed: List, cachesBaseDir: File) { -+ -+ if (experimentalIncremental) { -+ // TODO: consider other ways to pass incremental flag to compiler/builder -+ System.setProperty(""kotlin.incremental.compilation"", ""true"") -+ // TODO: experimental should be removed as soon as it becomes standard -+ System.setProperty(""kotlin.incremental.compilation.experimental"", ""true"") -+ } -+ -+ val targetType = ""java-production"" -+ val moduleName = args.moduleName -+ val targets = listOf(TargetId(moduleName, targetType)) -+ val outputDir = File(args.destination) -+ val caches = hashMapOf() -+ val lookupStorage = LookupStorage(File(cachesBaseDir, ""lookups"")) -+ val lookupTracker = LookupTrackerImpl(LookupTracker.DO_NOTHING) -+ var currentRemoved = removed -+ val allGeneratedFiles = hashSetOf>() -+ val compiledSourcesSet = hashSetOf() -+ -+ fun getOrCreateIncrementalCache(target: TargetId): GradleIncrementalCacheImpl { -+ val cacheDir = File(cachesBaseDir, ""increCache.${target.name}"") -+ cacheDir.mkdirs() -+ return GradleIncrementalCacheImpl(targetDataRoot = cacheDir, targetOutputDir = outputDir, target = target) -+ } -+ -+ fun getIncrementalCache(it: TargetId) = caches.getOrPut(it, { getOrCreateIncrementalCache(it) }) -+ -+ fun PsiClass.findLookupSymbols(): Iterable { -+ val fqn = qualifiedName.orEmpty() -+ return listOf(LookupSymbol(name.orEmpty(), if (fqn == name) """" else fqn.removeSuffix(""."" + name!!))) + -+ methods.map { LookupSymbol(it.name, fqn) } + -+ fields.map { LookupSymbol(it.name.orEmpty(), fqn) } + -+ innerClasses.flatMap { it.findLookupSymbols() } -+ } -+ -+ fun Iterable.files(filesFilter: (File) -> Boolean = { true }, logAction: (LookupSymbol, Iterable) -> Unit = { l,fs -> }): Iterable = -+ flatMap { lookup -> -+ val files = lookupStorage.get(lookup).map(::File).filter(filesFilter) -+ if (files.any()) { -+ logAction(lookup, files) -+ } -+ files -+ } -+ -+ fun dirtyLookupSymbolsFromRemovedKotlinFiles(): List { -+ val removedKotlinFiles = removed.filter { it.isKotlinFile() } -+ return if (removedKotlinFiles.isNotEmpty()) -+ targets.flatMap { getIncrementalCache(it).classesBySources(removedKotlinFiles).map { LookupSymbol(it.fqNameForClassNameWithoutDollars.shortName().toString(), it.packageFqName.toString()) } } -+ else listOf() -+ } -+ -+ fun dirtyLookupSymbolsFromModifiedJavaFiles(): List { -+ val modifiedJavaFiles = modified.filter { it.isJavaFile() } -+ return (if (modifiedJavaFiles.any()) { -+ val rootDisposable = Disposer.newDisposable() -+ val configuration = CompilerConfiguration() -+ val environment = KotlinCoreEnvironment.createForProduction(rootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES) -+ val project = environment.project -+ val psiFileFactory = PsiFileFactory.getInstance(project) as PsiFileFactoryImpl -+ modifiedJavaFiles.flatMap { -+ val javaFile = psiFileFactory.createFileFromText(it.nameWithoutExtension, Language.findLanguageByID(""JAVA"")!!, it.readText()) -+ if (javaFile is PsiJavaFile) -+ javaFile.classes.flatMap { it.findLookupSymbols() } -+ else listOf() -+ } -+ } else listOf()) -+ } -+ -+ fun dirtyKotlinSourcesFromGradle(): List { -+ // TODO: handle classpath changes similarly - compare with cashed version (likely a big change, may be costly, some heuristics could be considered) -+ val modifiedKotlinFiles = modified.filter { it.isKotlinFile() } -+ val lookupSymbols = -+ dirtyLookupSymbolsFromModifiedJavaFiles() + -+ dirtyLookupSymbolsFromRemovedKotlinFiles() -+ // TODO: add dirty lookups from modified kotlin files to reduce number of steps needed -+ -+ if (lookupSymbols.any()) { -+ val kotlinModifiedFilesSet = modifiedKotlinFiles.toHashSet() -+ return modifiedKotlinFiles + -+ lookupSymbols.files( -+ filesFilter = { it !in kotlinModifiedFilesSet }, -+ logAction = { lookup, files -> -+ logger.kotlinInfo(""changes in ${lookup.name} (${lookup.scope}) causes recompilation of ${files.joinToString { projectRelativePath(it) }}"") -+ }) -+ } -+ return modifiedKotlinFiles -+ } -+ -+ fun isClassPathChanged(): Boolean { -+ // TODO: that doesn't look to wise - join it first and then split here, consider storing it somewhere in between -+ val classpath = args.classpath.split(File.pathSeparator).map { File(it) }.toHashSet() -+ val changedClasspath = modified.filter { classpath.contains(it) } -+ return changedClasspath.any() -+ } -+ -+ fun allCachesVersions() = allCachesVersions(cachesBaseDir, listOf(cachesBaseDir)) -+ -+ fun calculateSourcesToCompile(): Pair, Boolean> { -+ -+ if (!experimentalIncremental || -+ !isIncrementalRequested || -+ // TODO: more precise will be not to rebuild unconditionally on classpath changes, but retrieve lookup info and try to find out which sources are affected by cp changes -+ isClassPathChanged() || -+ // so far considering it not incremental TODO: store java files in the cache and extract removed symbols from it here -+ removed.any { it.isJavaFile() } -+ ) { -+ logger.kotlinInfo(if (!isIncrementalRequested) ""clean caches on rebuild"" else ""classpath changed, rebuilding all kotlin files"") -+ targets.forEach { getIncrementalCache(it).clean() } -+ lookupStorage.clean() -+ return Pair(sources, false) -+ } -+ val actions = if (isIncrementalRequested) allCachesVersions().map { it.checkVersion() } -+ else listOf(CacheVersion.Action.REBUILD_ALL_KOTLIN) -+ // TODO: find out whether these flags should be emulated too -+// val hasKotlin = HasKotlinMarker(dataManager) -+// val rebuildAfterCacheVersionChanged = RebuildAfterCacheVersionChangeMarker(dataManager) -+ -+ for (status in actions.distinct().sorted()) { -+ when (status) { -+ CacheVersion.Action.REBUILD_ALL_KOTLIN -> { -+ logger.kotlinInfo(""Kotlin global lookup map format changed, rebuilding all kotlin files"") -+ targets.forEach { getIncrementalCache(it).clean() } -+ lookupStorage.clean() -+ return Pair(sources, false) -+ } -+ CacheVersion.Action.REBUILD_CHUNK -> { -+ logger.kotlinInfo(""Clearing caches for "" + targets.joinToString { it.name }) -+ targets.forEach { getIncrementalCache(it).clean() } -+ } -+ CacheVersion.Action.CLEAN_NORMAL_CACHES -> { -+ logger.kotlinInfo(""Clearing caches for all targets"") -+ targets.forEach { getIncrementalCache(it).clean() } -+ } -+ CacheVersion.Action.CLEAN_EXPERIMENTAL_CACHES -> { -+ logger.kotlinInfo(""Clearing experimental caches for all targets"") -+ targets.forEach { getIncrementalCache(it).cleanExperimental() } -+ } -+ CacheVersion.Action.CLEAN_DATA_CONTAINER -> { -+ logger.kotlinInfo(""Clearing lookup cache"") -+ lookupStorage.clean() -+ dataContainerCacheVersion(cachesBaseDir).clean() -+ } -+ else -> { -+ assert(status == CacheVersion.Action.DO_NOTHING) { ""Unknown version status $status"" } -+ } -+ } -+ } -+ val dirtyFiles = dirtyKotlinSourcesFromGradle().distinct() -+ // first dirty files should be found and only then caches cleared -+ val removedKotlinFiles = removed.filter { it.isKotlinFile() } -+ targets.forEach { getIncrementalCache(it).let { -+ it.markOutputClassesDirty(removedKotlinFiles) -+ it.removeClassfilesBySources(removedKotlinFiles) -+ }} -+ return Pair(dirtyFiles, true) -+ } -+ -+ fun cleanupOnError() { -+ val outputDirFile = File(args.destination!!) -+ -+ assert(outputDirFile.exists()) -+ val generatedRelPaths = allGeneratedFiles.map { it.outputFile.toRelativeString(outputDirFile) } -+ logger.kotlinInfo(""deleting output on error: ${generatedRelPaths.joinToString()}"") -+ -+ allGeneratedFiles.forEach { it.outputFile.delete() } -+ generatedRelPaths.forEach { File(destinationDir, it).delete() } -+ } -+ -+ fun processCompilerExitCode(exitCode: ExitCode) { -+ if (exitCode != ExitCode.OK) { -+ cleanupOnError() -+ } -+ when (exitCode) { -+ ExitCode.COMPILATION_ERROR -> throw GradleException(""Compilation error. See log for more details"") -+ ExitCode.INTERNAL_ERROR -> throw GradleException(""Internal compiler error. See log for more details"") -+ ExitCode.SCRIPT_EXECUTION_ERROR -> throw GradleException(""Script execution error. See log for more details"") -+ ExitCode.OK -> logger.kotlinInfo(""Compilation succeeded"") -+ } -+ } -+ -+ fun outputRelativePath(f: File) = f.toRelativeString(outputDir) -+ -+ -+ if (!experimentalIncremental) { -+ anyClassesCompiled = true -+ processCompilerExitCode(compileNotIncremental(sources, outputDir, args)) -+ return -+ } -+ logger.warn(""Using experimental kotlin incremental compilation"") -+ -+ anyClassesCompiled = false -+ -+ // TODO: decide what to do if no files are considered dirty - rebuild or skip the module -+ var (sourcesToCompile, isIncrementalDecided) = calculateSourcesToCompile() -+ -+ if (isIncrementalDecided) { -+ // TODO: process as list here, merge into string later -+ args.classpath = args.classpath + File.pathSeparator + outputDir.absolutePath -+ } -+ -+ while (sourcesToCompile.any()) { -+ logger.kotlinInfo(""compile iteration: ${sourcesToCompile.joinToString{ projectRelativePath(it) }}"") -+ -+ val (exitCode, generatedFiles) = compileChanged( -+ targets = targets, -+ sourcesToCompile = sourcesToCompile, -+ outputDir = outputDir, -+ args = args, -+ getIncrementalCache = ::getIncrementalCache, -+ lookupTracker = lookupTracker) -+ -+ allGeneratedFiles.addAll(generatedFiles) -+ // save versions? -+ -+ val changes = updateIncrementalCaches( -+ targets = targets, -+ generatedFiles = generatedFiles, -+ compiledWithErrors = exitCode != ExitCode.OK, -+ getIncrementalCache = { caches[it]!! }) -+ -+// lookupTracker.lookups.entrySet().forEach { -+// logger.kotlinDebug(""lookups to ${it.key.name}:${it.key.scope} from ${it.value.joinToString { projectRelativePath(it) }}"") -+// } -+ -+ lookupStorage.update(lookupTracker, sourcesToCompile, currentRemoved) -+ -+ allCachesVersions().forEach { it.saveIfNeeded() } -+ -+ processCompilerExitCode(exitCode) -+ -+ if (!isIncrementalDecided) break; -+ -+// logger.kotlinDebug(""generated ${generatedFiles.joinToString { outputRelativePath(it.outputFile) }}"") -+// logger.kotlinDebug(""changes: ${changes.changes.joinToString { ""${it.fqName}: ${it.javaClass.simpleName}"" }}"") -+// -+// logger.kotlinLazyDebug({ -+// ""known lookups:\n${lookupStorage.dump(changes.changes.flatMap { -+// change -> -+// if (change is ChangeInfo.MembersChanged) -+// change.names.asSequence().map { LookupSymbol(it, change.fqName.asString()) } -+// else -+// sequenceOf() -+// }.toSet(), project.projectDir)}"" }) -+ -+ compiledSourcesSet.addAll(sourcesToCompile) -+ -+ val dirtyLookups = changes.dirtyLookups(caches.values.asSequence()) -+ -+// logger.kotlinDebug(""dirty lookups: ${dirtyLookups.joinToString { ""${it.name}:${it.scope}"" }}"") -+ -+ val dirty = dirtyLookups.files( -+ filesFilter = { it !in compiledSourcesSet }, -+ logAction = { lookup, files -> -+ logger.kotlinInfo(""changes in ${lookup.name} (${lookup.scope}) causes recompilation of ${files.joinToString { projectRelativePath(it) }}"") -+ }) -+ sourcesToCompile = dirty.filter { it in sources }.toList()","Minor: `filter` returns list -","this is not the right way to do it. these arguments are not the same as the `kotlin.extra.compilation` flag," -684,"@@ -163,16 +217,341 @@ public open class KotlinCompile() : AbstractKotlinCompile Unit): Long { ++ contract {",I believe this requires `kotlin.contracts.*` import.,Wouldn't be good to have an expli +263,"@@ -100,10 +101,10 @@ open class ConstraintSystemBuilderImpl(private val mode: Mode = ConstraintSystem + } + + for ((_, typeVariable) in typeParameters.zip(typeVariables)) {",nit: `for (typeVariable in typeVariables)`,Could you please update the docst +264,"@@ -100,10 +101,10 @@ open class ConstraintSystemBuilderImpl(private val mode: Mode = ConstraintSystem + } + + for ((_, typeVariable) in typeParameters.zip(typeVariables)) { +- allTypeParameterBounds.put(typeVariable, TypeBoundsImpl(typeVariable)) ++ allTypeParameterBounds[typeVariable] = TypeBoundsImpl(typeVariable) + } + +- for ((typeVariable, _) in allTypeParameterBounds) { ++ for (typeVariable in allTypeParameterBounds.keys) {",nit: `for (typeVariable in typeVariables)`. Probably combine with the above.,It looks like this change (and th +265,"@@ -101,7 +106,29 @@ class KotlinUFunctionCallExpression( } -+ override fun callCompiler(args: K2JVMCompilerArguments, sources: List, isIncrementalRequested: Boolean, modified: List, removed: List, cachesBaseDir: File) { -+ -+ if (experimentalIncremental) { -+ // TODO: consider other ways to pass incremental flag to compiler/builder -+ System.setProperty(""kotlin.incremental.compilation"", ""true"") -+ // TODO: experimental should be removed as soon as it becomes standard -+ System.setProperty(""kotlin.incremental.compilation.experimental"", ""true"") -+ } -+ -+ val targetType = ""java-production"" -+ val moduleName = args.moduleName -+ val targets = listOf(TargetId(moduleName, targetType)) -+ val outputDir = File(args.destination) -+ val caches = hashMapOf() -+ val lookupStorage = LookupStorage(File(cachesBaseDir, ""lookups"")) -+ val lookupTracker = LookupTrackerImpl(LookupTracker.DO_NOTHING) -+ var currentRemoved = removed -+ val allGeneratedFiles = hashSetOf>() -+ val compiledSourcesSet = hashSetOf() -+ -+ fun getOrCreateIncrementalCache(target: TargetId): GradleIncrementalCacheImpl { -+ val cacheDir = File(cachesBaseDir, ""increCache.${target.name}"") -+ cacheDir.mkdirs() -+ return GradleIncrementalCacheImpl(targetDataRoot = cacheDir, targetOutputDir = outputDir, target = target) -+ } -+ -+ fun getIncrementalCache(it: TargetId) = caches.getOrPut(it, { getOrCreateIncrementalCache(it) }) -+ -+ fun PsiClass.findLookupSymbols(): Iterable { -+ val fqn = qualifiedName.orEmpty() -+ return listOf(LookupSymbol(name.orEmpty(), if (fqn == name) """" else fqn.removeSuffix(""."" + name!!))) + -+ methods.map { LookupSymbol(it.name, fqn) } + -+ fields.map { LookupSymbol(it.name.orEmpty(), fqn) } + -+ innerClasses.flatMap { it.findLookupSymbols() } -+ } -+ -+ fun Iterable.files(filesFilter: (File) -> Boolean = { true }, logAction: (LookupSymbol, Iterable) -> Unit = { l,fs -> }): Iterable = -+ flatMap { lookup -> -+ val files = lookupStorage.get(lookup).map(::File).filter(filesFilter) -+ if (files.any()) { -+ logAction(lookup, files) -+ } -+ files -+ } -+ -+ fun dirtyLookupSymbolsFromRemovedKotlinFiles(): List { -+ val removedKotlinFiles = removed.filter { it.isKotlinFile() } -+ return if (removedKotlinFiles.isNotEmpty()) -+ targets.flatMap { getIncrementalCache(it).classesBySources(removedKotlinFiles).map { LookupSymbol(it.fqNameForClassNameWithoutDollars.shortName().toString(), it.packageFqName.toString()) } } -+ else listOf() -+ } -+ -+ fun dirtyLookupSymbolsFromModifiedJavaFiles(): List { -+ val modifiedJavaFiles = modified.filter { it.isJavaFile() } -+ return (if (modifiedJavaFiles.any()) { -+ val rootDisposable = Disposer.newDisposable() -+ val configuration = CompilerConfiguration() -+ val environment = KotlinCoreEnvironment.createForProduction(rootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES) -+ val project = environment.project -+ val psiFileFactory = PsiFileFactory.getInstance(project) as PsiFileFactoryImpl -+ modifiedJavaFiles.flatMap { -+ val javaFile = psiFileFactory.createFileFromText(it.nameWithoutExtension, Language.findLanguageByID(""JAVA"")!!, it.readText()) -+ if (javaFile is PsiJavaFile) -+ javaFile.classes.flatMap { it.findLookupSymbols() } -+ else listOf() -+ } -+ } else listOf()) -+ } -+ -+ fun dirtyKotlinSourcesFromGradle(): List { -+ // TODO: handle classpath changes similarly - compare with cashed version (likely a big change, may be costly, some heuristics could be considered) -+ val modifiedKotlinFiles = modified.filter { it.isKotlinFile() } -+ val lookupSymbols = -+ dirtyLookupSymbolsFromModifiedJavaFiles() + -+ dirtyLookupSymbolsFromRemovedKotlinFiles() -+ // TODO: add dirty lookups from modified kotlin files to reduce number of steps needed -+ -+ if (lookupSymbols.any()) { -+ val kotlinModifiedFilesSet = modifiedKotlinFiles.toHashSet() -+ return modifiedKotlinFiles + -+ lookupSymbols.files( -+ filesFilter = { it !in kotlinModifiedFilesSet }, -+ logAction = { lookup, files -> -+ logger.kotlinInfo(""changes in ${lookup.name} (${lookup.scope}) causes recompilation of ${files.joinToString { projectRelativePath(it) }}"") -+ }) -+ } -+ return modifiedKotlinFiles -+ } -+ -+ fun isClassPathChanged(): Boolean { -+ // TODO: that doesn't look to wise - join it first and then split here, consider storing it somewhere in between -+ val classpath = args.classpath.split(File.pathSeparator).map { File(it) }.toHashSet() -+ val changedClasspath = modified.filter { classpath.contains(it) } -+ return changedClasspath.any() -+ } -+ -+ fun allCachesVersions() = allCachesVersions(cachesBaseDir, listOf(cachesBaseDir)) -+ -+ fun calculateSourcesToCompile(): Pair, Boolean> { -+ -+ if (!experimentalIncremental || -+ !isIncrementalRequested || -+ // TODO: more precise will be not to rebuild unconditionally on classpath changes, but retrieve lookup info and try to find out which sources are affected by cp changes -+ isClassPathChanged() || -+ // so far considering it not incremental TODO: store java files in the cache and extract removed symbols from it here -+ removed.any { it.isJavaFile() } -+ ) { -+ logger.kotlinInfo(if (!isIncrementalRequested) ""clean caches on rebuild"" else ""classpath changed, rebuilding all kotlin files"") -+ targets.forEach { getIncrementalCache(it).clean() } -+ lookupStorage.clean() -+ return Pair(sources, false) -+ } -+ val actions = if (isIncrementalRequested) allCachesVersions().map { it.checkVersion() } -+ else listOf(CacheVersion.Action.REBUILD_ALL_KOTLIN) -+ // TODO: find out whether these flags should be emulated too -+// val hasKotlin = HasKotlinMarker(dataManager) -+// val rebuildAfterCacheVersionChanged = RebuildAfterCacheVersionChangeMarker(dataManager) -+ -+ for (status in actions.distinct().sorted()) { -+ when (status) { -+ CacheVersion.Action.REBUILD_ALL_KOTLIN -> { -+ logger.kotlinInfo(""Kotlin global lookup map format changed, rebuilding all kotlin files"") -+ targets.forEach { getIncrementalCache(it).clean() } -+ lookupStorage.clean() -+ return Pair(sources, false) -+ } -+ CacheVersion.Action.REBUILD_CHUNK -> { -+ logger.kotlinInfo(""Clearing caches for "" + targets.joinToString { it.name }) -+ targets.forEach { getIncrementalCache(it).clean() } -+ } -+ CacheVersion.Action.CLEAN_NORMAL_CACHES -> { -+ logger.kotlinInfo(""Clearing caches for all targets"") -+ targets.forEach { getIncrementalCache(it).clean() } -+ } -+ CacheVersion.Action.CLEAN_EXPERIMENTAL_CACHES -> { -+ logger.kotlinInfo(""Clearing experimental caches for all targets"") -+ targets.forEach { getIncrementalCache(it).cleanExperimental() } -+ } -+ CacheVersion.Action.CLEAN_DATA_CONTAINER -> { -+ logger.kotlinInfo(""Clearing lookup cache"") -+ lookupStorage.clean() -+ dataContainerCacheVersion(cachesBaseDir).clean() -+ } -+ else -> { -+ assert(status == CacheVersion.Action.DO_NOTHING) { ""Unknown version status $status"" } -+ } -+ } -+ } -+ val dirtyFiles = dirtyKotlinSourcesFromGradle().distinct() -+ // first dirty files should be found and only then caches cleared -+ val removedKotlinFiles = removed.filter { it.isKotlinFile() } -+ targets.forEach { getIncrementalCache(it).let { -+ it.markOutputClassesDirty(removedKotlinFiles) -+ it.removeClassfilesBySources(removedKotlinFiles) -+ }} -+ return Pair(dirtyFiles, true) -+ } -+ -+ fun cleanupOnError() { -+ val outputDirFile = File(args.destination!!) -+ -+ assert(outputDirFile.exists()) -+ val generatedRelPaths = allGeneratedFiles.map { it.outputFile.toRelativeString(outputDirFile) } -+ logger.kotlinInfo(""deleting output on error: ${generatedRelPaths.joinToString()}"") -+ -+ allGeneratedFiles.forEach { it.outputFile.delete() } -+ generatedRelPaths.forEach { File(destinationDir, it).delete() } -+ } -+ -+ fun processCompilerExitCode(exitCode: ExitCode) { -+ if (exitCode != ExitCode.OK) { -+ cleanupOnError() -+ } -+ when (exitCode) { -+ ExitCode.COMPILATION_ERROR -> throw GradleException(""Compilation error. See log for more details"") -+ ExitCode.INTERNAL_ERROR -> throw GradleException(""Internal compiler error. See log for more details"") -+ ExitCode.SCRIPT_EXECUTION_ERROR -> throw GradleException(""Script execution error. See log for more details"") -+ ExitCode.OK -> logger.kotlinInfo(""Compilation succeeded"") -+ } -+ } -+ -+ fun outputRelativePath(f: File) = f.toRelativeString(outputDir) -+ -+ -+ if (!experimentalIncremental) { -+ anyClassesCompiled = true -+ processCompilerExitCode(compileNotIncremental(sources, outputDir, args)) -+ return -+ } -+ logger.warn(""Using experimental kotlin incremental compilation"") -+ -+ anyClassesCompiled = false -+ -+ // TODO: decide what to do if no files are considered dirty - rebuild or skip the module -+ var (sourcesToCompile, isIncrementalDecided) = calculateSourcesToCompile() -+ -+ if (isIncrementalDecided) { -+ // TODO: process as list here, merge into string later -+ args.classpath = args.classpath + File.pathSeparator + outputDir.absolutePath -+ } -+ -+ while (sourcesToCompile.any()) { -+ logger.kotlinInfo(""compile iteration: ${sourcesToCompile.joinToString{ projectRelativePath(it) }}"") -+ -+ val (exitCode, generatedFiles) = compileChanged( -+ targets = targets, -+ sourcesToCompile = sourcesToCompile, -+ outputDir = outputDir, -+ args = args, -+ getIncrementalCache = ::getIncrementalCache, -+ lookupTracker = lookupTracker) -+ -+ allGeneratedFiles.addAll(generatedFiles) -+ // save versions? -+ -+ val changes = updateIncrementalCaches( -+ targets = targets, -+ generatedFiles = generatedFiles, -+ compiledWithErrors = exitCode != ExitCode.OK, -+ getIncrementalCache = { caches[it]!! }) -+ -+// lookupTracker.lookups.entrySet().forEach { -+// logger.kotlinDebug(""lookups to ${it.key.name}:${it.key.scope} from ${it.value.joinToString { projectRelativePath(it) }}"") -+// } -+ -+ lookupStorage.update(lookupTracker, sourcesToCompile, currentRemoved) -+ -+ allCachesVersions().forEach { it.saveIfNeeded() } -+ -+ processCompilerExitCode(exitCode) -+ -+ if (!isIncrementalDecided) break; -+ -+// logger.kotlinDebug(""generated ${generatedFiles.joinToString { outputRelativePath(it.outputFile) }}"") -+// logger.kotlinDebug(""changes: ${changes.changes.joinToString { ""${it.fqName}: ${it.javaClass.simpleName}"" }}"") -+// -+// logger.kotlinLazyDebug({ -+// ""known lookups:\n${lookupStorage.dump(changes.changes.flatMap { -+// change -> -+// if (change is ChangeInfo.MembersChanged) -+// change.names.asSequence().map { LookupSymbol(it, change.fqName.asString()) } -+// else -+// sequenceOf() -+// }.toSet(), project.projectDir)}"" }) -+ -+ compiledSourcesSet.addAll(sourcesToCompile) -+ -+ val dirtyLookups = changes.dirtyLookups(caches.values.asSequence()) -+ -+// logger.kotlinDebug(""dirty lookups: ${dirtyLookups.joinToString { ""${it.name}:${it.scope}"" }}"") -+ -+ val dirty = dirtyLookups.files( -+ filesFilter = { it !in compiledSourcesSet }, -+ logAction = { lookup, files -> -+ logger.kotlinInfo(""changes in ${lookup.name} (${lookup.scope}) causes recompilation of ${files.joinToString { projectRelativePath(it) }}"") -+ }) -+ sourcesToCompile = dirty.filter { it in sources }.toList() -+ if (currentRemoved.any()) { -+ currentRemoved = listOf() -+ } -+// logger.kotlinDebug(""dirty: ${dirty.joinToString { projectRelativePath(it) }}"") -+// logger.kotlinDebug(""to compile: ${sourcesToCompile.joinToString { projectRelativePath(it) }}"") -+ } -+ lookupStorage.flush(false) -+ lookupStorage.close() -+ caches.values.forEach { it.flush(false); it.close() } -+ if (allGeneratedFiles.isNotEmpty()) { -+ anyClassesCompiled = true -+ } -+ } -+ -+ private data class CompileChangedResults(val exitCode: ExitCode, val generatedFiles: List>) -+ -+ private fun compileChanged(targets: List, -+ sourcesToCompile: List, -+ outputDir: File, -+ args: K2JVMCompilerArguments, -+ getIncrementalCache: (TargetId) -> GradleIncrementalCacheImpl, -+ lookupTracker: LookupTracker) -+ : CompileChangedResults","Minor: formatting -","this is not the right way to do it. these arguments are not the same as the `kotlin.extra.compilation` flag," -685,"@@ -163,16 +217,341 @@ public open class KotlinCompile() : AbstractKotlinCompile 0 && inductionVar <= last) || (step < 0 || last <= inductionVar) + val stepKotlinType = progressionType.stepType(builtIns).toKotlinType() +- val zero = if (progressionType == ProgressionType.LONG_PROGRESSION) irLong(0) else irInt(0) ++ val isLong = progressionType == ProgressionType.LONG_PROGRESSION;",Semicolon may be considered a nostalgic reminiscence here.,Don't use `if` without curly brac +267,"@@ -102,6 +101,22 @@ class JvmBuiltinOptimizationLowering(val context: JvmBackendContext) : FileLower + expression.branches.removeIf() { + it.condition.isFalseConst() && isCompilerGenerated + } ++ if (expression.origin == IrStatementOrigin.ANDAND) { ++ assert(expression.type.isBoolean()","Please always add messages with additional information to asserts, including a description of what's wrong and any relevant variables (e.g. `expression.dump()` here)",Shouldn't this be `IrStatementOri +268,"@@ -102,6 +102,20 @@ class JvmBuiltinOptimizationLowering(val context: JvmBackendContext) : FileLower + expression.branches.removeIf() { + it.condition.isFalseConst() && isCompilerGenerated + } ++ // Replace conjunction condition with intrinsic and function call ++ if (expression.type.isBoolean() && expression.branches.size == 2) {",@neetopia Please add '// a && b == if (a) b else false' clarification comment,Nit: simplify to `if (expression. +269,"@@ -102,6 +103,7 @@ class ReplaceSingleLineLetIntention : SelfTargetingOffsetIndependentIntention right.text != parameterName + is KtDotQualifiedExpression -> !right.hasLambdaExpression() && !right.nameUsed(parameterName) ++ is KtBinaryExpression -> right.operationToken == KtTokens.RANGE",Don't quite understand why only `RANGE` is allowed here. Please consider other binary operators. It seems to me (may be I miss something) that it should be allowed for most of them.,We should also check that the typ +270,"@@ -102,7 +103,7 @@ abstract class AbstractKotlinCompilation( + // To configure a task that may have not yet been created at this point, use 'withType-matching-all`: + .withType(AbstractKotlinCompile::class.java) + .matching { it.name == compileKotlinTaskName }","we can use `named(String, Class)` ",Would it make sense to add `.with +271,"@@ -102,7 +103,7 @@ private class VarargLowering(val context: JvmBackendContext) : FileLoweringPass, + context.createJvmIrBuilder(currentScope!!.scope.scopeOwnerSymbol, startOffset, endOffset) + + private val IrFunctionSymbol.isArrayOf: Boolean +- get() = this == context.ir.symbols.arrayOf || owner.isPrimitiveArrayOf ++ get() = this == context.ir.symbols.arrayOf || owner.isArrayOf","Looks like it is already checking is this is `kotlin.Array`, so it is no need to check it by name",Why did you remove `isArrayOf` he +272,"@@ -102,7 +105,12 @@ class DefaultArgumentsConversion(context: NewJ2kConverterContext) : RecursiveApp + return JKFieldAccessExpression(newSymbol) + } + } +- ++ if (on is JKExpression) {","Please, let's don't break functionallity with remapping we already have. Join your `addThisReceiverIfNeeded` with `remapParameterSymbol`, so we will be able to do both and not just taking over one case and forgetting about other one",why do you need this? can't you just do `return on is JKExpression`? +273,"@@ -103,7 +103,8 @@ object KeywordCompletion { + var keyword = keywordToken.value + + val nextKeyword = when { +- keywordToken == SUSPEND_KEYWORD && ((position.containingFile as? KtFile)?.isScript() == true) -> null ++ keywordToken == SUSPEND_KEYWORD && ((position.containingFile as? KtFile)?.isScript() == true ","It seems like there are no actual need to prevent `suspend` or `suspend fun` completion in `.kts` files. Could you please remove this check all along, so it will be something like: + +```kt +val nextKeyword = when { + keywordToken == SUSPEND_KEYWORD && position.getStrictParentOfType() != null -> null + else -> COMPOUND_KEYWORDS[keywordToken] +} +```",@marcosrdz Looks like there was a mistake in this file. +274,"@@ -104,26 +100,33 @@ class BlockInfo private constructor(val parent: BlockInfo?) { + + class VariableInfo(val declaration: IrVariable, val index: Int, val type: Type, val startLabel: Label) + +-@Suppress(""IMPLICIT_CAST_TO_ANY"") + class ExpressionCodegen( + val irFunction: IrFunction, + val frame: IrFrameMap,","val frame -> override val frameMap, +and next frameMap declaration would be redundant +",Why remove this? +275,"@@ -106,7 +106,6 @@ class SharedVariablesLowering(val context: BackendContext) : FunctionLoweringPas + if (declaration !in sharedVariables) return declaration + + val newDeclaration = context.sharedVariablesManager.declareSharedVariable(declaration) +- newDeclaration.parent = irFunction",This could affect JS and Native,I don't understand why this change is being made. Can you explain? +276,"@@ -107,6 +107,7 @@ val jvmPhases = namedIrFilePhase( + jvmTypeOperatorLoweringPhase then + flattenStringConcatenationPhase then + foldConstantLoweringPhase then ++ computeStringTrimPhase then","@JakeWharton +As order of lowers is sufficient here, please add also some tests with constant inlining and append operations, e.g.: +``` +private const val SPACES = "" "" + + + """""" + ${SPACES + SPACES} + Hello, + World + ${SPACES + SPACES} + """""".trimIndent() + +(SPACES + """""" + ${SPACES + SPACES} + Hello, + World + ${SPACES + SPACES} + """""" + SPACES + ).trimIndent() + +```",I don't see this method being called anywhere. Am I missing somethin +277,"@@ -107,6 +107,7 @@ val jvmPhases = namedIrFilePhase( + jvmTypeOperatorLoweringPhase then + foldConstantLoweringPhase then + flattenStringConcatenationPhase then ++ computeStringTrimPhase then","I wanted to add this for JS but I don't know how to test it. Would appreciate a pointer so I can follow-up. + +And for native I assume I wait until they update to a version of compiler that contains this phase and then I can update their list?",I don't see this method being called anywhere. Am I missing somethin +278,"@@ -107,7 +108,9 @@ open class InsertImplicitCasts( + + override fun visitReturn(expression: IrReturn): IrExpression = + expression.transformPostfix { +- value = value.cast(expression.returnTarget.returnType) ++ // Don't insert an implicit cast when returning from a (secondary) constructor. ++ if (expression.returnTargetSymbol !is IrConstructorSymbol) ++ value = value.cast(expression.returnTarget.returnType)","``` +class C() { + constructor(x: Any?) : this() { + if (x is Unit) return x + } +} +``` +The artificial example above is considered well-formed, and contains smart cast to Unit. +However. this smart cast will not be represented in IR. +Actually should cast constructor return value to `kotlin.Unit`.",why don't you move the `returnType` from `IrReturn` to `IrConstructo +279,"@@ -108,10 +109,11 @@ fun KtExpression.hasSuspendCalls(bindingContext: BindingContext = analyze(BodyRe + } + } + else -> { +- val resolvedCall = getResolvedCall(bindingContext) +- if ((resolvedCall?.resultingDescriptor as? FunctionDescriptor)?.isSuspend == true) true ++ val target = (this as? KtParenthesizedExpression)?.getStrictParentOfType() ?: this","This is a very hacky way to solve the problem. The root of problem here is the fact that the considered call expression is not a valid candidate (see check at line 88), so I believe this place should be fixed instead.",Fixes an issue when we don't have a resulting descriptor. If there i +280,"@@ -108,15 +115,18 @@ internal class InterfaceLowering(val context: JvmBackendContext) : IrElementTran + Visibilities.isPrivate(function.visibility)","It's true for private non-JvmDefault, private JvmDefault should be keeped in interface",I think visibility should be `public` +281,"@@ -109,11 +111,16 @@ class ErasedInlineClassBodyCodegen( + + + override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) { +- val iv = codegen.v +- iv.aconst(null) +- iv.athrow() ++ val asmType = signature.valueParameters[0].asmType ++ val secondParameterIndex = asmType.getSize()","I think you could use `codegen.frameMap` to get JVM parameter index from a parameter descriptor directly. But it probably wouldn't be easier, so I don't insist","This is the wrong place to call this, so it needs to be reverted." +282,"@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.ir.types.IrType + interface DeclarationFactory { + object FIELD_FOR_OUTER_THIS : IrDeclarationOriginImpl(""FIELD_FOR_OUTER_THIS"", isSynthetic = true) + +- fun getFieldForEnumEntry(enumEntry: IrEnumEntry, entryType: IrType): IrField ++ fun getFieldForEnumEntry(enumEntry: IrEnumEntry): IrField",Is it also unused in K/N?,Why did you remove `entryType` here? +283,"@@ -11,8 +11,7 @@ import kotlin.test.* + class TestNGContributor : AsserterContributor { + override fun contribute(): Asserter? { + for (stackFrame in currentStackTrace()) { +- @Suppress(""PLATFORM_CLASS_MAPPED_TO_KOTLIN"") +- val className = stackFrame.className as java.lang.String ++ val className = stackFrame.className as String",isn't `className` already String?,I can't get why this change is being made. I don't think it's releva +284,"@@ -110,7 +149,10 @@ fun createContainerForLazyResolveWithJava( + useImpl() } + }.apply { +- get().initialize(bindingTrace, get()) ++ if (useJavac) ++ get().initialize(bindingTrace, get())",I'd write here `JavacBasedClassFinder`. The current name is too close to just `JavaClassFinder`.,Do we still need to pass in the `JavacClassFinder`? +285,"@@ -111,7 +114,9 @@ interface ReplEvalAction { -+ override fun callCompiler(args: K2JVMCompilerArguments, sources: List, isIncrementalRequested: Boolean, modified: List, removed: List, cachesBaseDir: File) { -+ -+ if (experimentalIncremental) { -+ // TODO: consider other ways to pass incremental flag to compiler/builder -+ System.setProperty(""kotlin.incremental.compilation"", ""true"") -+ // TODO: experimental should be removed as soon as it becomes standard -+ System.setProperty(""kotlin.incremental.compilation.experimental"", ""true"") -+ } -+ -+ val targetType = ""java-production"" -+ val moduleName = args.moduleName -+ val targets = listOf(TargetId(moduleName, targetType)) -+ val outputDir = File(args.destination) -+ val caches = hashMapOf() -+ val lookupStorage = LookupStorage(File(cachesBaseDir, ""lookups"")) -+ val lookupTracker = LookupTrackerImpl(LookupTracker.DO_NOTHING) -+ var currentRemoved = removed -+ val allGeneratedFiles = hashSetOf>() -+ val compiledSourcesSet = hashSetOf() -+ -+ fun getOrCreateIncrementalCache(target: TargetId): GradleIncrementalCacheImpl { -+ val cacheDir = File(cachesBaseDir, ""increCache.${target.name}"") -+ cacheDir.mkdirs() -+ return GradleIncrementalCacheImpl(targetDataRoot = cacheDir, targetOutputDir = outputDir, target = target) -+ } -+ -+ fun getIncrementalCache(it: TargetId) = caches.getOrPut(it, { getOrCreateIncrementalCache(it) }) -+ -+ fun PsiClass.findLookupSymbols(): Iterable { -+ val fqn = qualifiedName.orEmpty() -+ return listOf(LookupSymbol(name.orEmpty(), if (fqn == name) """" else fqn.removeSuffix(""."" + name!!))) + -+ methods.map { LookupSymbol(it.name, fqn) } + -+ fields.map { LookupSymbol(it.name.orEmpty(), fqn) } + -+ innerClasses.flatMap { it.findLookupSymbols() } -+ } -+ -+ fun Iterable.files(filesFilter: (File) -> Boolean = { true }, logAction: (LookupSymbol, Iterable) -> Unit = { l,fs -> }): Iterable = -+ flatMap { lookup -> -+ val files = lookupStorage.get(lookup).map(::File).filter(filesFilter) -+ if (files.any()) { -+ logAction(lookup, files) -+ } -+ files -+ } -+ -+ fun dirtyLookupSymbolsFromRemovedKotlinFiles(): List { -+ val removedKotlinFiles = removed.filter { it.isKotlinFile() } -+ return if (removedKotlinFiles.isNotEmpty()) -+ targets.flatMap { getIncrementalCache(it).classesBySources(removedKotlinFiles).map { LookupSymbol(it.fqNameForClassNameWithoutDollars.shortName().toString(), it.packageFqName.toString()) } } -+ else listOf() -+ } -+ -+ fun dirtyLookupSymbolsFromModifiedJavaFiles(): List { -+ val modifiedJavaFiles = modified.filter { it.isJavaFile() } -+ return (if (modifiedJavaFiles.any()) { -+ val rootDisposable = Disposer.newDisposable() -+ val configuration = CompilerConfiguration() -+ val environment = KotlinCoreEnvironment.createForProduction(rootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES) -+ val project = environment.project -+ val psiFileFactory = PsiFileFactory.getInstance(project) as PsiFileFactoryImpl -+ modifiedJavaFiles.flatMap { -+ val javaFile = psiFileFactory.createFileFromText(it.nameWithoutExtension, Language.findLanguageByID(""JAVA"")!!, it.readText()) -+ if (javaFile is PsiJavaFile) -+ javaFile.classes.flatMap { it.findLookupSymbols() } -+ else listOf() -+ } -+ } else listOf()) -+ } -+ -+ fun dirtyKotlinSourcesFromGradle(): List { -+ // TODO: handle classpath changes similarly - compare with cashed version (likely a big change, may be costly, some heuristics could be considered) -+ val modifiedKotlinFiles = modified.filter { it.isKotlinFile() } -+ val lookupSymbols = -+ dirtyLookupSymbolsFromModifiedJavaFiles() + -+ dirtyLookupSymbolsFromRemovedKotlinFiles() -+ // TODO: add dirty lookups from modified kotlin files to reduce number of steps needed -+ -+ if (lookupSymbols.any()) { -+ val kotlinModifiedFilesSet = modifiedKotlinFiles.toHashSet() -+ return modifiedKotlinFiles + -+ lookupSymbols.files( -+ filesFilter = { it !in kotlinModifiedFilesSet }, -+ logAction = { lookup, files -> -+ logger.kotlinInfo(""changes in ${lookup.name} (${lookup.scope}) causes recompilation of ${files.joinToString { projectRelativePath(it) }}"") -+ }) -+ } -+ return modifiedKotlinFiles -+ } -+ -+ fun isClassPathChanged(): Boolean { -+ // TODO: that doesn't look to wise - join it first and then split here, consider storing it somewhere in between -+ val classpath = args.classpath.split(File.pathSeparator).map { File(it) }.toHashSet() -+ val changedClasspath = modified.filter { classpath.contains(it) } -+ return changedClasspath.any() -+ } -+ -+ fun allCachesVersions() = allCachesVersions(cachesBaseDir, listOf(cachesBaseDir)) -+ -+ fun calculateSourcesToCompile(): Pair, Boolean> { -+ -+ if (!experimentalIncremental || -+ !isIncrementalRequested || -+ // TODO: more precise will be not to rebuild unconditionally on classpath changes, but retrieve lookup info and try to find out which sources are affected by cp changes -+ isClassPathChanged() || -+ // so far considering it not incremental TODO: store java files in the cache and extract removed symbols from it here -+ removed.any { it.isJavaFile() } -+ ) { -+ logger.kotlinInfo(if (!isIncrementalRequested) ""clean caches on rebuild"" else ""classpath changed, rebuilding all kotlin files"") -+ targets.forEach { getIncrementalCache(it).clean() } -+ lookupStorage.clean() -+ return Pair(sources, false) -+ } -+ val actions = if (isIncrementalRequested) allCachesVersions().map { it.checkVersion() } -+ else listOf(CacheVersion.Action.REBUILD_ALL_KOTLIN) -+ // TODO: find out whether these flags should be emulated too -+// val hasKotlin = HasKotlinMarker(dataManager) -+// val rebuildAfterCacheVersionChanged = RebuildAfterCacheVersionChangeMarker(dataManager) -+ -+ for (status in actions.distinct().sorted()) { -+ when (status) { -+ CacheVersion.Action.REBUILD_ALL_KOTLIN -> { -+ logger.kotlinInfo(""Kotlin global lookup map format changed, rebuilding all kotlin files"") -+ targets.forEach { getIncrementalCache(it).clean() } -+ lookupStorage.clean() -+ return Pair(sources, false) -+ } -+ CacheVersion.Action.REBUILD_CHUNK -> { -+ logger.kotlinInfo(""Clearing caches for "" + targets.joinToString { it.name }) -+ targets.forEach { getIncrementalCache(it).clean() } -+ } -+ CacheVersion.Action.CLEAN_NORMAL_CACHES -> { -+ logger.kotlinInfo(""Clearing caches for all targets"") -+ targets.forEach { getIncrementalCache(it).clean() } -+ } -+ CacheVersion.Action.CLEAN_EXPERIMENTAL_CACHES -> { -+ logger.kotlinInfo(""Clearing experimental caches for all targets"") -+ targets.forEach { getIncrementalCache(it).cleanExperimental() } -+ } -+ CacheVersion.Action.CLEAN_DATA_CONTAINER -> { -+ logger.kotlinInfo(""Clearing lookup cache"") -+ lookupStorage.clean() -+ dataContainerCacheVersion(cachesBaseDir).clean() -+ } -+ else -> { -+ assert(status == CacheVersion.Action.DO_NOTHING) { ""Unknown version status $status"" } -+ } -+ } -+ } -+ val dirtyFiles = dirtyKotlinSourcesFromGradle().distinct() -+ // first dirty files should be found and only then caches cleared -+ val removedKotlinFiles = removed.filter { it.isKotlinFile() } -+ targets.forEach { getIncrementalCache(it).let { -+ it.markOutputClassesDirty(removedKotlinFiles) -+ it.removeClassfilesBySources(removedKotlinFiles) -+ }} -+ return Pair(dirtyFiles, true) -+ } -+ -+ fun cleanupOnError() { -+ val outputDirFile = File(args.destination!!) -+ -+ assert(outputDirFile.exists()) -+ val generatedRelPaths = allGeneratedFiles.map { it.outputFile.toRelativeString(outputDirFile) } -+ logger.kotlinInfo(""deleting output on error: ${generatedRelPaths.joinToString()}"") -+ -+ allGeneratedFiles.forEach { it.outputFile.delete() } -+ generatedRelPaths.forEach { File(destinationDir, it).delete() } -+ } -+ -+ fun processCompilerExitCode(exitCode: ExitCode) { -+ if (exitCode != ExitCode.OK) { -+ cleanupOnError() -+ } -+ when (exitCode) { -+ ExitCode.COMPILATION_ERROR -> throw GradleException(""Compilation error. See log for more details"") -+ ExitCode.INTERNAL_ERROR -> throw GradleException(""Internal compiler error. See log for more details"") -+ ExitCode.SCRIPT_EXECUTION_ERROR -> throw GradleException(""Script execution error. See log for more details"") -+ ExitCode.OK -> logger.kotlinInfo(""Compilation succeeded"") -+ } -+ } -+ -+ fun outputRelativePath(f: File) = f.toRelativeString(outputDir) -+ -+ -+ if (!experimentalIncremental) { -+ anyClassesCompiled = true -+ processCompilerExitCode(compileNotIncremental(sources, outputDir, args)) -+ return -+ } -+ logger.warn(""Using experimental kotlin incremental compilation"") -+ -+ anyClassesCompiled = false -+ -+ // TODO: decide what to do if no files are considered dirty - rebuild or skip the module -+ var (sourcesToCompile, isIncrementalDecided) = calculateSourcesToCompile() -+ -+ if (isIncrementalDecided) { -+ // TODO: process as list here, merge into string later -+ args.classpath = args.classpath + File.pathSeparator + outputDir.absolutePath -+ } -+ -+ while (sourcesToCompile.any()) { -+ logger.kotlinInfo(""compile iteration: ${sourcesToCompile.joinToString{ projectRelativePath(it) }}"") -+ -+ val (exitCode, generatedFiles) = compileChanged( -+ targets = targets, -+ sourcesToCompile = sourcesToCompile, -+ outputDir = outputDir, -+ args = args, -+ getIncrementalCache = ::getIncrementalCache, -+ lookupTracker = lookupTracker) -+ -+ allGeneratedFiles.addAll(generatedFiles) -+ // save versions? -+ -+ val changes = updateIncrementalCaches( -+ targets = targets, -+ generatedFiles = generatedFiles, -+ compiledWithErrors = exitCode != ExitCode.OK, -+ getIncrementalCache = { caches[it]!! }) -+ -+// lookupTracker.lookups.entrySet().forEach { -+// logger.kotlinDebug(""lookups to ${it.key.name}:${it.key.scope} from ${it.value.joinToString { projectRelativePath(it) }}"") -+// } -+ -+ lookupStorage.update(lookupTracker, sourcesToCompile, currentRemoved) -+ -+ allCachesVersions().forEach { it.saveIfNeeded() } -+ -+ processCompilerExitCode(exitCode) -+ -+ if (!isIncrementalDecided) break; -+ -+// logger.kotlinDebug(""generated ${generatedFiles.joinToString { outputRelativePath(it.outputFile) }}"") -+// logger.kotlinDebug(""changes: ${changes.changes.joinToString { ""${it.fqName}: ${it.javaClass.simpleName}"" }}"") -+// -+// logger.kotlinLazyDebug({ -+// ""known lookups:\n${lookupStorage.dump(changes.changes.flatMap { -+// change -> -+// if (change is ChangeInfo.MembersChanged) -+// change.names.asSequence().map { LookupSymbol(it, change.fqName.asString()) } -+// else -+// sequenceOf() -+// }.toSet(), project.projectDir)}"" }) -+ -+ compiledSourcesSet.addAll(sourcesToCompile) -+ -+ val dirtyLookups = changes.dirtyLookups(caches.values.asSequence()) -+ -+// logger.kotlinDebug(""dirty lookups: ${dirtyLookups.joinToString { ""${it.name}:${it.scope}"" }}"") -+ -+ val dirty = dirtyLookups.files( -+ filesFilter = { it !in compiledSourcesSet }, -+ logAction = { lookup, files -> -+ logger.kotlinInfo(""changes in ${lookup.name} (${lookup.scope}) causes recompilation of ${files.joinToString { projectRelativePath(it) }}"") -+ }) -+ sourcesToCompile = dirty.filter { it in sources }.toList() -+ if (currentRemoved.any()) { -+ currentRemoved = listOf() -+ } -+// logger.kotlinDebug(""dirty: ${dirty.joinToString { projectRelativePath(it) }}"") -+// logger.kotlinDebug(""to compile: ${sourcesToCompile.joinToString { projectRelativePath(it) }}"") -+ } -+ lookupStorage.flush(false) -+ lookupStorage.close() -+ caches.values.forEach { it.flush(false); it.close() } -+ if (allGeneratedFiles.isNotEmpty()) { -+ anyClassesCompiled = true -+ } -+ } -+ -+ private data class CompileChangedResults(val exitCode: ExitCode, val generatedFiles: List>) -+ -+ private fun compileChanged(targets: List, -+ sourcesToCompile: List, -+ outputDir: File, -+ args: K2JVMCompilerArguments, -+ getIncrementalCache: (TargetId) -> GradleIncrementalCacheImpl, -+ lookupTracker: LookupTracker) -+ : CompileChangedResults -+ { -+ // show kotlin compiler where to look for java source files -+ args.freeArgs = (sourcesToCompile.map { it.absolutePath } + getJavaSourceRoots().map { it.absolutePath }).distinct() -+ args.destination = outputDir.absolutePath -+ -+ logger.kotlinDebug(""compiling with args ${ArgumentUtils.convertArgumentsToStringList(args)}"") -+ -+ val outputItemCollector = OutputItemsCollectorImpl() -+ -+ val messageCollector = GradleMessageCollector(logger, outputItemCollector) -+ -+ val incrementalCaches = makeIncrementalCachesMap(targets, { listOf() }, getIncrementalCache, { this }) -+ -+ val compilationCanceledStatus = object : CompilationCanceledStatus { -+ override fun checkCanceled() {} -+ } + sealed class ReplEvalResult : Serializable { + class ValueResult(val value: Any?) : ReplEvalResult() { +- override fun toString(): String = ""Result: $value"" ++ val type = LastInferredTypeHolder.inferredType.get()",I think you can obtain this type from `compileResult` at `GenericReplEvaluator.eval` and pass to `ValueResult`'s constructor here,Please don't make any changes to the `ValueResult` class. The only r +286,"@@ -111,8 +112,13 @@ private class InheritedDefaultMethodsOnClassesLowering(val context: JvmBackendCo + irFunction.body = irBlockBody { + +irReturn( + irCall(defaultImplFun.symbol, irFunction.returnType).apply { ++ interfaceImplementation.parentAsClass.typeParameters.forEachIndexed { index, irTypeParameter -> ++ //TODO: See Note [Interface Parameters]","Minor, but could you extract a simple method that would return `context.irBuiltIns.anyNType` and put the comment there instead, so that we have only one TODO instead of three?",I think this TODO can be removed now. +287,"@@ -112,7 +133,7 @@ private fun collectionsSort(list: MutableList, comparator: Comparator ""Property"" + } + val nameElement = (declaration as? PsiNameIdentifierOwner)?.nameIdentifier ?: return +- holder.registerProblem(declaration.visibilityModifier() ?: nameElement, ++ val visibilityModifier = declaration.visibilityModifier() ++ val fix = object : AddModifierFix(modifierListOwner, KtTokens.PRIVATE_KEYWORD) {","I would do this as a general fix to AddModifierFix (which already has special logic for handling modality modifiers), not as a single-case override here.",Any reason why you didn't use `RegisterProblem` with the `modifierListOwner` parameter? +289,"@@ -113,6 +112,7 @@ open class ChangeVisibilityModifierIntention protected constructor( + class Private : ChangeVisibilityModifierIntention(KtTokens.PRIVATE_KEYWORD), HighPriorityAction { + override fun applicabilityRange(element: KtDeclaration): TextRange? { + if (isAnnotationClassPrimaryConstructor(element)) return null ++ if (element is KtProperty && element.hasJvmFieldAnnotation()) return null","I'd say it's not the best way to fix it. It's more correct to have all necessary checks inside `canBePrivate` and `canBeInternal` (which does not yet exist). Take into account the fact that both `ChangeVisibilityFix` and `ChangeVisibilityModifierIntention` use `canBePrivate` (and should probably share the same logic). Also I'd recommend to consider content of `canBePrivate` inside `MemberVisibilityCanBePrivateInspection` (private fun). I suspect that some checks from there (not all) could be used inside global `canBePrivate` (that can also fix a bunch of minor bugs, not reported yet).",nit: use `isKtProperty` instead of `isKtProperty`. +290,"@@ -115,7 +115,21 @@ class CodeConverter( + if (needConversion(actualType, expectedType)) { + val expectedTypeStr = expectedType.canonicalText + if (expression is PsiLiteralExpression) { +- if (expectedTypeStr == ""float"" || expectedTypeStr == ""double"") { ++ if (actualType.canonicalText == ""char"" && expression.parent !is PsiExpressionList) { ++ when (expectedTypeStr) {","I think that's here should be a better way. +Better to move such code may be to type converter or so. +Because it looks like something similar required here #1200",I don't think this is correct. This expression.parent will never be PsiExpressionList. +291,"@@ -115,9 +116,73 @@ class KotlinCodeFragmentFactory: CodeFragmentFactory() { + } + }) + ++ if (contextElement != null && contextElement !is KtElement) {","Now such variables are skipped during text rendering, so it doesn't matter if they are present in resulting map (this map is used only to get values for kotlin variables that are present in resulting text) +",Why do we need the `!is KtElement` check here? Shouldn't it always be a KtElement? +292,"@@ -116,4 +116,31 @@ public String toString() { + return ""("" + line + "","" + column + "")""; + } + } + -+ logger.kotlinDebug(""compiling with args ${ArgumentUtils.convertArgumentsToStringList(args)}"") ++ public static final class LineAndColumnRange {",I think that this change as well as the appropriate `getLineAndColumnRange*` helpers will fit into the separate commit with `CompilerMessageLocation` as well - they seem both have the same reason behind.,Doesn't look like this class was used anywhere. Can we remove it? +293,"@@ -1168,3 +1122,96 @@ fun CompileTimeConstant<*>.isStandaloneOnlyConstant(): Boolean { + else -> return false + } + } + -+ val exitCode = compiler.exec(messageCollector, makeCompileServices(incrementalCaches, lookupTracker, compilationCanceledStatus), args) ++internal fun isZero(value: Any?): Boolean {",private,This feels a bit awkward. `isZero` sounds like a function that checks if the value is z +294,"@@ -1168,3 +1122,96 @@ fun CompileTimeConstant<*>.isStandaloneOnlyConstant(): Boolean { + else -> return false + } + } + -+ return CompileChangedResults( -+ exitCode, -+ outputItemCollector.generatedFiles( -+ targets = targets, -+ representativeTarget = targets.first(), -+ getSources = { sourcesToCompile }, -+ getOutputDir = { outputDir })) ++internal fun isZero(value: Any?): Boolean { ++ return when { ++ isIntegerType(value) -> (value as Number).toLong() == 0L ++ value is Float || value is Double -> (value as Number).toDouble() == 0.0 ++ else -> false + } ++} + -+ private fun compileNotIncremental(sourcesToCompile: List, -+ outputDir: File, -+ args: K2JVMCompilerArguments) -+ : ExitCode","Minor: formatting -","this is not the right way to do it. these arguments are not the same as the `kotlin.extra.compilation` flag," -686,"@@ -168,6 +168,20 @@ class CommonIntentionActionsTest : LightPlatformCodeInsightFixtureTestCase() { - """""".trim().trimMargin(), true) ++internal fun typeStrToCompileTimeType(str: String) = when (str) {",private,Not sure what the best way to do this is. `value is Number` -> `isNaN` -> `isPositiveNu +295,"@@ -118,6 +134,18 @@ internal class ProgressionHeaderInfo( + } + constLimitAsLong == lastValueAsLong } - -+ fun testRemoveConstructorParameters() { -+ myFixture.configureByText(""foo.kt"", """""" -+ |class Foo(i: Int) { -+ |} -+ """""".trim().trimMargin()) -+ -+ myFixture.launchAction(codeModifications.createAddCallableMemberActions(MethodInsertionInfo.constructorInfo( -+ atCaret(myFixture), makeParams())).findWithText(""Remove 1st parameter from method 'Foo'""))","It's better to change the intention text so that it says ""constructor"" and not ""method"".",This line goes over the 80 character limit. Max line length is 79 characters. -687,"@@ -17,12 +17,22 @@ - package org.jetbrains.kotlin.idea.compiler.configuration - - import com.intellij.compiler.server.BuildProcessParametersProvider -+import org.jetbrains.kotlin.idea.PluginStartupComponent - --public class KotlinBuildProcessParametersProvider(private val compilerWorkspaceSettings: KotlinCompilerWorkspaceSettings): BuildProcessParametersProvider() { -+public class KotlinBuildProcessParametersProvider(private val compilerWorkspaceSettings: KotlinCompilerWorkspaceSettings, -+ private val kotlinPluginStartupComponent: PluginStartupComponent -+): BuildProcessParametersProvider() { - override fun getVMArguments(): MutableList { -- return if (compilerWorkspaceSettings.incrementalCompilationEnabled) -- arrayListOf() -- else -- arrayListOf(""-Dkotlin.incremental.compilation=false"") -+ val res = arrayListOf() -+ if (compilerWorkspaceSettings.incrementalCompilationEnabled) {","Is it ok that behavior changed? -",Could you please rename `PluginStartupComponent` to just `StartupComponent`? Thanks! -688,"@@ -17,3 +17,11 @@ - package org.jetbrains.kotlin.cli.common - - public val KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY = ""kotlin.environment.keepalive"" + -+ -+fun String?.toBooleanLenient(): Boolean? = when (this?.toLowerCase()) {","It seems it is possible to simplify conditional expressions by using the following function instead of `toBooleanLenient` - ++ override fun asReversed() = ProgressionHeaderInfo(","Please add bytecode test with double reverse for array.indices and constant until ranges, e.g.: ``` -fun String.systemPropertyAsBooleanOrTrueOtherwise(negate: Boolean): Boolean { - val propValue = System.getProperty(this) ?: return true +fun box(): String { + var sum = 0 + for (i in (1 until 5).reversed().reversed()) { + sum = sum * 10 + i + } - return when (propValue.toLowerCase()) { - in listOf("""", ""yes"", ""true"", ""on"", ""y"") -> !negate - in listOf(""no"", ""false"", ""off"", ""n"") -> negate - else -> true + var sumL = 0L + for (i in (1L until 5L).reversed().reversed()) { + sumL = sumL * 10 + i } + + var sumC = 0 + for (i in ('1' until '5').reversed().reversed()) { + sumC = sumC * 10 + i.toInt() - '0'.toInt() + } + + return ""OK"" } ``` +",Did you forget to remove the `override fun asReversed()` in ProgressionHeaderInfo.js? +296,"@@ -119,3 +119,28 @@ fun IrType.substitute(substitutionMap: Map): IrTy + newAnnotations + ) + } ++ ++fun getImmediateSupertypes(type: IrSimpleType): List {",`private`,Add docstring for this function +297,"@@ -119,7 +119,7 @@ private static String renderTemplate(String template, int number, String element + .replace(""\n"", LineSeparator.getSystemLineSeparator().getSeparatorString()); + } + +- private static final List WHITELISTED_FOR_JVM_IR_BACKEND = Collections.singletonList(""overflowZeroDownToMaxValue.kt"");",How did these changes break the test for JVM IR?,How about using the `StandardCharsets.UTF_8` constant? +298,"@@ -1199,6 +1199,29 @@ class KotlinTypeMapper @JvmOverloads constructor( + ?: computeInternalName(classDescriptor, typeMappingConfiguration, isIrBackend) + } + ++ private fun getDefaultDescriptor(",Could you keep old position of method and just pass neccesery parameters to it: actually there would be new TypeMapper for IR so all IR related logic would be removed from current one,why not the default implementation? +299,"@@ -12,3 +12,11 @@ class TestInitValInInitBlock { + } + } + ++class TestInitValInLambdaCalledOnce { ++ val x: Int ++ init { ++ 1.run {",`init { 1.run { } }` causes fir to fail with an error at `ConeClassifierLookupTag.toSymbol` because the tag is of unexpected type `ConeTypeVariableTypeConstructor`. Is there a way to mute this test for fir?,Wouldn't this be enough to just have `init: Int`? +300,"@@ -12,6 +11,16 @@ fun test() { + // 0 getFirst + // 0 getLast + ++// JVM non-IR uses while. ++// JVM IR uses if + do-while. ++ ++// JVM_TEMPLATES + // 0 IF_ICMPGT",These two lines (`// 0 IF_...`) can be removed; they are made redundant by the `// 1 IF`,"what does ""if + do-while"" mean here?" +301,"@@ -12,6 +11,4 @@ fun test() { + // 0 getFirst + // 0 getLast + +-// 0 IF_ICMPGT +-// 0 IF_ICMPEQ +-// 1 IF_ICMPGE ++// 1 IF_ICMP","@punzki +``` +// 1 IF_ICMPGE +``` +Could be reverted, please also add : +``` +// 1 IF +```",Why did you remove `IF_ICMPGT` and `IF_ICMPGE` here? +302,"@@ -12,6 +12,20 @@ import java.io.File + import java.io.IOException + import java.util.ArrayDeque + ++/** ++ * An enumeration to describe possible algorithms to traverse. ++ * There are two of them: search in breadth (same directory depth) ++ */ ++public enum class WalkAlgorithm { ++ /** ++ * Breadth-first search ++ */ ++ BFS,","I actually believe we should write these out as `BREADTH_FIRST` and `DEPTH_FIRST`, just like we have `TOP_DOWN` instead of `TD` below.",Breadth-first search -> Breadth-first search +303,"@@ -12,6 +12,20 @@ import java.io.File + import java.io.IOException + import java.util.ArrayDeque + ++/** ++ * An enumeration to describe possible algorithms to traverse. ++ * There are two of them: search in breadth (same directory depth) ++ */ ++public enum class WalkAlgorithm { ++ /** ++ * Breadth-first search ++ */ ++ BFS, ++ /** ++ * Depth-first search ++ */ ++ DFS ++}",Nit: Missing blank line after this one.,Should we rename this to DepthFirstSearchAlgorithm? +304,"@@ -12,6 +12,8 @@ internal external object QUnit { + fun module(name: String, suiteFn: () -> Unit): Unit + fun test(name: String, testFn: (dynamic) -> Any?): Unit + fun skip(name: String, testFn: (dynamic) -> Any?): Unit ++ fun beforeEach(name: String, beforeFn: () -> Any?): Unit ++ fun afterEach(name: String, afterFn: () -> Any?): Unit","Couldn't find this API neither in the docs, nor in npm qunit package version 2.9.3. +i.e. `require('qunit').beforeEach` => `undefined` -See comments below. -",This should be `boolean` not `Boolean`. -689,"@@ -17,6 +17,7 @@ - package kotlin +The closest I could find are hooks: https://api.qunitjs.com/QUnit/module +Those could be utilized, but this is not a correct way to do that.",You can use `Any` here instead of `Any?` as the return type is `Any`. +305,"@@ -12,7 +12,7 @@ public fun Enumeration.iterator(): Iterator = object : Iterator { + } /** -- * Nothing has no instances -+ * Nothing has no instances. You can use Nothing as the return type of a function to indicate -+ * that it never returns (always throws an exception).","There are more use-cases for Nothing, e.g. Iterable is ok to exist, but it will never enter ""for"" loop, etc. Needs link to lang docs. -","It's not clear what ""always returns"" me" -690,"@@ -171,11 +171,21 @@ private val stdin: BufferedReader by lazy { BufferedReader(InputStreamReader(obj - public override fun read(b: ByteArray, off: Int, len: Int): Int { - return System.`in`.read(b, off, len) +- * Returns the given iterator itself. This allows to use an instance of iterator in a ranged for-loop ++ * Returns the given iterator itself. This allows to use an instance of iterator in a ranged for-loop.","""ranged for-loop"" -> ""`for` loop"" +",Unused import `ranged for-loop` +306,"@@ -120,6 +120,7 @@ class DeclarationStubGenerator( + constantValueGenerator.generateConstantValueAsExpression(UNDEFINED_OFFSET, UNDEFINED_OFFSET, it) + ) + } ++ parent = generateParentStub(descriptor)",Seems like it overrides parent for deserialised IrField as well.,"This is going to cause all of the tests to fail, since `generateParen" +307,"@@ -120,6 +121,14 @@ class SingleAbstractMethodLowering(val context: CommonBackendContext) : FileLowe + } + +irIfNull(superType, irGet(invokableVariable), irNull(), instance) + } ++ } else if (invokable !is IrGetValue) { ++ // Hack for the JVM inliner: since the SAM wrappers might be regenerated, avoid putting complex logic",Please mention KT-21781 here ,Would it be better to use `!isIrGetValue` here? +308,"@@ -120,6 +129,39 @@ fun JetElement.wrapInBlock(): JetBlockExpression { + block.appendElement(this) + return block + } ++ ++fun JetExpressionImpl.findBlockInExpression(element: JetExpressionImpl, expressionType: String?): JetBlockExpression? {","Why are this and the following functions extensions, but you don't use `this` in them and require call sites to pass same value twice? +","woops, will add this in my next PR" +309,"@@ -120,7 +103,6 @@ From this root project there are Run/Debug Configurations for running IDEA or th + * VCS -> Git -> Pull + * Run IntelliJ IDEA","it's unclear that it is ""IDEA"" run configuration",Please remove this extra line +310,"@@ -123,6 +123,7 @@ class ReplaceCallWithBinaryOperatorInspection : AbstractApplicabilityBasedInspec + return when (identifier) { + OperatorNameConventions.EQUALS -> { + if (!dotQualified.isAnyEquals()) return null ++ if (dotQualified.isFloatingPointNumberEquals()) return null","Here we should not just drop a suggestion. It should be kept, but its highlight type should be changed to `INFORMATION`, and its fix text changed to `Replace total order equality with IEEE 754 equality`.",Are we missing tests for this? +311,"@@ -124,21 +128,71 @@ class ConvertTwoComparisonsToRangeCheckIntention : SelfTargetingOffsetIndependen + // To avoid possible side effects + if (!min.isSimple() || !max.isSimple()) return null + ++ val valContext = value.analyze()",You don't need to call `analyze()` multiple times; calling it once will return a `BindingContext` with information about all the expressions.,Why is this needed? The parameter `val` doesn't seem to be used. +312,"@@ -124,6 +124,7 @@ private val jvmFilePhases = + + enumWhenPhase then + singletonReferencesPhase then ++ callableReferencePhase then","Since this changes the order of the phases, are there new requirements on the order that should be explicitly declared somewhere?",Can we add a TODO to remove this in the future? +313,"@@ -125,6 +133,52 @@ class DefaultArgumentsConversion(context: NewJ2kConverterContext) : RecursiveApp + } --}))} -+})} - /** - * Reads a line of input from the standard input stream. - * - * @return the line read or `null` if the input stream is redirected to a file and the end of file has been reached. - */ --public fun readLine(): String? = stdin.readLine() -+public fun readLine(): String? { -+ tailrec fun readChars(oldBuffer: StringBuffer? = null): StringBuffer? {",Why do you choose `StringBuffer` instead of `StringBuilder`?,Why is this needed? -691,"@@ -171,11 +171,21 @@ private val stdin: BufferedReader by lazy { BufferedReader(InputStreamReader(obj - public override fun read(b: ByteArray, off: Int, len: Int): Int { - return System.`in`.read(b, off, len) ++ private fun JKExpression.addThisReceiverIfNeeded(","Also, please use `applyRecursive` for creating recursive conversions as it will not unnecessary recreate tree elements ",It looks like `addThisReceiverIfNeeded` and `addThisReceiverIfNeeded` +314,"@@ -125,9 +125,6 @@ class EnumClassConstructorTransformer(val context: CommonBackendContext, private + private val loweredEnumConstructors = HashMap() + + fun transform(): List { +- // Make sure InstanceInitializer exists",@skuzmich Please take a look for js/lower/EnumClassLowering.kt changes,"Can you remove the `IrConstructorSymbol` from the transform, since it" +315,"@@ -126,6 +131,12 @@ fun IrFunctionBuilder.buildConstructor(): IrConstructor { } --}))} -+})} + } + ++inline fun buildFunWithDescriptor(originalDescriptor: FunctionDescriptor, b: IrFunctionBuilder.() -> Unit): IrFunctionImpl =",Please rename 'b' to something meaningful: builder?,Would it be better to have this return a `Unit` instead of `FunctionD +316,"@@ -127,7 +127,9 @@ open class ClassCodegen protected constructor( + val shortName = File(fileEntry.name).name + visitor.visitSource(shortName, null) + } +- ++ if (irClass in context.suspendFunctionContinuations.values) {",This is a left-over from a previous hack. It can be removed.,"If the goal is to get rid of `suspendFunctionContinuations`, why do w" +317,"@@ -12710,6 +12865,8 @@ public inline fun Array.reduceRight(operation: (T, acc: S) -> /** - * Reads a line of input from the standard input stream. - * - * @return the line read or `null` if the input stream is redirected to a file and the end of file has been reached. - */ --public fun readLine(): String? = stdin.readLine() -+public fun readLine(): String? { -+ tailrec fun readChars(oldBuffer: StringBuffer? = null): StringBuffer? { -+ val c = mystdin.read()",What is `mystdin` here?,Please annotate `oldBuffer` with `@Null -692,"@@ -171,11 +171,21 @@ private val stdin: BufferedReader by lazy { BufferedReader(InputStreamReader(obj - public override fun read(b: ByteArray, off: Int, len: Int): Int { - return System.`in`.read(b, off, len) + * Accumulates value starting with last element and applying [operation] from right to left to each element and current accumulator value. ++ * ++ * @sample samples.collections.Collections.Aggregates.reduceRightOrNull","This sample is for `reduceRightOrNull` and doesn't relate to `reduceRight`. Perhaps it was misplaced? + +Note that the samples for `reduceRight` have been already submitted in the PR #2867.",Maybe it would be more clear and explicit to call this `reduceRight` +318,"@@ -128,6 +128,8 @@ extra[""versions.jsr305""] = ""1.3.9"" + extra[""versions.jansi""] = ""1.16"" + extra[""versions.jline""] = ""3.3.1"" + extra[""versions.junit""] = ""4.12"" ++extra[""versions.junit5""] = ""5.2.0"" ++extra[""versions.junit-platform""] = ""1.2.0""","Here we specify the versions that will be used throughout the entire project, e.g. in case if Kotlin project would be using JUnit 5 to run its own tests. That version should not necessary be the same as the version against which kotlin-test-junit5 is being built.",Is there a reason we are not using junit4 here? +319,"@@ -129,19 +126,22 @@ class MovePropertyToConstructorIntention : + return parameterDescriptor.source.getPsi() as? KtParameter } --}))} -+})} - /** - * Reads a line of input from the standard input stream. - * - * @return the line read or `null` if the input stream is redirected to a file and the end of file has been reached. +- private fun KtAnnotationEntry.isApplicableToConstructorParameter(): Boolean { +- val context = analyze(BodyResolveMode.PARTIAL) +- val descriptor = context[BindingContext.ANNOTATION, this] ?: return false ++ private fun KtAnnotationEntry.getTextWithUseSite(context: BindingContext): String {","The priority of annotation without use-site application is value parameter (the highest), property, field (the lowest) for constructor parameter property. For regular property it is property (the highest), field (the lowest). So, if some annotation is not applicable to value parameter (VALUE_PARAMETER target is not included), then we should not add use-site while moving to constructor because it will be redundant (priority queue will be the same). And only in case VALUE_PARAMETER target is included we should do all this checks you have done here. ",This should be `getTextWithResolveMode()`. +320,"@@ -129,19 +129,16 @@ public fun File.forEachBlock(action: (buffer: ByteArray, bytesRead: Int) -> Unit */ --public fun readLine(): String? = stdin.readLine() -+public fun readLine(): String? { -+ tailrec fun readChars(oldBuffer: StringBuffer? = null): StringBuffer? { -+ val c = mystdin.read() -+ if(c < 0) return oldBuffer -+ val buffer = oldBuffer ?: StringBuffer() -+ val ch = c.toChar() -+ if(ch == '\r' || ch == '\n') return buffer","We should support ""\n"" and ""\r\n"" line delimiters, and ""\r"" alone can be treated like a plain character.",Please annotate `oldBuffer` with `@Null -693,"@@ -171,11 +171,21 @@ private val stdin: BufferedReader by lazy { BufferedReader(InputStreamReader(obj - public override fun read(b: ByteArray, off: Int, len: Int): Int { - return System.`in`.read(b, off, len) - } --}))} -+})} + public fun File.forEachBlock(blockSize: Int, action: (buffer: ByteArray, bytesRead: Int) -> Unit): Unit { + val arr = ByteArray(blockSize.coerceAtLeast(MINIMUM_BLOCK_SIZE)) +- val fis = FileInputStream(this) + +- try { ++ inputStream().use { + do { +- val size = fis.read(arr) ++ val size = it.read(arr)","Better to add a more descriptive name instead of `it`, as it is inside a multiline lambda, for example `stream` or `input`.",What's the motivation for this change? +321,"@@ -13,3 +13,4 @@ fun foo(f: () -> Unit) { + } + + // 2 6 9 12 13 3 4 7 8 ++// IGNORE_BACKEND: JVM_IR","Could you look into this test too: it's fails on Windows: https://teamcity.jetbrains.com/comparisonFailureDiffView.html?buildId=2450360&testId=453380 +Maybe additional empty line is required to separate numbers from ignore directive",I think this should be removed. +322,"@@ -13,8 +13,8 @@ private enum class State { + } /** - * Reads a line of input from the standard input stream. - * - * @return the line read or `null` if the input stream is redirected to a file and the end of file has been reached. - */ --public fun readLine(): String? = stdin.readLine() -+public fun readLine(): String? { -+ tailrec fun readChars(oldBuffer: StringBuffer? = null): StringBuffer? { -+ val c = mystdin.read() -+ if(c < 0) return oldBuffer -+ val buffer = oldBuffer ?: StringBuffer() -+ val ch = c.toChar() -+ if(ch == '\r' || ch == '\n') return buffer -+ return readChars(buffer.append(ch)) -+ } -+ return readChars()?.toString() -+}","Overall, `buildString` + imperative loop might be more clear than tail recursion approach.",Replace this with a call to `toChar` on -694,"@@ -171,6 +138,36 @@ public open class KotlinCompile() : AbstractKotlinCompile { + + if (requestedTargetName == KOTLIN_TARGET_FOR_DEVICE) { + // We create a fat framework only for device platforms: iosArm64 and iosArm32. +- val devicePlatforms = listOf(KonanTarget.IOS_ARM64, KonanTarget.IOS_ARM32) ++ val devicePlatforms = listOf(KonanTarget.IOS_ARM64, KonanTarget.IOS_ARM32,",The comment above also needs to be updated.,This doesn't seem right. The list of p +330,"@@ -135,4 +136,23 @@ public static KotlinSingleIntentionActionFactory createFactory() { + } + }; + } + -+ // override source to track source directory sets -+ override fun source(vararg sources: Any?): SourceTask? { -+ for (source in sources) { -+ if (source is SourceDirectorySet) { -+ srcDirsSources.add(source) -+ } -+ } -+ return super.source(sources) -+ } -+","SourceTask has ""protected final List source"" field from version 1.10 (or 1.11) -",`srcDirsSources` will be populated when -695,"@@ -1730,14 +1730,14 @@ public fun Stream.lastOrNull(): T? { - } ++ public static KotlinSingleIntentionActionFactory createLateInitFactory() {","Please convert this file to Kotlin if you're adding substantial new code to it. (Rename to .kt, commit, then rename back to .java, run J2K, make any changes needed for the project to compile, commit again, then make your changes.)",Would it make sense to rename this fac +331,"@@ -1354,6 +1370,72 @@ public IElementType parseProperty(PropertyParsingMode mode) { + return multiDeclaration ? DESTRUCTURING_DECLARATION : PROPERTY; + } + ++ //public void parseProperty(PropertyParsingMode mode) {",Avoid such commented blocks. There is nothing good in having them in code,This method should be removed. +332,"@@ -137,6 +137,16 @@ + ) + public String[] scriptResolverEnvironment; + ++ // Javac options ++ @Argument(value = ""-Xuse-javac"", description = ""Use Javac analysis"")","Consider something like `""Use javac for analysis of Java source and class files""`",I don't think we should add `-Xuse-jav +333,"@@ -137,8 +137,8 @@ public inline fun String.Companion.format(format: String, vararg args: Any?): St + public inline fun String.format(locale: Locale, vararg args : Any?) : String = java.lang.String.format(locale, this, *args) /** -- * Returns last element, or null if collection is empty -+ * Returns the last character, or null if the string is empty - */ - public fun String.lastOrNull(): Char? { - return if (isEmpty()) null else this[length() - 1] +- * Uses this string as a format string and returns a string obtained by substituting the specified arguments, +- * using the default locale. ++ * Uses this string as a format string and returns a string obtained by substituting the specified arguments, using","I've spotted another copy-paste related issue: it uses not this string, but the provided [format] string. +Could you improve these two overloads' docs as well?",Why did you remove the default locale? +334,"@@ -138,7 +153,7 @@ internal class ProgressionLoopHeader( + + override fun buildLoop(builder: DeclarationIrBuilder, oldLoop: IrLoop, newBody: IrExpression?): LoopReplacement { + with(builder) { +- var (newLoop, replacementExpression) = if (headerInfo.canOverflow) { ++ return if (headerInfo.canOverflow) {","Nit, but could you use an expression body here?",Why remove `newLoop` from the function +335,"@@ -139,29 +140,34 @@ public fun File.readLines(charset: Charset = Charsets.UTF_8): List { + return result } - /** -- * Returns last element matching the given *predicate*, or null if element was not found -+ * Returns the last element matching the given [predicate], or *null* if no such element was found.","_null_ -> `null` -",This worries me a bit. It's not the las -696,"@@ -175,6 +175,23 @@ class KotlinQuickDocumentationProvider : AbstractDocumentationProvider() { - // element is not an KtReferenceExpression, but KtClass of enum - return renderEnum(element, originalElement, quickNavigation) +-/** Creates a buffered reader, or returns self if Reader is already buffered */ ++/** Creates a buffered reader wrapping this Reader, or returns self if Reader is already buffered */","self -> this Reader +",Also mention that returns self. +336,"@@ -139,6 +140,9 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter { + } } -+ else if (element is KtEnumEntry && !quickNavigation) { -+ val desc = element.resolveToDescriptorIfAny() -+ val ordinal =",It's better to calculate ordinal with `val ordinal = element.containingClassOrObject?.run { getChildrenOfType().indexOf(element) }`,When will the element be a KtEnumEntry? -697,"@@ -18,13 +18,15 @@ package org.jetbrains.kotlin.idea.quickfix - - import com.intellij.openapi.editor.Editor - import com.intellij.openapi.project.Project -+import com.intellij.psi.util.PsiTreeUtil - import org.jetbrains.kotlin.diagnostics.Diagnostic - import org.jetbrains.kotlin.psi.KtFile - import org.jetbrains.kotlin.psi.KtIsExpression - import org.jetbrains.kotlin.psi.KtPsiFactory -+import org.jetbrains.kotlin.psi.KtWhenEntry - import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType - --class RemoveUselessIsCheckFix(element: KtIsExpression) : KotlinQuickFixAction(element) { -+class RemoveUselessIsCheckFixForIf(element: KtIsExpression) : KotlinQuickFixAction(element) {","Not a good name, may be it's better to leave it as before. This action is applicable also for when without subject, or just for code like `val a = b is Any`.","The commit message should say ""Remove U" -698,"@@ -18,18 +18,17 @@ package org.jetbrains.kotlin.idea.intentions - - import com.intellij.openapi.editor.Editor - import org.jetbrains.kotlin.idea.core.replaced --import org.jetbrains.kotlin.psi.KtCallExpression --import org.jetbrains.kotlin.psi.KtDotQualifiedExpression --import org.jetbrains.kotlin.psi.KtPsiFactory --import org.jetbrains.kotlin.psi.createExpressionByPattern -+import org.jetbrains.kotlin.psi.* - import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType - - abstract class ReplaceMathMethodsWithKotlinNativeMethodsIntention( -- text: String, val replacedMethodName: String, val mathMethodName: String -+ text: String, private val replacedMethodName: String, private val mathMethodName: String - ) : SelfTargetingOffsetIndependentIntention(KtCallExpression::class.java, text) { - - override fun applyTo(element: KtCallExpression, editor: Editor?) { -- val target = element.getStrictParentOfType() ?: element -+ val target = element.getStrictParentOfType()?.takeIf { -+ (it.receiverExpression as? KtNameReferenceExpression)?.getReferencedName() == ""Math"" -+ } ?: element","It's also not the best way, you can meet something like - + result = BinaryExpression(leftConverted, rightConverted, operator.assignPrototype(expression.operationSign)) ++ if (!expression.isInSingleLine()) {","Will be ``` -Math.max(max(1, 3), max(2, 4)) +String a = b + + c; ``` - -and will have the same problem. Will fix it myself.","No wildcard imports, please." -699,"@@ -18,246 +18,376 @@ package org.jetbrains.kotlin.rmi.kotlinr - - import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache - import org.jetbrains.kotlin.rmi.* --import java.io.File --import java.io.OutputStream --import java.io.PrintStream -+import java.io.* - import java.rmi.ConnectException --import java.rmi.Remote - import java.rmi.registry.LocateRegistry - import java.util.concurrent.Semaphore - import java.util.concurrent.TimeUnit - import kotlin.concurrent.thread - --fun Process.isAlive() = -+ -+public object KotlinCompilerClient { -+ -+ val DAEMON_DEFAULT_STARTUP_TIMEOUT_MS = 10000L -+ val DAEMON_CONNECT_CYCLE_ATTEMPTS = 3 -+ -+ -+ // TODO: remove jvmStatic after all use sites will switch to kotlin -+ jvmStatic -+ public fun connectToCompileService(compilerId: CompilerId, -+ daemonJVMOptions: DaemonJVMOptions, -+ daemonOptions: DaemonOptions, -+ reportingTargets: DaemonReportingTargets, -+ autostart: Boolean = true, -+ checkId: Boolean = true -+ ): CompileService? { -+ -+ var attempts = 0 -+ var fileLock: FileBasedLock? = null - try { -- this.exitValue() -- false -+ while (attempts++ < DAEMON_CONNECT_CYCLE_ATTEMPTS) { -+ val service = tryFindDaemon(File(daemonOptions.runFilesPath), compilerId, reportingTargets) -+ if (service != null) { -+ if (!checkId || checkCompilerId(service, compilerId)) { -+ reportingTargets.report(DaemonReportCategory.DEBUG, ""connected to the daemon"") -+ return service -+ } -+ reportingTargets.report(DaemonReportCategory.DEBUG, ""compiler identity don't match: "" + compilerId.mappers.flatMap { it.toArgs("""") }.joinToString("" "")) -+ if (!autostart) return null -+ reportingTargets.report(DaemonReportCategory.DEBUG, ""shutdown the daemon"") -+ service.shutdown() -+ // TODO: find more reliable way -+ Thread.sleep(1000) -+ reportingTargets.report(DaemonReportCategory.DEBUG, ""daemon shut down correctly, restarting search"") -+ } -+ else { -+ if (!autostart) return null -+ reportingTargets.report(DaemonReportCategory.DEBUG, ""no suitable daemon found, starting a new one"") -+ } -+ -+ if (fileLock == null || !fileLock.isLocked()) { -+ File(daemonOptions.runFilesPath).mkdirs() -+ fileLock = FileBasedLock(compilerId, daemonOptions) -+ // need to check the daemons again here, because of possible racing conditions -+ // note: the algorithm could be simpler if we'll acquire lock right from the beginning, but it may be costly -+ attempts-- -+ } -+ else { -+ startDaemon(compilerId, daemonJVMOptions, daemonOptions, reportingTargets) -+ reportingTargets.report(DaemonReportCategory.DEBUG, ""daemon started, trying to resolve"") -+ } -+ } - } -- catch (e: IllegalThreadStateException) { -- true -+ catch (e: Exception) { -+ reportingTargets.report(DaemonReportCategory.EXCEPTION, e.toString()) -+ } -+ finally { -+ fileLock?.release() +parenthesized then? +Please add such test anyway. ",The result is ignored if `expression.isInSingleLine()` is false. +337,"@@ -139,9 +139,21 @@ class KotlinConstructorUMethod( + initializers.forEach {",`initializers` should be here only for primary constructors,Why did you change this? +338,"@@ -14,11 +14,19 @@ enum class Family(val exeSuffix:String, val dynamicPrefix: String, val dynamicSu + val staticPrefix: String, val staticSuffix: String) { + OSX (""kexe"", ""lib"", ""dylib"", ""lib"", ""a""), + IOS (""kexe"", ""lib"", ""dylib"", ""lib"", ""a""), ++ TVOS (""kexe"", ""lib"", ""dylib"", ""lib"", ""a""),",Better align like others.,Looks like there's some whitespace issues here. +339,"@@ -14,6 +14,9 @@ + ++ { + doc { f -> ""Returns `true` if [element] is found in the ${f.collection}."" } + typeParam(""@kotlin.internal.OnlyInputTypes T"") + returns(""Boolean"") +- body(Iterables) { f -> ++ body(Iterables) {","Please extract unrelated changes, such as formatting improvement in a separate PR.",Why did you remove the anonymous function? +341,"@@ -14,7 +14,8 @@ buildscript { + val repos = listOfNotNull( + bootstrapKotlinRepo, + ""https://jcenter.bintray.com/"", +- ""https://plugins.gradle.org/m2"") ++ ""https://plugins.gradle.org/m2"", ++ ""https://oss.sonatype.org/content/repositories/snapshots"")","Please, add the snapshots repo directly to the `kotlin-script-util` build script. I think we don't want (yet) to add it to all projects.",@martinwicke Is there a way to test this? +342,"@@ -140,6 +142,7 @@ class CommentSaver(originalElements: PsiChildRange, private val saveLineBreaks: + private val lineBreaksToRestore = ArrayList() + private var toNewPsiElementMap by Delegates.notNull>>() + private var needAdjustIndentAfterRestore = false ++ private var isSingleExpressionWithCommentBeneath = false","Please convert it to a parameter of `restore`, with default value. Don't introduce additional class state when it's not required",Please rename this to isSingleExpressionWithCommentBeneath. +343,"@@ -141,13 +141,28 @@ public static void checkAnnotationType( } -+ return null -+ } - --public class KotlinCompilerClient { - -- companion object { -+ public fun shutdownCompileService(daemonOptions: DaemonOptions): Unit { -+ KotlinCompilerClient.connectToCompileService(CompilerId(), DaemonJVMOptions(), daemonOptions, DaemonReportingTargets(out = System.out), autostart = false, checkId = false) -+ ?.shutdown() -+ } - -- val DAEMON_STARTUP_TIMEOUT_MS = 10000L + } -- private fun connectToService(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): CompileService? { -+ public fun shutdownCompileService(): Unit { -+ shutdownCompileService(DaemonOptions()) -+ } ++ @Nullable ++ private static T findAncestorOfType(@NotNull PsiElement element, Class ancestorType) {","There is already `getParentOfType`, please use it here",Please annotate `@Nullable`. +344,"@@ -141,6 +139,28 @@ class ExpressionCodegen( + mv.visitEnd() + } -- val compilerObj = connectToDaemon(compilerId, daemonOptions, errStream) ?: return null // no registry - no daemon running -- return compilerObj as? CompileService ?: -- throw ClassCastException(""Unable to cast compiler service, actual class received: ${compilerObj.javaClass}"") -+ -+ public fun compile(compiler: CompileService, args: Array, out: OutputStream): Int { -+ -+ val outStrm = RemoteOutputStreamServer(out) -+ try { -+ return compiler.remoteCompile(args, outStrm, CompileService.OutputFormat.PLAIN, outStrm) - } -+ finally { -+ outStrm.disconnect() ++ private fun markFunctionLineNumber() { ++ if (irFunction.origin == JvmLoweredDeclarationOrigin.CLASS_STATIC_INITIALIZER) { ++ return + } -+ } ++ if (irFunction is IrConstructor && irFunction.isPrimary) {","This method called after function body generation (irFunction.body!!.accept(this, info)). Should we use markLineNumber(startOffset = FALSE)?","Nit: can you move this to a separate method, so that it can be s" +345,"@@ -141,7 +139,7 @@ private class ToArrayLowering(private val context: JvmBackendContext) : ClassLow + toArrayName, + Visibilities.PUBLIC, + Modality.OPEN, +- returnType = irBuiltIns.arrayClass.typeWith(irBuiltIns.anyType), ++ returnType = irBuiltIns.arrayClass.typeWith(irBuiltIns.anyNType),",Could we extract nullability information from collection type?,shouldn't this be `irBuiltIns.anyTypeN`? +346,"@@ -141,7 +185,63 @@ public open class KotlinCompile(): AbstractCompile() { + } + } -- private fun connectToDaemon(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): Remote? { -- try { -- val daemon = LocateRegistry.getRegistry(""localhost"", daemonOptions.port) -- ?.lookup(COMPILER_SERVICE_RMI_NAME) -- if (daemon != null) -- return daemon -- errStream.println(""[daemon client] daemon not found"") -- } -- catch (e: ConnectException) { -- errStream.println(""[daemon client] cannot connect to registry: "" + (e.getCause()?.getMessage() ?: e.getMessage() ?: ""unknown exception"")) -- // ignoring it - processing below -- } -- return null +-public open class KDoc(): SourceTask() { ++public open class Kotlin2JsCompile() : AbstractKotlinCompile() { ++ override val compiler = K2JSCompiler() + -+ // TODO: remove jvmStatic after all use sites will switch to kotlin -+ jvmStatic -+ public fun incrementalCompile(compiler: CompileService, args: Array, caches: Map, compilerOut: OutputStream, daemonOut: OutputStream): Int { ++ override fun createBlankArgs(): K2JSCompilerArguments = K2JSCompilerArguments() + -+ val compilerOutStreamServer = RemoteOutputStreamServer(compilerOut) -+ val daemonOutStreamServer = RemoteOutputStreamServer(daemonOut) -+ val cacheServers = hashMapOf() -+ try { -+ caches.mapValuesTo(cacheServers, { RemoteIncrementalCacheServer(it.getValue()) }) -+ return compiler.remoteIncrementalCompile(args, cacheServers, compilerOutStreamServer, CompileService.OutputFormat.XML, daemonOutStreamServer) -+ } -+ finally { -+ cacheServers.forEach { it.getValue().disconnect() } -+ compilerOutStreamServer.disconnect() -+ daemonOutStreamServer.disconnect() - } -+ } ++ public fun addLibraryFiles(vararg fs: String) {","I think we should extract all libraries from dependencies instead. +",The `K2JSCompiler` has nothing to do with this PR. +347,"@@ -142,7 +144,7 @@ fun compile( + val deserializedModuleFragments = sortedImmediateDependencies.map { + val moduleFile = File(it.klibPath, moduleHeaderFileName) +- deserializer.deserializeIrModuleHeader(depsDescriptors.getModuleDescriptor(it), moduleFile.readBytes(), File(it.klibPath), DeserializationStrategy.ONLY_REFERENCED) ++ deserializer.DeserializeIrModuleHeader(depsDescriptors.getModuleDescriptor(it))",deserializer.~D~deserializeIrModuleHeader,Move the `deserializer` call into `deserializeIrModuleHeader` me +348,"@@ -142,7 +176,7 @@ public inline fun > Map.mapKeysTo(destinatio + } -- private fun startDaemon(compilerId: CompilerId, daemonJVMOptions: DaemonJVMOptions, daemonOptions: DaemonOptions, errStream: PrintStream) { -- val javaExecutable = File(System.getProperty(""java.home""), ""bin"").let { -- val javaw = File(it, ""javaw.exe"") -- if (javaw.exists()) javaw -- else File(it, ""java"") -- } -- // TODO: add some specific environment variables to the cp and may be command line, to allow some specific startup configs -- val args = listOf(javaExecutable.absolutePath, -- ""-cp"", compilerId.compilerClasspath.joinToString(File.pathSeparator)) + -- daemonJVMOptions.mappers.flatMap { it.toArgs(""-"") } + -- COMPILER_DAEMON_CLASS_FQN + -- daemonOptions.mappers.flatMap { it.toArgs(COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX) } + -- compilerId.mappers.flatMap { it.toArgs(COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX) } -- errStream.println(""[daemon client] starting the daemon as: "" + args.joinToString("" "")) -- val processBuilder = ProcessBuilder(args).redirectErrorStream(true) -- // assuming daemon process is deaf and (mostly) silent, so do not handle streams -- val daemon = processBuilder.start() -- -- var isEchoRead = Semaphore(1) -- isEchoRead.acquire() -- -- val stdoutThread = -- thread { -- daemon.getInputStream() -- .reader() -- .forEachLine { -- if (daemonOptions.startEcho.isNotEmpty() && it.contains(daemonOptions.startEcho)) { -- isEchoRead.release() -- return@forEachLine -- } -- errStream.println(""[daemon] "" + it) -- } -- } -- try { -- // trying to wait for process -- if (daemonOptions.startEcho.isNotEmpty()) { -- errStream.println(""[daemon client] waiting for daemon to respond"") -- val succeeded = isEchoRead.tryAcquire(DAEMON_STARTUP_TIMEOUT_MS, TimeUnit.MILLISECONDS) -- if (!daemon.isAlive()) -- throw Exception(""Daemon terminated unexpectedly"") -- if (!succeeded) -- throw Exception(""Unable to get response from daemon in $DAEMON_STARTUP_TIMEOUT_MS ms"") -- } -- else -- // without startEcho defined waiting for max timeout -- Thread.sleep(DAEMON_STARTUP_TIMEOUT_MS) -- } -- finally { -- // assuming that all important output is already done, the rest should be routed to the log by the daemon itself -- if (stdoutThread.isAlive) -- // TODO: find better method to stop the thread, but seems it will require asynchronous consuming of the stream -- stdoutThread.stop() -+ data class ClientOptions( -+ public var stop: Boolean = false -+ ) : OptionsGroup { -+ override val mappers: List> -+ get() = listOf(BoolPropMapper(this, ::stop)) -+ } -+ -+ -+ jvmStatic public fun main(vararg args: String) { -+ val compilerId = CompilerId() -+ val daemonOptions = DaemonOptions() -+ val daemonLaunchingOptions = DaemonJVMOptions() -+ val clientOptions = ClientOptions() -+ val filteredArgs = args.asIterable().filterExtractProps(compilerId, daemonOptions, daemonLaunchingOptions, clientOptions, prefix = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX) -+ -+ if (!clientOptions.stop) { -+ if (compilerId.compilerClasspath.none()) { -+ // attempt to find compiler to use -+ System.err.println(""compiler wasn't explicitly specified, attempt to find appropriate jar"") -+ System.getProperty(""java.class.path"") -+ ?.split(File.pathSeparator) -+ ?.map { File(it).parentFile } -+ ?.distinct() -+ ?.map { -+ it?.walk() -+ ?.firstOrNull { it.name.equals(COMPILER_JAR_NAME, ignoreCase = true) } -+ } -+ ?.filterNotNull() -+ ?.firstOrNull() -+ ?.let { compilerId.compilerClasspath = listOf(it.absolutePath) } - } -- } -+ if (compilerId.compilerClasspath.none()) -+ throw IllegalArgumentException(""Cannot find compiler jar"") -+ else -+ println(""desired compiler classpath: "" + compilerId.compilerClasspath.joinToString(File.pathSeparator)) - -- public fun checkCompilerId(compiler: CompileService, localId: CompilerId, errStream: PrintStream): Boolean { -- val remoteId = compiler.getCompilerId() -- errStream.println(""[daemon client] remoteId = "" + remoteId.toString()) -- errStream.println(""[daemon client] localId = "" + localId.toString()) -- return (localId.compilerVersion.isEmpty() || localId.compilerVersion == remoteId.compilerVersion) && -- (localId.compilerClasspath.all { remoteId.compilerClasspath.contains(it) }) && -- (localId.compilerDigest.isEmpty() || remoteId.compilerDigest.isEmpty() || localId.compilerDigest == remoteId.compilerDigest) -+ compilerId.updateDigest() - } + /** +- * Puts all the entries into this [[MutableMap]] with the first value in the pair being the key and the second the value ++ * Puts all the entries into this [MutableMap] with the first value in the pair being the key and the second the value","""Puts given values"", and again value vs component for Pair. +",Not sure this is correct. It should be like `with the first valu +349,"@@ -143,6 +143,9 @@ public IntrinsicMethods(JvmTarget jvmTarget, boolean shouldThrowNpeOnExplicitEqu + declareIntrinsicFunction(FQ_NAMES.string, ""plus"", 1, new Concat()); + declareIntrinsicFunction(FQ_NAMES.string, ""get"", 1, new StringGetChar()); -- public fun connectToCompileService(compilerId: CompilerId, daemonJVMOptions: DaemonJVMOptions, daemonOptions: DaemonOptions, errStream: PrintStream, autostart: Boolean = true, checkId: Boolean = true): CompileService? { -- val service = connectToService(compilerId, daemonOptions, errStream) -- if (service != null) { -- if (!checkId || checkCompilerId(service, compilerId, errStream)) { -- errStream.println(""[daemon client] found the suitable daemon"") -- return service -- } -- errStream.println(""[daemon client] compiler identity don't match: "" + compilerId.mappers.flatMap { it.toArgs("""") }.joinToString("" "")) -- if (!autostart) return null; -- errStream.println(""[daemon client] shutdown the daemon"") -- service.shutdown() -- // TODO: find more reliable way -- Thread.sleep(1000) -- errStream.println(""[daemon client] daemon shut down correctly, restarting"") -+ val daemon = connectToCompileService(compilerId, daemonLaunchingOptions, daemonOptions, DaemonReportingTargets(out = System.out), autostart = !clientOptions.stop, checkId = !clientOptions.stop) -+ -+ if (daemon == null) { -+ if (clientOptions.stop) { -+ System.err.println(""No daemon found to shut down"") - } -- else { -- if (!autostart) return null; -- else errStream.println(""[daemon client] cannot connect to Compile Daemon, trying to start"") -+ else throw Exception(""Unable to connect to daemon"") -+ } -+ else when { -+ clientOptions.stop -> { -+ println(""Shutdown the daemon"") -+ daemon.shutdown() -+ println(""Daemon shut down successfully"") - } -+ else -> { -+ println(""Executing daemon compilation with args: "" + filteredArgs.joinToString("" "")) -+ val outStrm = RemoteOutputStreamServer(System.out) -+ try { -+ val memBefore = daemon.getUsedMemory() / 1024 -+ val startTime = System.nanoTime() -+ -+ val res = daemon.remoteCompile(filteredArgs.toArrayList().toTypedArray(), outStrm, CompileService.OutputFormat.PLAIN, outStrm) - -- startDaemon(compilerId, daemonJVMOptions, daemonOptions, errStream) -- errStream.println(""[daemon client] daemon started, trying to connect"") -- return connectToService(compilerId, daemonOptions, errStream) -+ val endTime = System.nanoTime() -+ println(""Compilation result code: $res"") -+ val memAfter = daemon.getUsedMemory() / 1024 -+ println(""Compilation time: "" + TimeUnit.NANOSECONDS.toMillis(endTime - startTime) + "" ms"") -+ println(""Used memory $memAfter (${""%+d"".format(memAfter - memBefore)} kb)"") -+ } -+ finally { -+ outStrm.disconnect() -+ } -+ } ++ intrinsicsMap.registerIntrinsic(TEXT_PACKAGE_FQ_NAME, FQ_NAMES.string, ""trimMargin"", 1, new TrimMargin());","We've discussed internally the idea to apply the intrinsic unconditionally and figured that it might lead to compatibility problems in case we decide to change the behavior of `trimMargin`/`trimIndent` on some corner case in a future release. It seems that these kinds of problems will only arise if the compiler of version X is compiling code against standard library of version Y where Y > X: the user expects behavior of version Y at runtime, but will actually observe behavior of version X because that's what was executed in the compiler at compilation time. + +Therefore we'd like to restrict these intrinsics to be applicable only if the version of the standard library in dependencies is _not greater_ than the version of the compiler itself. This can be achieved by checking if the API version (can be obtained via `languageVersionSettings.apiVersion` at the call site) is <= than the version of the standard library in the runtime of the compiler (can be obtained via `KotlinVersion.CURRENT`). (Sorry if this sounds confusing, I can do it myself if it's unclear, just wanted to notify you that we'd like it to work that way -- maybe you have some other related concerns.)",Why did you add `intrinsicsMap` as an intrinsic? AFAIK `declareI +350,"@@ -145,10 +145,22 @@ private static JetElement overrideFunction(Project project, JetFile file, Simple + StringBuilder bodyBuilder = new StringBuilder(""override fun ""); + bodyBuilder.append(descriptor.getName()); + bodyBuilder.append(""(""); ++ boolean isAbstractFun = descriptor.getModality() == Modality.ABSTRACT; ++ StringBuilder delegationBuilder = new StringBuilder();","It's not very critical now, but I think that your decision to barter flat and simple structure of this method to one more iteration over parameters collection was a bad deal. Now it's really difficult to understand the logic of filling StringBuilder variables. +",`isAbstractFun` -> `isAbstract` +351,"@@ -146,4 +146,4 @@ public enum class InvocationKind { + @InlineOnly + @SinceKotlin(""1.3"") + @Suppress(""UNUSED_PARAMETER"") +-public inline fun contract(builder: ContractBuilder.() -> Unit) { }",Please revert unrelated line ending change,Why did you remove this method? Was it unused? +352,"@@ -146,6 +145,7 @@ val jvmPhases = namedIrFilePhase( + collectionStubMethodLowering then + bridgePhase then + jvmOverloadsAnnotationPhase then ++ jvmDefaultConstructorPhase then",Please add 'jvmOverloadsAnnotationPhase' prerequisite for jvmDefaultConstructorPhase phase,"Hmmm, why is this part of this PR?" +353,"@@ -147,20 +148,33 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat } -+ } + } -- public fun shutdownCompileService(daemonOptions: DaemonOptions): Unit { -- KotlinCompilerClient.connectToCompileService(CompilerId(), DaemonJVMOptions(), daemonOptions, System.out, autostart = false, checkId = false) -- ?.shutdown() -+ // --- Implementation --------------------------------------- ++ private fun IrStatementsBuilder<*>.generateIrIfNull(","I'm unsure if this has consequences for non-jvm backends? On the JVM, introducing a temporary for constants makes little sense as the constant can just be reloaded. Is that a reasonable assumption for the other backends as well?",doesn't look like this method is c +354,"@@ -148,4 +149,19 @@ class ReplaceCallWithBinaryOperatorInspection : AbstractApplicabilityBasedInspec + else -> OperatorConventions.BINARY_OPERATION_NAMES.inverse()[identifier] + } + } + -+ val verboseReporting = System.getProperty(COMPILE_DAEMON_VERBOSE_REPORT_PROPERTY) != null ++ private fun KtDotQualifiedExpression.isFloatingPointNumberEquals(): Boolean {","This implementation is very strange. You focus here on a given example, but there are some simpler cases which probably will not be detected by this implementation correctly. I'd suggest you should find (via `resolveToCall()`) type of `equals` receiver and type of `equals` argument, and in case at least one of them is FP type (`Float` or `Double`) and another of them is numeric type (FP or `Byte`, `Short`, `Int`, `Long`), the function should return `true`, otherwise `false`.",This does not look like it is inte +355,"@@ -148,6 +148,10 @@ You can now run the various Run/Debug Configurations such as + * All Compiler Tests + * All IDEA Plugin Tests + ++### Running specific generated tests + -+ fun DaemonReportingTargets.report(category: DaemonReportCategory, message: String, source: String = ""daemon client"") { -+ if (category == DaemonReportCategory.DEBUG && !verboseReporting) return -+ out?.println(""[$source] ${category.name()}: $message"") -+ messages?.add(DaemonReportMessage(category, ""[$source] $message"")) -+ } ++If you need to debug a specific generated test ensure that you have the `Working directory` your IntellJ run configuration set","> generated test ensure that + +* generated test`,` ensure that + +> you have the \`Working directory\` your IntellJ + +* you have the \`Working directory\` `in` your Intell`i`J + +> If you don't every test + +If you don't`,` every test",I'm guessing this is a leftover? +356,"@@ -148,6 +148,10 @@ You can now run the various Run/Debug Configurations such as + * All Compiler Tests + * All IDEA Plugin Tests + ++### Running specific generated tests + -+ private fun tryFindDaemon(registryDir: File, compilerId: CompilerId, reportingTargets: DaemonReportingTargets): CompileService? { -+ val classPathDigest = compilerId.compilerClasspath.map { File(it).absolutePath }.distinctStringsDigest() -+ val daemons = registryDir.walk() -+ .map { Pair(it, makeRunFilenameRegex(digest = classPathDigest, port = ""(\\d+)"").match(it.name)?.groups?.get(1)?.value?.toInt() ?: 0) } -+ .filter { it.second != 0 } -+ .map { -+ reportingTargets.report(DaemonReportCategory.DEBUG, ""found suitable daemon on port ${it.second}, trying to connect"") -+ val daemon = tryConnectToDaemon(it.second, reportingTargets) -+ // cleaning orphaned file; note: daemon should shut itself down if it detects that the run file is deleted -+ if (daemon == null && !it.first.delete()) { -+ reportingTargets.report(DaemonReportCategory.INFO, ""WARNING: unable to delete seemingly orphaned file '${it.first.absolutePath}', cleanup recommended"") -+ } -+ daemon -+ } -+ .filterNotNull() -+ .toList() -+ return when (daemons.size()) { -+ 0 -> null -+ 1 -> daemons.first() -+ else -> throw IllegalStateException(""Multiple daemons serving the same compiler, reset with the cleanup required"") -+ // TODO: consider implementing automatic recovery instead, e.g. getting the youngest or least used daemon and shut down others - } -+ } ++If you need to debug a specific generated test ensure that you have the `Working directory` your IntellJ run configuration set ++to the root directory of this project. If you don't every test you try to run will fail with a `No such file or directory` exception.","Basically change the test run config from `$MODULE_DIR$` to `$PROJECT_DIR$`, right? +Could we maybe fix that, instead of explaining, i.e. by setting the `JUnit default run config` to it?",I don't think this is specific to +357,"@@ -148,7 +148,7 @@ abstract class AbstractKotlinCompile() : AbstractKo + protected val additionalClasspath = arrayListOf() -- public fun shutdownCompileService(): Unit { -- shutdownCompileService(DaemonOptions()) -+ private fun tryConnectToDaemon(port: Int, reportingTargets: DaemonReportingTargets): CompileService? { -+ try { -+ val daemon = LocateRegistry.getRegistry(loopbackAddrName, port) -+ ?.lookup(COMPILER_SERVICE_RMI_NAME) -+ if (daemon != null) -+ return daemon as? CompileService ?: -+ throw ClassCastException(""Unable to cast compiler service, actual class received: ${daemon.javaClass}"") -+ reportingTargets.report(DaemonReportCategory.EXCEPTION, ""daemon not found"") -+ } -+ catch (e: ConnectException) { -+ reportingTargets.report(DaemonReportCategory.EXCEPTION, ""cannot connect to registry: "" + (e.getCause()?.getMessage() ?: e.getMessage() ?: ""unknown exception"")) -+ // ignoring it - processing below - } -+ return null -+ } + @get:Internal // classpath already participates in the checks +- protected val compileClasspath: Iterable","We'd like to keep the visibility of this `val` restricted, maybe use `internal` if it is not needed outside the module.",Please annotate with `@VisibleForT +358,"@@ -149,6 +249,10 @@ open class KotlinUField( -- public fun compile(compiler: CompileService, args: Array, out: OutputStream): Int { + override val psi = javaPsi -- val outStrm = RemoteOutputStreamServer(out) -- try { -- return compiler.remoteCompile(args, outStrm, CompileService.OutputFormat.PLAIN) -- } -- finally { -- outStrm.disconnect() -- } -+ private fun startDaemon(compilerId: CompilerId, daemonJVMOptions: DaemonJVMOptions, daemonOptions: DaemonOptions, reportingTargets: DaemonReportingTargets) { -+ val javaExecutable = File(System.getProperty(""java.home""), ""bin"").let { -+ val javaw = File(it, ""javaw.exe"") -+ // TODO: doesn't seem reliable enough, consider more checks if OS is of windows flavor, etc. -+ if (javaw.exists() && javaw.isFile && javaw.canExecute()) javaw else File(it, ""java"") - } -+ val args = listOf(javaExecutable.absolutePath, -+ ""-cp"", compilerId.compilerClasspath.joinToString(File.pathSeparator)) + -+ daemonJVMOptions.mappers.flatMap { it.toArgs(""-"") } + -+ COMPILER_DAEMON_CLASS_FQN + -+ daemonOptions.mappers.flatMap { it.toArgs(COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX) } + -+ compilerId.mappers.flatMap { it.toArgs(COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX) } -+ reportingTargets.report(DaemonReportCategory.DEBUG, ""starting the daemon as: "" + args.joinToString("" "")) -+ val processBuilder = ProcessBuilder(args).redirectErrorStream(true) -+ // assuming daemon process is deaf and (mostly) silent, so do not handle streams -+ val daemon = processBuilder.start() - -- public fun incrementalCompile(compiler: CompileService, args: Array, caches: Map, out: OutputStream): Int { -+ var isEchoRead = Semaphore(1) -+ isEchoRead.acquire() - -- val outStrm = RemoteOutputStreamServer(out) -- val cacheServers = hashMapOf() -- try { -- caches.mapValuesTo(cacheServers, { RemoteIncrementalCacheServer( it.getValue()) }) -- return compiler.remoteIncrementalCompile(args, cacheServers, outStrm, CompileService.OutputFormat.XML) -+ val stdoutThread = -+ thread { -+ daemon.inputStream -+ .reader() -+ .forEachLine { -+ if (daemonOptions.runFilesPath.isNotEmpty() && it.contains(daemonOptions.runFilesPath)) { -+ isEchoRead.release() -+ return@forEachLine -+ } -+ reportingTargets.report(DaemonReportCategory.DEBUG, it, ""daemon"") -+ } -+ } -+ try { -+ // trying to wait for process -+ val daemonStartupTimeout = System.getProperty(COMPILE_DAEMON_STARTUP_TIMEOUT_PROPERTY)?.let { -+ try { -+ it.toLong() -+ } -+ catch (e: Exception) { -+ reportingTargets.report(DaemonReportCategory.INFO, ""unable to interpret $COMPILE_DAEMON_STARTUP_TIMEOUT_PROPERTY property ('$it'); using default timeout $DAEMON_DEFAULT_STARTUP_TIMEOUT_MS ms"") -+ null -+ } -+ } ?: DAEMON_DEFAULT_STARTUP_TIMEOUT_MS -+ if (daemonOptions.runFilesPath.isNotEmpty()) { -+ val succeeded = isEchoRead.tryAcquire(daemonStartupTimeout, TimeUnit.MILLISECONDS) -+ if (!daemon.isAlive()) -+ throw Exception(""Daemon terminated unexpectedly"") -+ if (!succeeded) -+ throw Exception(""Unable to get response from daemon in $daemonStartupTimeout ms"") - } -- finally { -- cacheServers.forEach { it.getValue().disconnect() } -- outStrm.disconnect() -+ else -+ // without startEcho defined waiting for max timeout -+ Thread.sleep(daemonStartupTimeout) -+ } -+ finally { -+ // assuming that all important output is already done, the rest should be routed to the log by the daemon itself -+ if (stdoutThread.isAlive) { -+ // TODO: find better method to stop the thread, but seems it will require asynchronous consuming of the stream -+ stdoutThread.stop() - } ++ override fun acceptsAnnotationTarget(target: AnnotationUseSiteTarget?): Boolean = ++ target == AnnotationUseSiteTarget.FIELD || ++ (sourcePsi is KtProperty) && (target == null || target == AnnotationUseSiteTarget.PROPERTY)",The `@delegate:` target also maps to fields.,I think you can simplify this to ` +359,"@@ -149,7 +150,7 @@ class MemoizedInlineClassReplacements { + } + + private fun buildReplacement(function: IrFunction, body: IrFunctionImpl.() -> Unit) = +- buildFun { ++ buildFunWithDescriptor(function.descriptor) {",Could you clarify why descriptor is reuqired here?,The `function.descriptor` is not a +360,"@@ -15,3 +17,20 @@ public static void runTest(doGenerateParamAssertions a) { + throw new AssertionError(""Fail: IllegalArgumentException expected""); + } + } ++ ++// FILE: B.kt ++import test.doGenerateParamAssertions as C","Would be nice to rename the class itself now that it's possible. Previously the Java class was named this way because its file was compiled directly by javac, but box tests copy everything to tmpdir with new names, so we can use the short name for convenience","Unrelated to this PR, but this tes" +361,"@@ -15,6 +15,7 @@ public abstract class Mine : java.util.AbstractList { + public open /*fake_override*/ fun clear(): kotlin.Unit + public open /*fake_override*/ fun contains(/*0*/ T!): kotlin.Boolean + public open /*fake_override*/ fun containsAll(/*0*/ kotlin.collections.Collection): kotlin.Boolean ++ public open /*fake_override*/ fun forEach(/*0*/ java.util.function.Consumer!): kotlin.Unit","You'd better not to change existing tests, but to create a new test group with the same test data and your flag enabled.",You might be able to use `java.uti +362,"@@ -151,15 +156,19 @@ abstract class AbstractWriteSignatureTest : CodegenTestCase() { } -+ } -- data class ClientOptions( -- public var stop: Boolean = false -- ) : OptionsGroup { -- override val mappers: List> -- get() = listOf( BoolPropMapper(this, ::stop)) -- } + fun addClassExpectation(name: String, jvmSignature: String?, genericSignature: String) { +- classExpectations.add(SignatureExpectation(""class: $name"", name, jvmSignature, genericSignature)) ++ classExpectations.add(SignatureExpectation(true,""class: $name"", name, jvmSignature, genericSignature))",Please reformat here and below,What does this change do? +363,"@@ -151,7 +185,7 @@ public fun MutableMap.putAll(vararg values: Pair): Unit { + } + + /** +- * Puts all the entries into this [[MutableMap]] with the first value in the pair being the key and the second the value ++ * Puts all the entries into this [MutableMap] with the first value in the pair being the key and the second the value","""Puts elements of the given collection"" +",Not sure this is correct. It shoul +364,"@@ -152,23 +147,14 @@ class IrExpressionLambdaImpl( + } -- jvmStatic public fun main(vararg args: String) { -- val compilerId = CompilerId() -- val daemonOptions = DaemonOptions() -- val daemonLaunchingOptions = DaemonJVMOptions() -- val clientOptions = ClientOptions() -- val filteredArgs = args.asIterable().filterExtractProps(compilerId, daemonOptions, daemonLaunchingOptions, clientOptions, prefix = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX) -- -- if (!clientOptions.stop) { -- if (compilerId.compilerClasspath.none()) { -- // attempt to find compiler to use -- println(""compiler wasn't explicitly specified, attempt to find appropriate jar"") -- System.getProperty(""java.class.path"") -- ?.split(File.pathSeparator) -- ?.map { File(it).parent } -- ?.distinct() -- ?.map { -- it?.walk() -- ?.firstOrNull { it.getName().equals(COMPILER_JAR_NAME, ignoreCase = true) } -- } -- ?.filterNotNull() -- ?.firstOrNull() -- ?.let { compilerId.compilerClasspath = listOf(it.absolutePath) } -- } -- if (compilerId.compilerClasspath.none()) -- throw IllegalArgumentException(""Cannot find compiler jar"") -- else -- println(""desired compiler classpath: "" + compilerId.compilerClasspath.joinToString(File.pathSeparator)) -+ private fun checkCompilerId(compiler: CompileService, localId: CompilerId): Boolean { -+ val remoteId = compiler.getCompilerId() -+ return (localId.compilerVersion.isEmpty() || localId.compilerVersion == remoteId.compilerVersion) && -+ (localId.compilerClasspath.all { remoteId.compilerClasspath.contains(it) }) && -+ (localId.compilerDigest.isEmpty() || remoteId.compilerDigest.isEmpty() || localId.compilerDigest == remoteId.compilerDigest) -+ } + companion object { +- private var counter: Int = 123//TODO: pass proper type ++ private var counter: Int = 1//TODO: pass proper type + } -- compilerId.updateDigest() -+ -+ class FileBasedLock(compilerId: CompilerId, daemonOptions: DaemonOptions) { -+ private val lockFile: File = -+ File(daemonOptions.runFilesPath,","do we need to keep them in home dir? can we use tempdir instead to eliminate possible issues caused by NFS-backed homedir, etc ? -",Please add the name of the variable to -700,"@@ -18,246 +18,376 @@ package org.jetbrains.kotlin.rmi.kotlinr - - import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache - import org.jetbrains.kotlin.rmi.* --import java.io.File --import java.io.OutputStream --import java.io.PrintStream -+import java.io.* - import java.rmi.ConnectException --import java.rmi.Remote - import java.rmi.registry.LocateRegistry - import java.util.concurrent.Semaphore - import java.util.concurrent.TimeUnit - import kotlin.concurrent.thread - --fun Process.isAlive() = -+ -+public object KotlinCompilerClient { -+ -+ val DAEMON_DEFAULT_STARTUP_TIMEOUT_MS = 10000L -+ val DAEMON_CONNECT_CYCLE_ATTEMPTS = 3 -+ -+ -+ // TODO: remove jvmStatic after all use sites will switch to kotlin -+ jvmStatic -+ public fun connectToCompileService(compilerId: CompilerId, -+ daemonJVMOptions: DaemonJVMOptions, -+ daemonOptions: DaemonOptions, -+ reportingTargets: DaemonReportingTargets, -+ autostart: Boolean = true, -+ checkId: Boolean = true -+ ): CompileService? { -+ -+ var attempts = 0 -+ var fileLock: FileBasedLock? = null - try { -- this.exitValue() -- false -+ while (attempts++ < DAEMON_CONNECT_CYCLE_ATTEMPTS) { -+ val service = tryFindDaemon(File(daemonOptions.runFilesPath), compilerId, reportingTargets) -+ if (service != null) { -+ if (!checkId || checkCompilerId(service, compilerId)) { -+ reportingTargets.report(DaemonReportCategory.DEBUG, ""connected to the daemon"") -+ return service -+ } -+ reportingTargets.report(DaemonReportCategory.DEBUG, ""compiler identity don't match: "" + compilerId.mappers.flatMap { it.toArgs("""") }.joinToString("" "")) -+ if (!autostart) return null -+ reportingTargets.report(DaemonReportCategory.DEBUG, ""shutdown the daemon"") -+ service.shutdown() -+ // TODO: find more reliable way -+ Thread.sleep(1000) -+ reportingTargets.report(DaemonReportCategory.DEBUG, ""daemon shut down correctly, restarting search"") -+ } -+ else { -+ if (!autostart) return null -+ reportingTargets.report(DaemonReportCategory.DEBUG, ""no suitable daemon found, starting a new one"") -+ } -+ -+ if (fileLock == null || !fileLock.isLocked()) { -+ File(daemonOptions.runFilesPath).mkdirs() -+ fileLock = FileBasedLock(compilerId, daemonOptions) -+ // need to check the daemons again here, because of possible racing conditions -+ // note: the algorithm could be simpler if we'll acquire lock right from the beginning, but it may be costly -+ attempts-- -+ } -+ else { -+ startDaemon(compilerId, daemonJVMOptions, daemonOptions, reportingTargets) -+ reportingTargets.report(DaemonReportCategory.DEBUG, ""daemon started, trying to resolve"") -+ } -+ } - } -- catch (e: IllegalThreadStateException) { -- true -+ catch (e: Exception) { -+ reportingTargets.report(DaemonReportCategory.EXCEPTION, e.toString()) -+ } -+ finally { -+ fileLock?.release() +- override val lambdaClassType: Type = Type.getObjectType(""test${counter++}"") ++ override val lambdaClassType: Type = Type.getObjectType(""$typePrefix\$lambda-${counter++}"")",Maybe best to use precalculated old name ```codegen.context.getLocalClassInfo(reference)```,the indent is wrong here (should b +365,"@@ -1520,6 +1520,15 @@ + language=""kotlin"" + /> + ++ + ++ { +- return setOf(codegen.irFunction.name.asString()) ++ val name = codegen.irFunction.name.asString() ++ if (name == INVOKE_SUSPEND_METHOD_NAME) {",Should this check for invoke as well as invokeSuspend? ,"Please don't do this - it should be a constant somewhere, and not a magic value." +369,"@@ -155,7 +155,7 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain + + if (functions.size != 1) { + val allMembers = members.joinToString(""\n"") { descriptor -> +- DescriptorRenderer.DEBUG_TEXT.render(descriptor) + "" | "" + RuntimeTypeMapper.mapSignature(descriptor) ++ DescriptorRenderer.DEBUG_TEXT.render(descriptor) + "" | "" + RuntimeTypeMapper.mapSignature(descriptor).asString()",Thanks for fixing this. Please also fix the similar code above where `RuntimeTypeMapper.mapPropertySignature` is invoked,"This should be fine to keep, but remove the 'asString' method." +370,"@@ -155,7 +161,31 @@ class KotlinAddImportAction internal constructor( + return true } -+ return null -+ } --public class KotlinCompilerClient { +- JBPopupFactory.getInstance().createListPopup(getVariantSelectionPopup()).showInBestPositionFor(editor) ++ val popup = object : ListPopupImpl(getVariantSelectionPopup()) { ++ @Suppress(""UNCHECKED_CAST"")",Thoughts on how to avoid this?,I'm not sure why we need to suppress this. Can you explain? +371,"@@ -1554,6 +1554,11 @@ + Kotlin + -- companion object { -+ public fun shutdownCompileService(daemonOptions: DaemonOptions): Unit { -+ KotlinCompilerClient.connectToCompileService(CompilerId(), DaemonJVMOptions(), daemonOptions, DaemonReportingTargets(out = System.out), autostart = false, checkId = false) -+ ?.shutdown() -+ } ++ ","Really inspection is enough here. Since IDEA 2016.3, we have `INFORMATION` level for inspection (= No highlighting, only fix), so separate intentions are not necessary in this situation.",Can we remove the `intentionAction` component here? +372,"@@ -157,7 +157,7 @@ inline fun buildFun(builder: IrFunctionBuilder.() -> Unit): IrFunctionImpl = + buildFun() + } -- val DAEMON_STARTUP_TIMEOUT_MS = 10000L +-inline fun IrDeclarationContainer.addFunction(builder: IrFunctionBuilder.() -> Unit): IrSimpleFunction = ++inline fun IrDeclarationContainer.addFunction(builder: IrFunctionBuilder.() -> Unit): IrFunctionImpl =",Is this change is neccessery for pr?,Shouldn't this be `IrFunctionImpl`? +373,"@@ -158,11 +193,7 @@ private fun ModuleInfo.findNativeStdlib(project: Project): NativeLibraryInfo? = -- private fun connectToService(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): CompileService? { -+ public fun shutdownCompileService(): Unit { -+ shutdownCompileService(DaemonOptions()) -+ } + class NativeLibraryInfo(project: Project, library: Library, root: File) : LibraryInfo(project, library) { -- val compilerObj = connectToDaemon(compilerId, daemonOptions, errStream) ?: return null // no registry - no daemon running -- return compilerObj as? CompileService ?: -- throw ClassCastException(""Unable to cast compiler service, actual class received: ${compilerObj.javaClass}"") -+ -+ public fun compile(compiler: CompileService, args: Array, out: OutputStream): Int { -+ -+ val outStrm = RemoteOutputStreamServer(out) -+ try { -+ return compiler.remoteCompile(args, outStrm, CompileService.OutputFormat.PLAIN, outStrm) - } -+ finally { -+ outStrm.disconnect() -+ } -+ } +- private val nativeLibrary = createKonanLibrary( +- root, +- KOTLIN_NATIVE_CURRENT_ABI_VERSION, +- metadataReader = CachingIdeMetadataReaderImpl +- ) ++ private val nativeLibrary = createKotlinLibrary(root)",But here `CachingIdeKonanLibraryMetadataLoader` must be present in order to cache contents of any KLIB loaded in IDE.,Why do we need to pass `cachingIdeMetadataReaderImpl` here? Can't we just use `c +374,"@@ -158,6 +146,12 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL + }) + } -- private fun connectToDaemon(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): Remote? { -- try { -- val daemon = LocateRegistry.getRegistry(""localhost"", daemonOptions.port) -- ?.lookup(COMPILER_SERVICE_RMI_NAME) -- if (daemon != null) -- return daemon -- errStream.println(""[daemon client] daemon not found"") -- } -- catch (e: ConnectException) { -- errStream.println(""[daemon client] cannot connect to registry: "" + (e.getCause()?.getMessage() ?: e.getMessage() ?: ""unknown exception"")) -- // ignoring it - processing below -- } -- return null -+ -+ // TODO: remove jvmStatic after all use sites will switch to kotlin -+ jvmStatic -+ public fun incrementalCompile(compiler: CompileService, args: Array, caches: Map, compilerOut: OutputStream, daemonOut: OutputStream): Int { ++ private val arrayGetFun =",@pyos Please make these declaration lazy: this will allow to avoid overhead with loading lazy data from IrLazyClass when it is not necessery.,What is this for? +375,"@@ -158,6 +157,7 @@ protected void blackBox() { + Method method = aClass.getMethod(""box""); + String r = (String) method.invoke(null); + assertEquals(""OK"", r); ++ System.out.println(generateToText());","I beleive this was commited erroneously. +",This looks like a debug statement. +376,"@@ -158,6 +162,23 @@ class IrExpressionLambdaImpl( + override val invokeMethodDescriptor: FunctionDescriptor = function.descriptor + + override val hasDispatchReceiver: Boolean = false + -+ val compilerOutStreamServer = RemoteOutputStreamServer(compilerOut) -+ val daemonOutStreamServer = RemoteOutputStreamServer(daemonOut) -+ val cacheServers = hashMapOf() -+ try { -+ caches.mapValuesTo(cacheServers, { RemoteIncrementalCacheServer(it.getValue()) }) -+ return compiler.remoteIncrementalCompile(args, cacheServers, compilerOutStreamServer, CompileService.OutputFormat.XML, daemonOutStreamServer) -+ } -+ finally { -+ cacheServers.forEach { it.getValue().disconnect() } -+ compilerOutStreamServer.disconnect() -+ daemonOutStreamServer.disconnect() - } -+ } ++ override fun generateLambdaBody(sourceCompiler: SourceCompilerForInline, reifiedTypeInliner: ReifiedTypeInliner) { ++ require(sourceCompiler is IrSourceCompilerForInline) ++ lateinit var methodNode: MethodNode",Is it possible to move this logic and related one from ExpressionLambda to sourceCompiler? Seems all adapter related logic could be shared there,Is this necessary? +377,"@@ -1592,6 +1592,11 @@ + Kotlin + ++ ++ org.jetbrains.kotlin.idea.intentions.IndentRawStringIntention ++ Kotlin ++ ++","For future PRs: we have now ""branch"" files `plugin.xml.172` etc. that also should be modified if you are modifying `plugin.xml`.",Why do we need a new intention action for this? +378,"@@ -16,10 +16,25 @@ -- private fun startDaemon(compilerId: CompilerId, daemonJVMOptions: DaemonJVMOptions, daemonOptions: DaemonOptions, errStream: PrintStream) { -- val javaExecutable = File(System.getProperty(""java.home""), ""bin"").let { -- val javaw = File(it, ""javaw.exe"") -- if (javaw.exists()) javaw -- else File(it, ""java"") -- } -- // TODO: add some specific environment variables to the cp and may be command line, to allow some specific startup configs -- val args = listOf(javaExecutable.absolutePath, -- ""-cp"", compilerId.compilerClasspath.joinToString(File.pathSeparator)) + -- daemonJVMOptions.mappers.flatMap { it.toArgs(""-"") } + -- COMPILER_DAEMON_CLASS_FQN + -- daemonOptions.mappers.flatMap { it.toArgs(COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX) } + -- compilerId.mappers.flatMap { it.toArgs(COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX) } -- errStream.println(""[daemon client] starting the daemon as: "" + args.joinToString("" "")) -- val processBuilder = ProcessBuilder(args).redirectErrorStream(true) -- // assuming daemon process is deaf and (mostly) silent, so do not handle streams -- val daemon = processBuilder.start() -- -- var isEchoRead = Semaphore(1) -- isEchoRead.acquire() -- -- val stdoutThread = -- thread { -- daemon.getInputStream() -- .reader() -- .forEachLine { -- if (daemonOptions.startEcho.isNotEmpty() && it.contains(daemonOptions.startEcho)) { -- isEchoRead.release() -- return@forEachLine -- } -- errStream.println(""[daemon] "" + it) -- } -- } -- try { -- // trying to wait for process -- if (daemonOptions.startEcho.isNotEmpty()) { -- errStream.println(""[daemon client] waiting for daemon to respond"") -- val succeeded = isEchoRead.tryAcquire(DAEMON_STARTUP_TIMEOUT_MS, TimeUnit.MILLISECONDS) -- if (!daemon.isAlive()) -- throw Exception(""Daemon terminated unexpectedly"") -- if (!succeeded) -- throw Exception(""Unable to get response from daemon in $DAEMON_STARTUP_TIMEOUT_MS ms"") -- } -- else -- // without startEcho defined waiting for max timeout -- Thread.sleep(DAEMON_STARTUP_TIMEOUT_MS) -- } -- finally { -- // assuming that all important output is already done, the rest should be routed to the log by the daemon itself -- if (stdoutThread.isAlive) -- // TODO: find better method to stop the thread, but seems it will require asynchronous consuming of the stream -- stdoutThread.stop() -+ data class ClientOptions( -+ public var stop: Boolean = false -+ ) : OptionsGroup { -+ override val mappers: List> -+ get() = listOf(BoolPropMapper(this, ::stop)) -+ } -+ -+ -+ jvmStatic public fun main(vararg args: String) { -+ val compilerId = CompilerId() -+ val daemonOptions = DaemonOptions() -+ val daemonLaunchingOptions = DaemonJVMOptions() -+ val clientOptions = ClientOptions() -+ val filteredArgs = args.asIterable().filterExtractProps(compilerId, daemonOptions, daemonLaunchingOptions, clientOptions, prefix = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX) -+ -+ if (!clientOptions.stop) { -+ if (compilerId.compilerClasspath.none()) { -+ // attempt to find compiler to use -+ System.err.println(""compiler wasn't explicitly specified, attempt to find appropriate jar"") -+ System.getProperty(""java.class.path"") -+ ?.split(File.pathSeparator) -+ ?.map { File(it).parentFile } -+ ?.distinct() -+ ?.map { -+ it?.walk() -+ ?.firstOrNull { it.name.equals(COMPILER_JAR_NAME, ignoreCase = true) } -+ } -+ ?.filterNotNull() -+ ?.firstOrNull() -+ ?.let { compilerId.compilerClasspath = listOf(it.absolutePath) } - } -- } -+ if (compilerId.compilerClasspath.none()) -+ throw IllegalArgumentException(""Cannot find compiler jar"") -+ else -+ println(""desired compiler classpath: "" + compilerId.compilerClasspath.joinToString(File.pathSeparator)) - -- public fun checkCompilerId(compiler: CompileService, localId: CompilerId, errStream: PrintStream): Boolean { -- val remoteId = compiler.getCompilerId() -- errStream.println(""[daemon client] remoteId = "" + remoteId.toString()) -- errStream.println(""[daemon client] localId = "" + localId.toString()) -- return (localId.compilerVersion.isEmpty() || localId.compilerVersion == remoteId.compilerVersion) && -- (localId.compilerClasspath.all { remoteId.compilerClasspath.contains(it) }) && -- (localId.compilerDigest.isEmpty() || remoteId.compilerDigest.isEmpty() || localId.compilerDigest == remoteId.compilerDigest) -+ compilerId.updateDigest() - } + package kotlin -- public fun connectToCompileService(compilerId: CompilerId, daemonJVMOptions: DaemonJVMOptions, daemonOptions: DaemonOptions, errStream: PrintStream, autostart: Boolean = true, checkId: Boolean = true): CompileService? { -- val service = connectToService(compilerId, daemonOptions, errStream) -- if (service != null) { -- if (!checkId || checkCompilerId(service, compilerId, errStream)) { -- errStream.println(""[daemon client] found the suitable daemon"") -- return service -- } -- errStream.println(""[daemon client] compiler identity don't match: "" + compilerId.mappers.flatMap { it.toArgs("""") }.joinToString("" "")) -- if (!autostart) return null; -- errStream.println(""[daemon client] shutdown the daemon"") -- service.shutdown() -- // TODO: find more reliable way -- Thread.sleep(1000) -- errStream.println(""[daemon client] daemon shut down correctly, restarting"") -+ val daemon = connectToCompileService(compilerId, daemonLaunchingOptions, daemonOptions, DaemonReportingTargets(out = System.out), autostart = !clientOptions.stop, checkId = !clientOptions.stop) -+ -+ if (daemon == null) { -+ if (clientOptions.stop) { -+ System.err.println(""No daemon found to shut down"") - } -- else { -- if (!autostart) return null; -- else errStream.println(""[daemon client] cannot connect to Compile Daemon, trying to start"") -+ else throw Exception(""Unable to connect to daemon"") -+ } -+ else when { -+ clientOptions.stop -> { -+ println(""Shutdown the daemon"") -+ daemon.shutdown() -+ println(""Daemon shut down successfully"") - } -+ else -> { -+ println(""Executing daemon compilation with args: "" + filteredArgs.joinToString("" "")) -+ val outStrm = RemoteOutputStreamServer(System.out) -+ try { -+ val memBefore = daemon.getUsedMemory() / 1024 -+ val startTime = System.nanoTime() -+ -+ val res = daemon.remoteCompile(filteredArgs.toArrayList().toTypedArray(), outStrm, CompileService.OutputFormat.PLAIN, outStrm) - -- startDaemon(compilerId, daemonJVMOptions, daemonOptions, errStream) -- errStream.println(""[daemon client] daemon started, trying to connect"") -- return connectToService(compilerId, daemonOptions, errStream) -+ val endTime = System.nanoTime() -+ println(""Compilation result code: $res"") -+ val memAfter = daemon.getUsedMemory() / 1024 -+ println(""Compilation time: "" + TimeUnit.NANOSECONDS.toMillis(endTime - startTime) + "" ms"") -+ println(""Used memory $memAfter (${""%+d"".format(memAfter - memBefore)} kb)"") -+ } -+ finally { -+ outStrm.disconnect() -+ } -+ } - } -+ } ++/** ++ * Represents a sequence of numbers or characters with a given start value, end value and step. ++ * This class is intended to be used in 'for' loops, and the JVM backend suggests efficient ++ * bytecode generation for it. Progressions with a step of -1 can be created through the ++ * `downTo` method on classes representing primitive types.","Link to `downTo` method. +",The enum value is `-1` and the enum value is `-1`. I think it would be clearer t +379,"@@ -16,10 +16,25 @@ -- public fun shutdownCompileService(daemonOptions: DaemonOptions): Unit { -- KotlinCompilerClient.connectToCompileService(CompilerId(), DaemonJVMOptions(), daemonOptions, System.out, autostart = false, checkId = false) -- ?.shutdown() -+ // --- Implementation --------------------------------------- -+ -+ val verboseReporting = System.getProperty(COMPILE_DAEMON_VERBOSE_REPORT_PROPERTY) != null -+ -+ fun DaemonReportingTargets.report(category: DaemonReportCategory, message: String, source: String = ""daemon client"") { -+ if (category == DaemonReportCategory.DEBUG && !verboseReporting) return -+ out?.println(""[$source] ${category.name()}: $message"") -+ messages?.add(DaemonReportMessage(category, ""[$source] $message"")) -+ } -+ -+ private fun tryFindDaemon(registryDir: File, compilerId: CompilerId, reportingTargets: DaemonReportingTargets): CompileService? { -+ val classPathDigest = compilerId.compilerClasspath.map { File(it).absolutePath }.distinctStringsDigest() -+ val daemons = registryDir.walk() -+ .map { Pair(it, makeRunFilenameRegex(digest = classPathDigest, port = ""(\\d+)"").match(it.name)?.groups?.get(1)?.value?.toInt() ?: 0) } -+ .filter { it.second != 0 } -+ .map { -+ reportingTargets.report(DaemonReportCategory.DEBUG, ""found suitable daemon on port ${it.second}, trying to connect"") -+ val daemon = tryConnectToDaemon(it.second, reportingTargets) -+ // cleaning orphaned file; note: daemon should shut itself down if it detects that the run file is deleted -+ if (daemon == null && !it.first.delete()) { -+ reportingTargets.report(DaemonReportCategory.INFO, ""WARNING: unable to delete seemingly orphaned file '${it.first.absolutePath}', cleanup recommended"") -+ } -+ daemon -+ } -+ .filterNotNull() -+ .toList() -+ return when (daemons.size()) { -+ 0 -> null -+ 1 -> daemons.first() -+ else -> throw IllegalStateException(""Multiple daemons serving the same compiler, reset with the cleanup required"") -+ // TODO: consider implementing automatic recovery instead, e.g. getting the youngest or least used daemon and shut down others - } -+ } + package kotlin -- public fun shutdownCompileService(): Unit { -- shutdownCompileService(DaemonOptions()) -+ private fun tryConnectToDaemon(port: Int, reportingTargets: DaemonReportingTargets): CompileService? { -+ try { -+ val daemon = LocateRegistry.getRegistry(loopbackAddrName, port) -+ ?.lookup(COMPILER_SERVICE_RMI_NAME) -+ if (daemon != null) -+ return daemon as? CompileService ?: -+ throw ClassCastException(""Unable to cast compiler service, actual class received: ${daemon.javaClass}"") -+ reportingTargets.report(DaemonReportCategory.EXCEPTION, ""daemon not found"") -+ } -+ catch (e: ConnectException) { -+ reportingTargets.report(DaemonReportCategory.EXCEPTION, ""cannot connect to registry: "" + (e.getCause()?.getMessage() ?: e.getMessage() ?: ""unknown exception"")) -+ // ignoring it - processing below - } -+ return null -+ } ++/** ++ * The root of the Kotlin class hierarchy. Every Kotlin class has [Any] as a superclass. ++ */ + public open class Any { ++ /** ++ * Indicates whether some other object is ""equal to"" this one. Implementations must follow ++ * the same contract as the [Java equals() method](http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals%28java.lang.Object%29).","Referencing Java in such a way doesn't make it look like a standard library for a _language_, which is targeting different platforms. E.g. for JS it may be different contract. +",Would it be possible to add a link to the docs for this? +380,"@@ -16,10 +16,30 @@ -- public fun compile(compiler: CompileService, args: Array, out: OutputStream): Int { + package kotlin -- val outStrm = RemoteOutputStreamServer(out) -- try { -- return compiler.remoteCompile(args, outStrm, CompileService.OutputFormat.PLAIN) -- } -- finally { -- outStrm.disconnect() -- } -+ private fun startDaemon(compilerId: CompilerId, daemonJVMOptions: DaemonJVMOptions, daemonOptions: DaemonOptions, reportingTargets: DaemonReportingTargets) { -+ val javaExecutable = File(System.getProperty(""java.home""), ""bin"").let { -+ val javaw = File(it, ""javaw.exe"") -+ // TODO: doesn't seem reliable enough, consider more checks if OS is of windows flavor, etc. -+ if (javaw.exists() && javaw.isFile && javaw.canExecute()) javaw else File(it, ""java"") - } -+ val args = listOf(javaExecutable.absolutePath, -+ ""-cp"", compilerId.compilerClasspath.joinToString(File.pathSeparator)) + -+ daemonJVMOptions.mappers.flatMap { it.toArgs(""-"") } + -+ COMPILER_DAEMON_CLASS_FQN + -+ daemonOptions.mappers.flatMap { it.toArgs(COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX) } + -+ compilerId.mappers.flatMap { it.toArgs(COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX) } -+ reportingTargets.report(DaemonReportCategory.DEBUG, ""starting the daemon as: "" + args.joinToString("" "")) -+ val processBuilder = ProcessBuilder(args).redirectErrorStream(true) -+ // assuming daemon process is deaf and (mostly) silent, so do not handle streams -+ val daemon = processBuilder.start() - -- public fun incrementalCompile(compiler: CompileService, args: Array, caches: Map, out: OutputStream): Int { -+ var isEchoRead = Semaphore(1) -+ isEchoRead.acquire() - -- val outStrm = RemoteOutputStreamServer(out) -- val cacheServers = hashMapOf() -- try { -- caches.mapValuesTo(cacheServers, { RemoteIncrementalCacheServer( it.getValue()) }) -- return compiler.remoteIncrementalCompile(args, cacheServers, outStrm, CompileService.OutputFormat.XML) -+ val stdoutThread = -+ thread { -+ daemon.inputStream -+ .reader() -+ .forEachLine { -+ if (daemonOptions.runFilesPath.isNotEmpty() && it.contains(daemonOptions.runFilesPath)) { -+ isEchoRead.release() -+ return@forEachLine -+ } -+ reportingTargets.report(DaemonReportCategory.DEBUG, it, ""daemon"") -+ } -+ } -+ try { -+ // trying to wait for process -+ val daemonStartupTimeout = System.getProperty(COMPILE_DAEMON_STARTUP_TIMEOUT_PROPERTY)?.let { -+ try { -+ it.toLong() -+ } -+ catch (e: Exception) { -+ reportingTargets.report(DaemonReportCategory.INFO, ""unable to interpret $COMPILE_DAEMON_STARTUP_TIMEOUT_PROPERTY property ('$it'); using default timeout $DAEMON_DEFAULT_STARTUP_TIMEOUT_MS ms"") -+ null -+ } -+ } ?: DAEMON_DEFAULT_STARTUP_TIMEOUT_MS -+ if (daemonOptions.runFilesPath.isNotEmpty()) { -+ val succeeded = isEchoRead.tryAcquire(daemonStartupTimeout, TimeUnit.MILLISECONDS) -+ if (!daemon.isAlive()) -+ throw Exception(""Daemon terminated unexpectedly"") -+ if (!succeeded) -+ throw Exception(""Unable to get response from daemon in $daemonStartupTimeout ms"") - } -- finally { -- cacheServers.forEach { it.getValue().disconnect() } -- outStrm.disconnect() -+ else -+ // without startEcho defined waiting for max timeout -+ Thread.sleep(daemonStartupTimeout) -+ } -+ finally { -+ // assuming that all important output is already done, the rest should be routed to the log by the daemon itself -+ if (stdoutThread.isAlive) { -+ // TODO: find better method to stop the thread, but seems it will require asynchronous consuming of the stream -+ stdoutThread.stop() - } - } -+ } ++/** ++ * Marks the annotated class as a data class. Data classes have automatically generated","""When processing data class, compiler will generate""... +",This file has nothing to do with the PR. +381,"@@ -16,13 +16,31 @@ -- data class ClientOptions( -- public var stop: Boolean = false -- ) : OptionsGroup { -- override val mappers: List> -- get() = listOf( BoolPropMapper(this, ::stop)) -- } + package kotlin -- jvmStatic public fun main(vararg args: String) { -- val compilerId = CompilerId() -- val daemonOptions = DaemonOptions() -- val daemonLaunchingOptions = DaemonJVMOptions() -- val clientOptions = ClientOptions() -- val filteredArgs = args.asIterable().filterExtractProps(compilerId, daemonOptions, daemonLaunchingOptions, clientOptions, prefix = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX) -- -- if (!clientOptions.stop) { -- if (compilerId.compilerClasspath.none()) { -- // attempt to find compiler to use -- println(""compiler wasn't explicitly specified, attempt to find appropriate jar"") -- System.getProperty(""java.class.path"") -- ?.split(File.pathSeparator) -- ?.map { File(it).parent } -- ?.distinct() -- ?.map { -- it?.walk() -- ?.firstOrNull { it.getName().equals(COMPILER_JAR_NAME, ignoreCase = true) } -- } -- ?.filterNotNull() -- ?.firstOrNull() -- ?.let { compilerId.compilerClasspath = listOf(it.absolutePath) } -- } -- if (compilerId.compilerClasspath.none()) -- throw IllegalArgumentException(""Cannot find compiler jar"") -- else -- println(""desired compiler classpath: "" + compilerId.compilerClasspath.joinToString(File.pathSeparator)) -+ private fun checkCompilerId(compiler: CompileService, localId: CompilerId): Boolean { -+ val remoteId = compiler.getCompilerId() -+ return (localId.compilerVersion.isEmpty() || localId.compilerVersion == remoteId.compilerVersion) && -+ (localId.compilerClasspath.all { remoteId.compilerClasspath.contains(it) }) && -+ (localId.compilerDigest.isEmpty() || remoteId.compilerDigest.isEmpty() || localId.compilerDigest == remoteId.compilerDigest) -+ } ++/** ++ * Returns true if the receiver and the [other] object are the same object instance, or if they ++ * are both null. ++ */ + public fun Any?.identityEquals(other: Any?): Boolean // = this === other -- compilerId.updateDigest() -+ -+ class FileBasedLock(compilerId: CompilerId, daemonOptions: DaemonOptions) { -+ private val lockFile: File = -+ File(daemonOptions.runFilesPath, -+ makeRunFilenameString(ts = ""lock"", -+ digest = compilerId.compilerClasspath.map { File(it).absolutePath }.distinctStringsDigest(), -+ port = ""0"")) -+ -+ private var locked: Boolean = acquireLockFile(lockFile) -+ -+ public fun isLocked(): Boolean = locked -+ -+ synchronized public fun release(): Unit { -+ if (locked) { -+ lock?.release() -+ channel?.close() -+ lockFile.delete() -+ locked = false - } -+ } ++/** ++ * Returns true if the receiver and the [other] object are ""equal"" to each other, or if they are","Link to Any.equals() on ""equal"" would be good, to refer to explanation of equality. +","If the [other] object are the same object instance, then it is considered ""equal" +382,"@@ -16,18 +16,25 @@ -- val daemon = connectToCompileService(compilerId, daemonLaunchingOptions, daemonOptions, System.out, autostart = !clientOptions.stop, checkId = !clientOptions.stop) -+ private val channel = if (locked) RandomAccessFile(lockFile, ""rw"").channel else null -+ private val lock = channel?.lock() - -- if (daemon == null) { -- if (clientOptions.stop) println(""No daemon found to shut down"") -- else throw Exception(""Unable to connect to daemon"") -+ synchronized private fun acquireLockFile(lockFile: File): Boolean {","~~Why do we have `:Boolean` function that always returns `true` ?~~ -I see, sorry -",Please add the name of the variable to -701,"@@ -18,246 +18,376 @@ package org.jetbrains.kotlin.rmi.kotlinr - - import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache - import org.jetbrains.kotlin.rmi.* --import java.io.File --import java.io.OutputStream --import java.io.PrintStream -+import java.io.* - import java.rmi.ConnectException --import java.rmi.Remote - import java.rmi.registry.LocateRegistry - import java.util.concurrent.Semaphore - import java.util.concurrent.TimeUnit - import kotlin.concurrent.thread - --fun Process.isAlive() = -+ -+public object KotlinCompilerClient { -+ -+ val DAEMON_DEFAULT_STARTUP_TIMEOUT_MS = 10000L -+ val DAEMON_CONNECT_CYCLE_ATTEMPTS = 3 -+ -+ -+ // TODO: remove jvmStatic after all use sites will switch to kotlin -+ jvmStatic -+ public fun connectToCompileService(compilerId: CompilerId, -+ daemonJVMOptions: DaemonJVMOptions, -+ daemonOptions: DaemonOptions, -+ reportingTargets: DaemonReportingTargets, -+ autostart: Boolean = true, -+ checkId: Boolean = true -+ ): CompileService? { -+ -+ var attempts = 0 -+ var fileLock: FileBasedLock? = null - try { -- this.exitValue() -- false -+ while (attempts++ < DAEMON_CONNECT_CYCLE_ATTEMPTS) { -+ val service = tryFindDaemon(File(daemonOptions.runFilesPath), compilerId, reportingTargets) -+ if (service != null) { -+ if (!checkId || checkCompilerId(service, compilerId)) { -+ reportingTargets.report(DaemonReportCategory.DEBUG, ""connected to the daemon"") -+ return service -+ } -+ reportingTargets.report(DaemonReportCategory.DEBUG, ""compiler identity don't match: "" + compilerId.mappers.flatMap { it.toArgs("""") }.joinToString("" "")) -+ if (!autostart) return null -+ reportingTargets.report(DaemonReportCategory.DEBUG, ""shutdown the daemon"") -+ service.shutdown() -+ // TODO: find more reliable way -+ Thread.sleep(1000) -+ reportingTargets.report(DaemonReportCategory.DEBUG, ""daemon shut down correctly, restarting search"") -+ } -+ else { -+ if (!autostart) return null -+ reportingTargets.report(DaemonReportCategory.DEBUG, ""no suitable daemon found, starting a new one"") -+ } -+ -+ if (fileLock == null || !fileLock.isLocked()) { -+ File(daemonOptions.runFilesPath).mkdirs() -+ fileLock = FileBasedLock(compilerId, daemonOptions) -+ // need to check the daemons again here, because of possible racing conditions -+ // note: the algorithm could be simpler if we'll acquire lock right from the beginning, but it may be costly -+ attempts-- -+ } -+ else { -+ startDaemon(compilerId, daemonJVMOptions, daemonOptions, reportingTargets) -+ reportingTargets.report(DaemonReportCategory.DEBUG, ""daemon started, trying to resolve"") -+ } -+ } - } -- catch (e: IllegalThreadStateException) { -- true -+ catch (e: Exception) { -+ reportingTargets.report(DaemonReportCategory.EXCEPTION, e.toString()) -+ } -+ finally { -+ fileLock?.release() - } -+ return null -+ } + package kotlin.script.templates.standard --public class KotlinCompilerClient { ++// discuss ++// ++// These are some 'basic' script templates ++// Should we keep them here?","I think we should do the following with these: +* `SimpleScriptTemplate` -> remove (script with args can be always used instead of it) +* `kotlin.script.templates.standard.ScriptTemplateWithArgs` -> rename and move to `kotlin.script.templates.StandardScriptTemplate` +* `kotlin.script.templates.standard.ScriptTemplateWithBindings` -> move to `kotlin.script.templates.ScriptTemplateWithBindings`",How about: `// Keep them in the 'basic' script template` ? +383,"@@ -16,26 +16,66 @@ -- companion object { -+ public fun shutdownCompileService(daemonOptions: DaemonOptions): Unit { -+ KotlinCompilerClient.connectToCompileService(CompilerId(), DaemonJVMOptions(), daemonOptions, DaemonReportingTargets(out = System.out), autostart = false, checkId = false) -+ ?.shutdown() -+ } + package kotlin -- val DAEMON_STARTUP_TIMEOUT_MS = 10000L ++/** ++ * An iterator over a collection. Allows to sequentially access the elements in a collection.","Not necessary ""in a collection"". +","This isn't a collection, it's a collection of elements." +384,"@@ -16,40 +16,112 @@ -- private fun connectToService(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): CompileService? { -+ public fun shutdownCompileService(): Unit { -+ shutdownCompileService(DaemonOptions()) -+ } + package kotlin -- val compilerObj = connectToDaemon(compilerId, daemonOptions, errStream) ?: return null // no registry - no daemon running -- return compilerObj as? CompileService ?: -- throw ClassCastException(""Unable to cast compiler service, actual class received: ${compilerObj.javaClass}"") -+ -+ public fun compile(compiler: CompileService, args: Array, out: OutputStream): Int { -+ -+ val outStrm = RemoteOutputStreamServer(out) -+ try { -+ return compiler.remoteCompile(args, outStrm, CompileService.OutputFormat.PLAIN, outStrm) - } -+ finally { -+ outStrm.disconnect() -+ } -+ } ++/** ++ * Classes that inherit from this trait can be represented as a sequence of elements that can ++ * be iterated over. ++ */ + public trait Iterable {","doc for `T`? +",This is not true. The `out T` type is `Iterable` +385,"@@ -16,6 +16,11 @@ -- private fun connectToDaemon(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): Remote? { -- try { -- val daemon = LocateRegistry.getRegistry(""localhost"", daemonOptions.port) -- ?.lookup(COMPILER_SERVICE_RMI_NAME) -- if (daemon != null) -- return daemon -- errStream.println(""[daemon client] daemon not found"") -- } -- catch (e: ConnectException) { -- errStream.println(""[daemon client] cannot connect to registry: "" + (e.getCause()?.getMessage() ?: e.getMessage() ?: ""unknown exception"")) -- // ignoring it - processing below -- } -- return null -+ -+ // TODO: remove jvmStatic after all use sites will switch to kotlin -+ jvmStatic -+ public fun incrementalCompile(compiler: CompileService, args: Array, caches: Map, compilerOut: OutputStream, daemonOut: OutputStream): Int { + package kotlin.script.extensions + ++// discuss + -+ val compilerOutStreamServer = RemoteOutputStreamServer(compilerOut) -+ val daemonOutStreamServer = RemoteOutputStreamServer(daemonOut) -+ val cacheServers = hashMapOf() -+ try { -+ caches.mapValuesTo(cacheServers, { RemoteIncrementalCacheServer(it.getValue()) }) -+ return compiler.remoteIncrementalCompile(args, cacheServers, compilerOutStreamServer, CompileService.OutputFormat.XML, daemonOutStreamServer) -+ } -+ finally { -+ cacheServers.forEach { it.getValue().disconnect() } -+ compilerOutStreamServer.disconnect() -+ daemonOutStreamServer.disconnect() - } -+ } ++// Is this an appropriate place to put this class?","This doesn't look like an appropriate place. If I understand correctly, it has nothing to do with scripts, so putting it into package `kotlin.script.extensions` is risky. As soon as we decide to publish it as a supported compiler plugin, we'll have to move it to another package and artifact, causing incompatibilities, so maybe it'd be better to do this earlier.",Why did you put this here instead of in `scripts/`? +386,"@@ -16,8 +16,18 @@ + package kotlin -- private fun startDaemon(compilerId: CompilerId, daemonJVMOptions: DaemonJVMOptions, daemonOptions: DaemonOptions, errStream: PrintStream) { -- val javaExecutable = File(System.getProperty(""java.home""), ""bin"").let { -- val javaw = File(it, ""javaw.exe"") -- if (javaw.exists()) javaw -- else File(it, ""java"") -- } -- // TODO: add some specific environment variables to the cp and may be command line, to allow some specific startup configs -- val args = listOf(javaExecutable.absolutePath, -- ""-cp"", compilerId.compilerClasspath.joinToString(File.pathSeparator)) + -- daemonJVMOptions.mappers.flatMap { it.toArgs(""-"") } + -- COMPILER_DAEMON_CLASS_FQN + -- daemonOptions.mappers.flatMap { it.toArgs(COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX) } + -- compilerId.mappers.flatMap { it.toArgs(COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX) } -- errStream.println(""[daemon client] starting the daemon as: "" + args.joinToString("" "")) -- val processBuilder = ProcessBuilder(args).redirectErrorStream(true) -- // assuming daemon process is deaf and (mostly) silent, so do not handle streams -- val daemon = processBuilder.start() -- -- var isEchoRead = Semaphore(1) -- isEchoRead.acquire() -- -- val stdoutThread = -- thread { -- daemon.getInputStream() -- .reader() -- .forEachLine { -- if (daemonOptions.startEcho.isNotEmpty() && it.contains(daemonOptions.startEcho)) { -- isEchoRead.release() -- return@forEachLine -- } -- errStream.println(""[daemon] "" + it) -- } -- } -- try { -- // trying to wait for process -- if (daemonOptions.startEcho.isNotEmpty()) { -- errStream.println(""[daemon client] waiting for daemon to respond"") -- val succeeded = isEchoRead.tryAcquire(DAEMON_STARTUP_TIMEOUT_MS, TimeUnit.MILLISECONDS) -- if (!daemon.isAlive()) -- throw Exception(""Daemon terminated unexpectedly"") -- if (!succeeded) -- throw Exception(""Unable to get response from daemon in $DAEMON_STARTUP_TIMEOUT_MS ms"") -- } -- else -- // without startEcho defined waiting for max timeout -- Thread.sleep(DAEMON_STARTUP_TIMEOUT_MS) -- } -- finally { -- // assuming that all important output is already done, the rest should be routed to the log by the daemon itself -- if (stdoutThread.isAlive) -- // TODO: find better method to stop the thread, but seems it will require asynchronous consuming of the stream -- stdoutThread.stop() -+ data class ClientOptions( -+ public var stop: Boolean = false -+ ) : OptionsGroup { -+ override val mappers: List> -+ get() = listOf(BoolPropMapper(this, ::stop)) -+ } -+ ++/** ++ * Annotates the parameter of a function annotates as [inline] and forbids inlining of","Typo: ""annotates as [inline]"" -> ""annotated as [inline]"" +","Perhaps should be ""annotates the parameter of a fun" +387,"@@ -16,8 +16,18 @@ + + package kotlin + ++/** ++ * Annotates the parameter of a function annotates as [inline] and forbids inlining of ++ * function literals passed as arguments for this parameter. ++ */ + public annotation class noinline + ++/**","Add cross-reference to other annotations, like `noinline` +",nit: typo ininlining +388,"@@ -16,9 +16,11 @@ import org.jetbrains.kotlin.codegen.state.GenerationState + import org.jetbrains.kotlin.codegen.visitAnnotableParameterCount + import org.jetbrains.kotlin.config.LanguageFeature + import org.jetbrains.kotlin.descriptors.Modality ++import org.jetbrains.kotlin.descriptors.Visibilities + import org.jetbrains.kotlin.ir.declarations.* + import org.jetbrains.kotlin.ir.expressions.* + import org.jetbrains.kotlin.ir.util.* ++import org.jetbrains.kotlin.load.java.JavaVisibilities",These imports seem unused,This import does not appear to be used. +389,"@@ -161,6 +162,13 @@ object KotlinToJVMBytecodeCompiler { + ProgressIndicatorAndCompilationCanceledStatus.checkCanceled() + writeOutput(state.configuration, state.factory, null) + } + -+ jvmStatic public fun main(vararg args: String) { -+ val compilerId = CompilerId() -+ val daemonOptions = DaemonOptions() -+ val daemonLaunchingOptions = DaemonJVMOptions() -+ val clientOptions = ClientOptions() -+ val filteredArgs = args.asIterable().filterExtractProps(compilerId, daemonOptions, daemonLaunchingOptions, clientOptions, prefix = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX) -+ -+ if (!clientOptions.stop) { -+ if (compilerId.compilerClasspath.none()) { -+ // attempt to find compiler to use -+ System.err.println(""compiler wasn't explicitly specified, attempt to find appropriate jar"") -+ System.getProperty(""java.class.path"") -+ ?.split(File.pathSeparator) -+ ?.map { File(it).parentFile } -+ ?.distinct() -+ ?.map { -+ it?.walk() -+ ?.firstOrNull { it.name.equals(COMPILER_JAR_NAME, ignoreCase = true) } -+ } -+ ?.filterNotNull() -+ ?.firstOrNull() -+ ?.let { compilerId.compilerClasspath = listOf(it.absolutePath) } ++ if (chunk.size == 1 && projectConfiguration.getBoolean(JVMConfigurationKeys.USE_JAVAC)) {","If the chunk contains multiple modules and `-Xuse-javac` has been specified, maybe we should report a warning saying that we won't in fact use javac for compilation",I think we can remove this check. It's sufficient t +390,"@@ -161,6 +162,14 @@ object KotlinToJVMBytecodeCompiler { + ProgressIndicatorAndCompilationCanceledStatus.checkCanceled() + writeOutput(state.configuration, state.factory, null) } -- } -+ if (compilerId.compilerClasspath.none()) -+ throw IllegalArgumentException(""Cannot find compiler jar"") -+ else -+ println(""desired compiler classpath: "" + compilerId.compilerClasspath.joinToString(File.pathSeparator)) - -- public fun checkCompilerId(compiler: CompileService, localId: CompilerId, errStream: PrintStream): Boolean { -- val remoteId = compiler.getCompilerId() -- errStream.println(""[daemon client] remoteId = "" + remoteId.toString()) -- errStream.println(""[daemon client] localId = "" + localId.toString()) -- return (localId.compilerVersion.isEmpty() || localId.compilerVersion == remoteId.compilerVersion) && -- (localId.compilerClasspath.all { remoteId.compilerClasspath.contains(it) }) && -- (localId.compilerDigest.isEmpty() || remoteId.compilerDigest.isEmpty() || localId.compilerDigest == remoteId.compilerDigest) -+ compilerId.updateDigest() - } ++ ++ if (chunk.size == 1) { ++ val javacWrapper = JavacWrapper.getInstance(environment.project) ++ if (projectConfiguration[JVMConfigurationKeys.USE_JAVAC]!!) {",@baratynskiy Please use `getBoolean(...)` instead of `get(...)!!`,Remove the `!` +391,"@@ -162,4 +162,8 @@ change.function.signature.family=Change function signature + change.function.signature.chooser.title=Choose signature + change.function.signature.action=Change function signature + remove.unnecessary.parentheses=Remove unnecessary parentheses +-remove.unnecessary.parentheses.family=Remove Unnecessary Parentheses +\ No newline at end of file ++remove.unnecessary.parentheses.family=Remove Unnecessary Parentheses ++add.function.to.supertype.family=Add Function to Supertype","While I know it's technically not 100% correct and maybe ""Add Function to _Superclassifier_"" would be a more accurate name for this quickfix I still want to stick with the name ""Add Function to Supertype"". In my opinion the user would be confused by using word ""superclassifier"". I can change the name though if you disagree. +",Why not just add this to `add.function.family`? +392,"@@ -162,6 +169,22 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) : + return completeInference.compose() + } -- public fun connectToCompileService(compilerId: CompilerId, daemonJVMOptions: DaemonJVMOptions, daemonOptions: DaemonOptions, errStream: PrintStream, autostart: Boolean = true, checkId: Boolean = true): CompileService? { -- val service = connectToService(compilerId, daemonOptions, errStream) -- if (service != null) { -- if (!checkId || checkCompilerId(service, compilerId, errStream)) { -- errStream.println(""[daemon client] found the suitable daemon"") -- return service -- } -- errStream.println(""[daemon client] compiler identity don't match: "" + compilerId.mappers.flatMap { it.toArgs("""") }.joinToString("" "")) -- if (!autostart) return null; -- errStream.println(""[daemon client] shutdown the daemon"") -- service.shutdown() -- // TODO: find more reliable way -- Thread.sleep(1000) -- errStream.println(""[daemon client] daemon shut down correctly, restarting"") -+ val daemon = connectToCompileService(compilerId, daemonLaunchingOptions, daemonOptions, DaemonReportingTargets(out = System.out), autostart = !clientOptions.stop, checkId = !clientOptions.stop) -+ -+ if (daemon == null) { -+ if (clientOptions.stop) { -+ System.err.println(""No daemon found to shut down"") - } -- else { -- if (!autostart) return null; -- else errStream.println(""[daemon client] cannot connect to Compile Daemon, trying to start"") -+ else throw Exception(""Unable to connect to daemon"") -+ } -+ else when { -+ clientOptions.stop -> { -+ println(""Shutdown the daemon"") -+ daemon.shutdown() -+ println(""Daemon shut down successfully"") ++ // Use the generic invoke method in Function classes, to match bridges generated by the backend. ++ private fun checkIfInvoke(functionCall: FirFunctionCall) : FirFunctionCall {","I'd think frontend shouldn't rewrite declarations in sake of knowledge of backend behavior, so this logic should rather be in fir2ir or even in backend itself",nit: `checkIfInvoke` -> `checkIfInvokeMethod` +393,"@@ -163,7 +164,10 @@ object KDocRenderer { + // Avoid wrapping the entire converted contents in a

tag if it's just a single paragraph + val maybeSingleParagraph = markdownNode.children.singleOrNull { it.type != MarkdownTokenTypes.EOL } + return if (maybeSingleParagraph != null && !allowSingleParagraph) { +- maybeSingleParagraph.children.joinToString("""") { it.toHtml() } ++ val lineSeparator = LineSeparator.getSystemLineSeparator().separatorString",Source code in IntelliJ always uses `\n` as a line separator. No need to access the system line separator here.,Please remove the `LineSeparator.getSystemLineSepar +394,"@@ -164,6 +165,7 @@ class CodeToInlineBuilder( } -+ else -> { -+ println(""Executing daemon compilation with args: "" + filteredArgs.joinToString("" "")) -+ val outStrm = RemoteOutputStreamServer(System.out) -+ try { -+ val memBefore = daemon.getUsedMemory() / 1024 -+ val startTime = System.nanoTime() -+ -+ val res = daemon.remoteCompile(filteredArgs.toArrayList().toTypedArray(), outStrm, CompileService.OutputFormat.PLAIN, outStrm) - -- startDaemon(compilerId, daemonJVMOptions, daemonOptions, errStream) -- errStream.println(""[daemon client] daemon started, trying to connect"") -- return connectToService(compilerId, daemonOptions, errStream) -+ val endTime = System.nanoTime() -+ println(""Compilation result code: $res"") -+ val memAfter = daemon.getUsedMemory() / 1024 -+ println(""Compilation time: "" + TimeUnit.NANOSECONDS.toMillis(endTime - startTime) + "" ms"") -+ println(""Used memory $memAfter (${""%+d"".format(memAfter - memBefore)} kb)"") -+ } -+ finally { -+ outStrm.disconnect() -+ } -+ } - } -+ } -- public fun shutdownCompileService(daemonOptions: DaemonOptions): Unit { -- KotlinCompilerClient.connectToCompileService(CompilerId(), DaemonJVMOptions(), daemonOptions, System.out, autostart = false, checkId = false) -- ?.shutdown() -+ // --- Implementation --------------------------------------- -+ -+ val verboseReporting = System.getProperty(COMPILE_DAEMON_VERBOSE_REPORT_PROPERTY) != null -+ -+ fun DaemonReportingTargets.report(category: DaemonReportCategory, message: String, source: String = ""daemon client"") { -+ if (category == DaemonReportCategory.DEBUG && !verboseReporting) return -+ out?.println(""[$source] ${category.name()}: $message"") -+ messages?.add(DaemonReportMessage(category, ""[$source] $message"")) -+ } -+ -+ private fun tryFindDaemon(registryDir: File, compilerId: CompilerId, reportingTargets: DaemonReportingTargets): CompileService? { -+ val classPathDigest = compilerId.compilerClasspath.map { File(it).absolutePath }.distinctStringsDigest() -+ val daemons = registryDir.walk() -+ .map { Pair(it, makeRunFilenameRegex(digest = classPathDigest, port = ""(\\d+)"").match(it.name)?.groups?.get(1)?.value?.toInt() ?: 0) } -+ .filter { it.second != 0 } -+ .map { -+ reportingTargets.report(DaemonReportCategory.DEBUG, ""found suitable daemon on port ${it.second}, trying to connect"") -+ val daemon = tryConnectToDaemon(it.second, reportingTargets) -+ // cleaning orphaned file; note: daemon should shut itself down if it detects that the run file is deleted -+ if (daemon == null && !it.first.delete()) { -+ reportingTargets.report(DaemonReportCategory.INFO, ""WARNING: unable to delete seemingly orphaned file '${it.first.absolutePath}', cleanup recommended"") -+ } -+ daemon -+ } -+ .filterNotNull() -+ .toList() -+ return when (daemons.size()) { -+ 0 -> null -+ 1 -> daemons.first() -+ else -> throw IllegalStateException(""Multiple daemons serving the same compiler, reset with the cleanup required"") -+ // TODO: consider implementing automatic recovery instead, e.g. getting the youngest or least used daemon and shut down others - } -+ } + if (expression.getReceiverExpression() == null) { ++ val targetCallable = (targetCallable as? FunctionImportedFromObject)?.callableFromObject ?: targetCallable",Should we use `ImportedFromObjectCallableDescriptor<*>` instead?,"If `targetCallable` is null, then `null` should be " +395,"@@ -164,7 +164,8 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL + val irFunctionReference: IrFunctionReference + ) { -- public fun shutdownCompileService(): Unit { -- shutdownCompileService(DaemonOptions()) -+ private fun tryConnectToDaemon(port: Int, reportingTargets: DaemonReportingTargets): CompileService? { -+ try { -+ val daemon = LocateRegistry.getRegistry(loopbackAddrName, port) -+ ?.lookup(COMPILER_SERVICE_RMI_NAME) -+ if (daemon != null) -+ return daemon as? CompileService ?: -+ throw ClassCastException(""Unable to cast compiler service, actual class received: ${daemon.javaClass}"") -+ reportingTargets.report(DaemonReportCategory.EXCEPTION, ""daemon not found"") -+ } -+ catch (e: ConnectException) { -+ reportingTargets.report(DaemonReportCategory.EXCEPTION, ""cannot connect to registry: "" + (e.getCause()?.getMessage() ?: e.getMessage() ?: ""unknown exception"")) -+ // ignoring it - processing below - } -+ return null -+ } +- private val isLambda = irFunctionReference.origin == IrStatementOrigin.LAMBDA ++ private val isLambda = irFunctionReference.origin == IrStatementOrigin.LAMBDA ||",Please rename to isLambdaOrAnonymousFunction,Can you please explain why this change is needed? +396,"@@ -164,7 +165,10 @@ internal actual inline fun Array.copyToArrayOfAny(isVarargs: Boolean) + else + this.copyOf() -- public fun compile(compiler: CompileService, args: Array, out: OutputStream): Int { +- ++@PublishedApi ++@SinceKotlin(""1.3"")","Should this be `""1.4""`, or some other value?",Why did you remove the `since Kotlin` annotation he +397,"@@ -165,6 +165,9 @@ fun IrDeclarationWithVisibility.getVisibilityAccessFlag(kind: OwnerKind? = null) + ?: visibilityToAccessFlag[visibility] + ?: throw IllegalStateException(""$visibility is not a valid visibility in backend for ${ir2string(this)}"") -- val outStrm = RemoteOutputStreamServer(out) -- try { -- return compiler.remoteCompile(args, outStrm, CompileService.OutputFormat.PLAIN) -- } -- finally { -- outStrm.disconnect() -- } -+ private fun startDaemon(compilerId: CompilerId, daemonJVMOptions: DaemonJVMOptions, daemonOptions: DaemonOptions, reportingTargets: DaemonReportingTargets) { -+ val javaExecutable = File(System.getProperty(""java.home""), ""bin"").let { -+ val javaw = File(it, ""javaw.exe"") -+ // TODO: doesn't seem reliable enough, consider more checks if OS is of windows flavor, etc. -+ if (javaw.exists() && javaw.isFile && javaw.canExecute()) javaw else File(it, ""java"") - } -+ val args = listOf(javaExecutable.absolutePath, -+ ""-cp"", compilerId.compilerClasspath.joinToString(File.pathSeparator)) + -+ daemonJVMOptions.mappers.flatMap { it.toArgs(""-"") } + -+ COMPILER_DAEMON_CLASS_FQN + -+ daemonOptions.mappers.flatMap { it.toArgs(COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX) } + -+ compilerId.mappers.flatMap { it.toArgs(COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX) } -+ reportingTargets.report(DaemonReportCategory.DEBUG, ""starting the daemon as: "" + args.joinToString("" "")) -+ val processBuilder = ProcessBuilder(args).redirectErrorStream(true) -+ // assuming daemon process is deaf and (mostly) silent, so do not handle streams -+ val daemon = processBuilder.start() - -- public fun incrementalCompile(compiler: CompileService, args: Array, caches: Map, out: OutputStream): Int { -+ var isEchoRead = Semaphore(1) -+ isEchoRead.acquire() - -- val outStrm = RemoteOutputStreamServer(out) -- val cacheServers = hashMapOf() -- try { -- caches.mapValuesTo(cacheServers, { RemoteIncrementalCacheServer( it.getValue()) }) -- return compiler.remoteIncrementalCompile(args, cacheServers, outStrm, CompileService.OutputFormat.XML) -+ val stdoutThread = -+ thread { -+ daemon.inputStream -+ .reader() -+ .forEachLine { -+ if (daemonOptions.runFilesPath.isNotEmpty() && it.contains(daemonOptions.runFilesPath)) { -+ isEchoRead.release() -+ return@forEachLine -+ } -+ reportingTargets.report(DaemonReportCategory.DEBUG, it, ""daemon"") -+ } -+ } -+ try { -+ // trying to wait for process -+ val daemonStartupTimeout = System.getProperty(COMPILE_DAEMON_STARTUP_TIMEOUT_PROPERTY)?.let { -+ try { -+ it.toLong() -+ } -+ catch (e: Exception) { -+ reportingTargets.report(DaemonReportCategory.INFO, ""unable to interpret $COMPILE_DAEMON_STARTUP_TIMEOUT_PROPERTY property ('$it'); using default timeout $DAEMON_DEFAULT_STARTUP_TIMEOUT_MS ms"") -+ null -+ } -+ } ?: DAEMON_DEFAULT_STARTUP_TIMEOUT_MS -+ if (daemonOptions.runFilesPath.isNotEmpty()) { -+ val succeeded = isEchoRead.tryAcquire(daemonStartupTimeout, TimeUnit.MILLISECONDS) -+ if (!daemon.isAlive()) -+ throw Exception(""Daemon terminated unexpectedly"") -+ if (!succeeded) -+ throw Exception(""Unable to get response from daemon in $daemonStartupTimeout ms"") - } -- finally { -- cacheServers.forEach { it.getValue().disconnect() } -- outStrm.disconnect() -+ else -+ // without startEcho defined waiting for max timeout -+ Thread.sleep(daemonStartupTimeout) -+ } -+ finally { -+ // assuming that all important output is already done, the rest should be routed to the log by the daemon itself -+ if (stdoutThread.isAlive) { -+ // TODO: find better method to stop the thread, but seems it will require asynchronous consuming of the stream -+ stdoutThread.stop() ++fun IrFunction.getVisibilityForDefaultArgumentStub(): Int =","I'd implement it like this, and probably move it to `FunctionCodegen`: +``` +when (visibility) { + Visibilities.PUBLIC -> Opcodes.ACC_PUBLIC + JavaVisibilities.PACKAGE_VISIBILITY -> AsmUtil.NO_FLAG_PACKAGE_PRIVATE + else -> error(""Default argument stub should be either public or package private: ${ir2string(this)}"") +} +```",is there a reason for not using `visibilityToAccess +398,"@@ -167,7 +166,7 @@ class ExpressionCodegen( + irFunction.markLineNumber(startOffset = irFunction is IrConstructor && irFunction.isPrimary) } + val returnType = typeMapper.mapReturnType(irFunction) +- result.coerce(returnType).materialize() ++ result.coerce(returnType, if (irFunction !is IrConstructor) irFunction.returnType else null).materialize()",I'm wondering if the `null` here could be the unit type instead? ,I don't think this is the right fix. The code below +399,"@@ -168,14 +170,14 @@ abstract class AbstractKotlinCompile() : AbstractKo + get() = (classpath + additionalClasspath) + .filterTo(LinkedHashSet(), File::exists) + +- private val sourceFilesExtensionsSources: MutableList> = mutableListOf() ++ private val sourceFilesExtensionsSources = project.objects.listProperty(String::class.java)","`listProperty` is introduced in Gradle `4.3`, but we support all versions starting from `4.1`",Can't we use `sourceFilesExtensionsSources` directl +400,"@@ -169,6 +169,28 @@ class Maps { + + // map.containsValue(""string"") // cannot call extension when the argument type and the map value type are unrelated at all } -+ } ++ ++ @Sample ++ fun mapIsNotEmpty() {","Perhaps you could think up an example that is closer to a real use case, like [`stringIsEmpty`](https://github.com/JetBrains/kotlin/blob/555d503ff914705209817d326f01d668271957cd/libraries/stdlib/samples/test/samples/text/strings.kt#L287)?",This isn't a sample so we should remove it. +401,"@@ -17,10 +16,8 @@ fun test() { + } -- data class ClientOptions( -- public var stop: Boolean = false -- ) : OptionsGroup { -- override val mappers: List> -- get() = listOf( BoolPropMapper(this, ::stop)) -- } + // @TestKt.class: +-// 1 NEW TestKt\$test\$1","It's best keep smth like +``` + //1 NEW TestKt\$ +``` +and add ```// 2 NEW```",This file has nothing to do with this PR. +402,"@@ -17,10 +16,8 @@ fun test() { + } -- jvmStatic public fun main(vararg args: String) { -- val compilerId = CompilerId() -- val daemonOptions = DaemonOptions() -- val daemonLaunchingOptions = DaemonJVMOptions() -- val clientOptions = ClientOptions() -- val filteredArgs = args.asIterable().filterExtractProps(compilerId, daemonOptions, daemonLaunchingOptions, clientOptions, prefix = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX) -- -- if (!clientOptions.stop) { -- if (compilerId.compilerClasspath.none()) { -- // attempt to find compiler to use -- println(""compiler wasn't explicitly specified, attempt to find appropriate jar"") -- System.getProperty(""java.class.path"") -- ?.split(File.pathSeparator) -- ?.map { File(it).parent } -- ?.distinct() -- ?.map { -- it?.walk() -- ?.firstOrNull { it.getName().equals(COMPILER_JAR_NAME, ignoreCase = true) } -- } -- ?.filterNotNull() -- ?.firstOrNull() -- ?.let { compilerId.compilerClasspath = listOf(it.absolutePath) } -- } -- if (compilerId.compilerClasspath.none()) -- throw IllegalArgumentException(""Cannot find compiler jar"") -- else -- println(""desired compiler classpath: "" + compilerId.compilerClasspath.joinToString(File.pathSeparator)) -+ private fun checkCompilerId(compiler: CompileService, localId: CompilerId): Boolean { -+ val remoteId = compiler.getCompilerId() -+ return (localId.compilerVersion.isEmpty() || localId.compilerVersion == remoteId.compilerVersion) && -+ (localId.compilerClasspath.all { remoteId.compilerClasspath.contains(it) }) && -+ (localId.compilerDigest.isEmpty() || remoteId.compilerDigest.isEmpty() || localId.compilerDigest == remoteId.compilerDigest) -+ } + // @TestKt.class: +-// 1 NEW TestKt\$test\$1 + // 1 NEW kotlin/jvm/internal/Ref\$IntRef + // 2 NEW +-// 1 INVOKESPECIAL TestKt\$test\$1.","@pyos Same here +``` +// 1 INVOKESPECIAL TestKt\$[a-z0-9$]*. +```",Why was this removed? +403,"@@ -17,3 +17,11 @@ + package org.jetbrains.kotlin.cli.common -- compilerId.updateDigest() -+ -+ class FileBasedLock(compilerId: CompilerId, daemonOptions: DaemonOptions) { -+ private val lockFile: File = -+ File(daemonOptions.runFilesPath, -+ makeRunFilenameString(ts = ""lock"", -+ digest = compilerId.compilerClasspath.map { File(it).absolutePath }.distinctStringsDigest(), -+ port = ""0"")) -+ -+ private var locked: Boolean = acquireLockFile(lockFile) + public val KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY = ""kotlin.environment.keepalive"" + -+ public fun isLocked(): Boolean = locked + -+ synchronized public fun release(): Unit { -+ if (locked) { -+ lock?.release() -+ channel?.close() -+ lockFile.delete() -+ locked = false - } -+ } - -- val daemon = connectToCompileService(compilerId, daemonLaunchingOptions, daemonOptions, System.out, autostart = !clientOptions.stop, checkId = !clientOptions.stop) -+ private val channel = if (locked) RandomAccessFile(lockFile, ""rw"").channel else null -+ private val lock = channel?.lock() - -- if (daemon == null) { -- if (clientOptions.stop) println(""No daemon found to shut down"") -- else throw Exception(""Unable to connect to daemon"") -+ synchronized private fun acquireLockFile(lockFile: File): Boolean { -+ if (lockFile.createNewFile()) return true -+ try { -+ // attempt to delete if file is orphaned -+ if (lockFile.delete() && lockFile.createNewFile()) -+ return true // if orphaned file deleted assuming that the probability of - } -- else when { -- clientOptions.stop -> { -- println(""Shutdown the daemon"") -- daemon.shutdown() -- println(""Daemon shut down successfully"") -- } -- else -> { -- println(""Executing daemon compilation with args: "" + filteredArgs.joinToString("" "")) -- val outStrm = RemoteOutputStreamServer(System.out) -- try { -- val memBefore = daemon.getUsedMemory() / 1024 -- val startTime = System.nanoTime() -- val res = daemon.remoteCompile(filteredArgs.toArrayList().toTypedArray(), outStrm, CompileService.OutputFormat.PLAIN) -- val endTime = System.nanoTime() -- println(""Compilation result code: $res"") -- val memAfter = daemon.getUsedMemory() / 1024 -- println(""Compilation time: "" + TimeUnit.NANOSECONDS.toMillis(endTime - startTime) + "" ms"") -- println(""Used memory $memAfter (${""%+d"".format(memAfter - memBefore)} kb)"") -- } -- finally { -- outStrm.disconnect() -- } -- } -+ catch (e: IOException) { -+ // Ignoring it - assuming it is another client process owning it - } -+ var attempts = 0L -+ while (lockFile.exists() && attempts++ * COMPILE_DAEMON_STARTUP_LOCK_TIMEOUT_CHECK_MS < COMPILE_DAEMON_STARTUP_LOCK_TIMEOUT_MS) { -+ Thread.sleep(COMPILE_DAEMON_STARTUP_LOCK_TIMEOUT_CHECK_MS) -+ } -+ if (lockFile.exists()) -+ throw IOException(""Timeout waiting the release of the lock file '${lockFile.absolutePath}"") -+ -+ return lockFile.createNewFile()","Can't we replace it with something like that: ++fun String?.toBooleanLenient(): Boolean? = when (this?.toLowerCase()) {","It seems it is possible to simplify conditional expressions by using the following function instead of `toBooleanLenient` -``` kotlin -do { - if (lockFile.createNewFile()) return true - Thread.sleep(...) -} while (!timeout) +``` +fun String.systemPropertyAsBooleanOrTrueOtherwise(negate: Boolean): Boolean { + val propValue = System.getProperty(this) ?: return true -throw timeout exception + return when (propValue.toLowerCase()) { + in listOf("""", ""yes"", ""true"", ""on"", ""y"") -> !negate + in listOf(""no"", ""false"", ""off"", ""n"") -> negate + else -> true + } +} ``` -It is better because the function has only two cases: return or exception. Now we have true/false/exception -",Please add the name of the variable to -702,"@@ -18,64 +18,89 @@ package org.jetbrains.kotlin.gradle.plugin - - import org.gradle.BuildAdapter - import org.gradle.BuildResult -+import org.gradle.api.invocation.Gradle - import org.gradle.api.logging.Logging - import java.lang.ref.Reference - import java.util.concurrent.ScheduledExecutorService -+import kotlin.text.MatchGroup - --class FinishBuildListener(var pluginClassLoader: ParentLastURLClassLoader?) : BuildAdapter() { -+internal fun getUsedMemoryKb(): Long { -+ System.gc() -+ val rt = Runtime.getRuntime() -+ return (rt.totalMemory() - rt.freeMemory()) / 1024 -+} +See comments below. +",This should be `boolean` not `Boolean`. +404,"@@ -17,6 +17,7 @@ + package kotlin + + /** +- * Nothing has no instances ++ * Nothing has no instances. You can use Nothing as the return type of a function to indicate ++ * that it never returns (always throws an exception).","There are more use-cases for Nothing, e.g. Iterable is ok to exist, but it will never enter ""for"" loop, etc. Needs link to lang docs. +","It's not clear what ""always returns"" means." +405,"@@ -17,8 +16,16 @@ fun test() { + JFoo.foo2({}, runnable()) + } + ++// JVM_TEMPLATES + // @TestKt.class:","Minor: +``` +// @TestKt.class +// 2 NEW +``` +could be extracted in common part",Remove this line since it is unnecessary no +406,"@@ -17,8 +21,6 @@ fun test(u1: UInt, u2: UInt, us: Array) { + // 2 INVOKESTATIC UInt\.box + // 0 INVOKEVIRTUAL UInt.unbox + +-// 2 CHECKCAST \[LUInt","@sfs Please customize test for both backend via: +...TEMPLATES ... + +// JVM_TEMPLATES +// 2 CHECKCAST \[LUInt + +// JVM_IR_TEMPLATES +// 0 CHECKCAST \[LUInt +// Maybe smth else",Why was this removed? +407,"@@ -171,5 +173,11 @@ class PropertyGenerator(declarationGenerator: DeclarationGenerator) : Declaratio + val variableDescriptor = getOrFail(BindingContext.VARIABLE, ktProperty) + return variableDescriptor as? PropertyDescriptor ?: TODO(""not a property: $variableDescriptor"") + } + ++ private val Visibility.admitsFakeOverride: Boolean ++ get() = this != Visibilities.PRIVATE && this != Visibilities.PRIVATE_TO_THIS && this != Visibilities.INVISIBLE_FAKE",Looks like this can be simplified to `!Visibilities.isPrivate(this)` and inlined because invisible fakes have been filtered out in the first line of `generateFakeOverrideProperty`?,You don't need the `get()` call here. If `v +408,"@@ -172,6 +202,33 @@ abstract class KaptTask : ConventionTask(), TaskWithLocalState { + } + } + ++ private fun findClasspathChanges(changedClasspath: Iterable): KaptClasspathChanges { ++ incAptCache!!.mkdirs()","Minor, style: I find creating a local val with the same or using `lateinit` modifier for property more readable than using `!!` operator multiple times.",Is there a reason we need to create the cac +409,"@@ -1730,14 +1730,14 @@ public fun Stream.lastOrNull(): T? { + } + + /** +- * Returns last element, or null if collection is empty ++ * Returns the last character, or null if the string is empty + */ + public fun String.lastOrNull(): Char? { + return if (isEmpty()) null else this[length() - 1] + } + + /** +- * Returns last element matching the given *predicate*, or null if element was not found ++ * Returns the last element matching the given [predicate], or *null* if no such element was found.","_null_ -> `null` +",This worries me a bit. It's not the last el +410,"@@ -175,6 +175,23 @@ class KotlinQuickDocumentationProvider : AbstractDocumentationProvider() { + // element is not an KtReferenceExpression, but KtClass of enum + return renderEnum(element, originalElement, quickNavigation) + } ++ else if (element is KtEnumEntry && !quickNavigation) { ++ val desc = element.resolveToDescriptorIfAny() ++ val ordinal =",It's better to calculate ordinal with `val ordinal = element.containingClassOrObject?.run { getChildrenOfType().indexOf(element) }`,When will the element be a KtEnumEntry? If +411,"@@ -175,7 +195,9 @@ class ExpressionCodegen( + + override fun visitBlockBody(body: IrBlockBody, data: BlockInfo): StackValue { + return body.statements.fold(none()) { _, exp -> +- exp.accept(this, data) ++ val result = exp.accept(this, data) ++ (exp as? IrExpression)?.markEndOfStatementIfNeeded()","``` +exp.accept(this, data).also { + (exp as? IrExpression)?.markEndOfStatementIfNeeded() +} +```","Unrelated to this PR, but this doesn't seem" +412,"@@ -175,8 +188,8 @@ internal class ConstraintSystemImpl( + + override fun toBuilder(filterConstraintPosition: (ConstraintPosition) -> Boolean): ConstraintSystem.Builder { + val result = ConstraintSystemBuilderImpl() +- for ((typeParameter, typeBounds) in allTypeParameterBounds) { +- result.allTypeParameterBounds.put(typeParameter, typeBounds.filter(filterConstraintPosition)) ++ for (typeParameter in allTypeParameterBounds.entries) {","Since `entries` returns a destructurable class, I suppose you can keep the `for ((typeParameter, typeBounds) ...` syntax here",This was the only place where we used the ` +413,"@@ -176,6 +174,18 @@ class FoldConstantLowering(private val context: JvmBackendContext) : IrElementTr + else -> expression + } + } + -+private fun comparableVersionStr(version: String) = -+ ""(\\d+)\\.(\\d+).*"" -+ .toRegex() -+ .match(version) -+ ?.groups -+ ?.drop(1)?.take(2) -+ // checking if two subexpression groups are found and length of each is >0 and <4 -+ ?.let { if (it.all { (it?.value?.length() ?: 0).let { it > 0 && it < 4 }}) it else null } -+ ?.map { ""%3s"".format(it?.value ?: 0).replace(' ', '0') } -+ ?.joinToString(""."")","We can omit some of safe calls using `filterNotNull` and `padStart` trick: - -``` kotlin -private fun comparableVersionStr(version: String) = - ""(\\d+)\\.(\\d+).*"" - .toRegex() - .match(version) - ?.groups - ?.drop(1)?.take(2) - ?.filterNotNull() - // checking if two subexpression groups are found and length of each is >0 and <4 - ?.let { if (it.size() == 2 && it.all { it.value.length() in 1..3 }) it else null } - ?.map { it.value.padStart(3, '0') } - ?.joinToString(""."") -``` -","This is a bit confusing, as `totalMemor" -703,"@@ -18,72 +18,118 @@ ++ override fun visitStringConcatenation(expression: IrStringConcatenation): IrExpression { ++ expression.transformChildrenVoid(this) ++ return if (expression.arguments.all { it is IrConst<*> && it.value is String }) {","@pyos Seems it's possible to support some additional cases when begining of IrStringConcatenation is constant concatenation: +expression.arguments.takeWhile {it is IrConst<*> && it.value is String } and ...",This won't work for `IrConst<*>`. +414,"@@ -178,7 +181,7 @@ abstract class AbstractDebugTest : CodegenTestCase() { + var inBoxMethod = false + vmLoop@ + while (true) { +- val eventSet = virtualMachine.eventQueue().remove(1000) ++ val eventSet = virtualMachine.eventQueue().remove(1000) ?: continue",Seems it's equals to remove without timeout,This is the fix for the bug described in th +415,"@@ -1793,6 +1793,15 @@ + language=""kotlin"" + /> + ++ +