Create From Usage: Quote declaration name if it's not a valid identifier

#EA-70291 Fixed
This commit is contained in:
Alexey Sedunov
2015-08-18 18:24:35 +03:00
parent d18a9f6d8a
commit 85f85e85b4
12 changed files with 78 additions and 5 deletions
@@ -449,7 +449,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
CallableKind.PROPERTY -> ""
}
val returnTypeString = if (skipReturnType || assignmentToReplace != null) "" else ": Any"
val header = "$ownerTypeString${callableInfo.name}$paramList$returnTypeString"
val header = "$ownerTypeString${callableInfo.name.quoteIfNeeded()}$paramList$returnTypeString"
val psiFactory = JetPsiFactory(currentFile)
@@ -479,11 +479,12 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
ClassKind.ANNOTATION_CLASS, ClassKind.ENUM_ENTRY -> ""
else -> "{\n\n}"
}
val safeName = name.quoteIfNeeded()
when (kind) {
ClassKind.ENUM_ENTRY -> {
if (!(targetParent is JetClass && targetParent.isEnum())) throw AssertionError("Enum class expected: ${targetParent.getText()}")
val hasParameters = targetParent.getPrimaryConstructorParameters().isNotEmpty()
psiFactory.createEnumEntry("$name${if (hasParameters) "()" else " "}")
psiFactory.createEnumEntry("$safeName${if (hasParameters) "()" else " "}")
}
else -> {
val openMod = if (open) "open " else ""
@@ -493,7 +494,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
else -> ""
}
psiFactory.createDeclaration<JetClassOrObject>(
"$openMod$innerMod${kind.keyword} $name$typeParamList$paramList$returnTypeString $classBody"
"$openMod$innerMod${kind.keyword} $safeName$typeParamList$paramList$returnTypeString $classBody"
)
}
}
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.core.compareDescriptors
import org.jetbrains.kotlin.idea.core.refactoring.quoteIfNeeded
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.JetCallableDefinitionUsage
import org.jetbrains.kotlin.idea.references.JetReference
import org.jetbrains.kotlin.idea.references.mainReference
@@ -200,7 +201,7 @@ public class JetParameterInfo(
buffer.append(valOrVar).append(' ')
}
buffer.append(getInheritedName(inheritedCallable))
buffer.append(getInheritedName(inheritedCallable).quoteIfNeeded())
if (requiresExplicitType(inheritedCallable)) {
buffer.append(": ").append(renderType(parameterIndex, inheritedCallable))
@@ -66,6 +66,7 @@ import org.jetbrains.kotlin.idea.JetFileType
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.getJavaMemberDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
import org.jetbrains.kotlin.idea.core.KotlinNameSuggester
import org.jetbrains.kotlin.idea.core.getPackage
import org.jetbrains.kotlin.idea.j2k.IdeaJavaToKotlinServices
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
@@ -661,4 +662,6 @@ public fun invokeOnceOnCommandFinish(action: () -> Unit) {
}
}
commandProcessor.addCommandListener(listener)
}
}
public fun String.quoteIfNeeded(): String = if (KotlinNameSuggester.isIdentifier(this)) this else "`$this`"
@@ -0,0 +1,4 @@
// "Create class 'A\u00A0'" "true"
fun test() {
val t = <caret>`A\u00A0`(1)
}
@@ -0,0 +1,8 @@
// "Create class 'A\u00A0'" "true"
fun test() {
val t = `A\u00A0`(1)
}
class `A\u00A0`(i: Int) {
}
@@ -0,0 +1,4 @@
// "Create extension function '\u00A0'" "true"
fun test() {
val t: Int = 1 <caret>`\u00A0` 2
}
@@ -0,0 +1,8 @@
// "Create extension function '\u00A0'" "true"
fun test() {
val t: Int = 1 `\u00A0` 2
}
fun Int.`\u00A0`(i: Int): Int {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@@ -0,0 +1,4 @@
// "Create parameter '\u00A0'" "true"
fun test() {
val t: Int = <caret>`\u00A0`
}
@@ -0,0 +1,4 @@
// "Create parameter '\u00A0'" "true"
fun test(`\u00A0`: Int) {
val t: Int = `\u00A0`
}
@@ -0,0 +1,5 @@
// "Create property '\u00A0'" "true"
// ERROR: Property must be initialized
fun test() {
val t: Int = <caret>`\u00A0`
}
@@ -0,0 +1,7 @@
val `\u00A0`: Int
// "Create property '\u00A0'" "true"
// ERROR: Property must be initialized
fun test() {
val t: Int = `\u00A0`
}
@@ -920,6 +920,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
doTest(fileName);
}
@TestMetadata("quotedName.kt")
public void testQuotedName() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createClass/callExpression/quotedName.kt");
doTest(fileName);
}
@TestMetadata("singleArgCallInAnnotationEntry.kt")
public void testSingleArgCallInAnnotationEntry() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createClass/callExpression/singleArgCallInAnnotationEntry.kt");
@@ -1547,6 +1553,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
doTest(fileName);
}
@TestMetadata("quotedName.kt")
public void testQuotedName() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/binaryOperations/quotedName.kt");
doTest(fileName);
}
@TestMetadata("whenInOnUserType.kt")
public void testWhenInOnUserType() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/binaryOperations/whenInOnUserType.kt");
@@ -2672,6 +2684,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
doTest(fileName);
}
@TestMetadata("quotedName.kt")
public void testQuotedName() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/parameter/quotedName.kt");
doTest(fileName);
}
@TestMetadata("recursiveBound.kt")
public void testRecursiveBound() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/parameter/recursiveBound.kt");
@@ -2759,6 +2777,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
doTest(fileName);
}
@TestMetadata("quotedName.kt")
public void testQuotedName() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/property/quotedName.kt");
doTest(fileName);
}
@TestMetadata("recursiveBound.kt")
public void testRecursiveBound() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/property/recursiveBound.kt");