Implement for/iter postfix templates
#KT-4710 In Progress
This commit is contained in:
committed by
Nikolay Krasko
parent
b702886f0d
commit
1b391123e6
@@ -60,6 +60,7 @@ fun KotlinType.isBoolean(): Boolean = KotlinBuiltIns.isBoolean(this)
|
||||
fun KotlinType.isPrimitiveNumberType(): Boolean = KotlinBuiltIns.isPrimitiveType(this) && !isBoolean()
|
||||
fun KotlinType.isBooleanOrNullableBoolean(): Boolean = KotlinBuiltIns.isBooleanOrNullableBoolean(this)
|
||||
fun KotlinType.isThrowable(): Boolean = isConstructedFromClassWithGivenFqName(KotlinBuiltIns.FQ_NAMES.throwable) && !isMarkedNullable
|
||||
fun KotlinType.isIterator(): Boolean = isConstructedFromClassWithGivenFqName(KotlinBuiltIns.FQ_NAMES.iterator) && !isMarkedNullable
|
||||
|
||||
fun KotlinType.isConstructedFromClassWithGivenFqName(fqName: FqName) =
|
||||
(constructor.declarationDescriptor as? ClassDescriptor)?.fqNameUnsafe == fqName.toUnsafe()
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
fun bar() = 1
|
||||
fun foo() {
|
||||
val bar = bar()
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fun foo(list: List<String>) {
|
||||
<spot>list</spot>$key
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
Creates for statement from given iterable expression.
|
||||
</body>
|
||||
</html>
|
||||
@@ -44,7 +44,9 @@ class KtPostfixTemplateProvider : PostfixTemplateProvider {
|
||||
KtWhenExpressionPostfixTemplate,
|
||||
KtTryPostfixTemplate,
|
||||
KtIntroduceVariablePostfixTemplate("val"),
|
||||
KtIntroduceVariablePostfixTemplate("var")
|
||||
KtIntroduceVariablePostfixTemplate("var"),
|
||||
KtForEachPostfixTemplate("for"),
|
||||
KtForEachPostfixTemplate("iter")
|
||||
)
|
||||
|
||||
override fun isTerminalSymbol(currentChar: Char) = currentChar == '.' || currentChar == '!'
|
||||
|
||||
@@ -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.codeInsight.postfix
|
||||
|
||||
import com.intellij.codeInsight.template.Template
|
||||
import com.intellij.codeInsight.template.impl.ConstantNode
|
||||
import com.intellij.codeInsight.template.impl.MacroCallNode
|
||||
import com.intellij.codeInsight.template.postfix.templates.StringBasedPostfixTemplate
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.idea.liveTemplates.macro.SuggestVariableNameMacro
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.typeUtil.isIterator
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
|
||||
internal class KtForEachPostfixTemplate(
|
||||
name: String
|
||||
) : StringBasedPostfixTemplate(name, "for (item in expr)", createExpressionSelector(statementsOnly = true, predicate = KotlinType::containsIteratorMethod)) {
|
||||
override fun getTemplateString(element: PsiElement) = "for (\$name$ in \$expr$) {\n \$END$\n}"
|
||||
|
||||
override fun setVariables(template: Template, element: PsiElement) {
|
||||
val name = MacroCallNode(SuggestVariableNameMacro())
|
||||
template.addVariable("name", name, ConstantNode("item"), true)
|
||||
}
|
||||
|
||||
override fun getElementToRemove(expr: PsiElement?) = expr
|
||||
}
|
||||
|
||||
private fun KotlinType.containsIteratorMethod() =
|
||||
memberScope.getContributedFunctions(OperatorNameConventions.ITERATOR, NoLookupLocation.FROM_IDE).any {
|
||||
it.returnType?.isIterator() ?: false && it.valueParameters.isEmpty()
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun foo(list: List<String>) {
|
||||
list.for<caret>
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
fun foo(list: List<String>) {
|
||||
for (s in list) {
|
||||
<caret>
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun foo(list: List<String>) {
|
||||
list.iter<caret>
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
fun foo(list: List<String>) {
|
||||
for (s in list) {
|
||||
<caret>
|
||||
}
|
||||
}
|
||||
+12
@@ -41,12 +41,24 @@ public class PostfixTemplateProviderTestGenerated extends AbstractPostfixTemplat
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("for.kt")
|
||||
public void testFor() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/postfix/for.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("if.kt")
|
||||
public void testIf() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/postfix/if.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("iter.kt")
|
||||
public void testIter() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/postfix/iter.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("notBoolean.kt")
|
||||
public void testNotBoolean() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/postfix/notBoolean.kt");
|
||||
|
||||
Reference in New Issue
Block a user