Dropped support for backing fields (with '$') completion

This commit is contained in:
Valentin Kipyatkov
2015-09-29 12:16:21 +03:00
parent 7c0b3e31c7
commit 72a5a68769
16 changed files with 3 additions and 318 deletions
@@ -20,7 +20,6 @@ import com.intellij.codeInsight.completion.*
import com.intellij.codeInsight.completion.impl.CamelHumpMatcher
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.patterns.ElementPattern
import com.intellij.patterns.StandardPatterns
import com.intellij.psi.PsiCompiledElement
import com.intellij.psi.PsiElement
@@ -38,11 +37,9 @@ import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.idea.resolve.frontendService
import org.jetbrains.kotlin.idea.util.CallType
import org.jetbrains.kotlin.idea.util.ShadowedDeclarationsFilter
import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
import org.jetbrains.kotlin.psi.psiUtil.prevLeaf
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfo
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
@@ -99,20 +96,8 @@ abstract class CompletionSession(protected val configuration: CompletionSessionC
protected val bindingContext: BindingContext = resolutionFacade.analyze(position.parentsWithSelf.firstIsInstance<JetElement>(), BodyResolveMode.PARTIAL_FOR_COMPLETION)
protected val inDescriptor: DeclarationDescriptor = position.getResolutionScope(bindingContext, resolutionFacade).ownerDescriptor
private val kotlinIdentifierStartPattern: ElementPattern<Char>
private val kotlinIdentifierPartPattern: ElementPattern<Char>
init {
val includeDollar = position.prevLeaf()?.getNode()?.getElementType() != JetTokens.SHORT_TEMPLATE_ENTRY_START
if (includeDollar) {
kotlinIdentifierStartPattern = StandardPatterns.character().javaIdentifierStart()
kotlinIdentifierPartPattern = StandardPatterns.character().javaIdentifierPart()
}
else {
kotlinIdentifierStartPattern = StandardPatterns.character().javaIdentifierStart() andNot singleCharPattern('$')
kotlinIdentifierPartPattern = StandardPatterns.character().javaIdentifierPart() andNot singleCharPattern('$')
}
}
private val kotlinIdentifierStartPattern = StandardPatterns.character().javaIdentifierStart() andNot singleCharPattern('$')
private val kotlinIdentifierPartPattern = StandardPatterns.character().javaIdentifierPart() andNot singleCharPattern('$')
protected val prefix: String = CompletionUtil.findIdentifierPrefix(
parameters.getPosition().getContainingFile(),
@@ -175,7 +160,7 @@ abstract class CompletionSession(protected val configuration: CompletionSessionC
} ?: emptyList()
}
LookupElementFactory(resolutionFacade, receiverTypes, contextType, inDescriptor, InsertHandlerProvider { expectedInfos }, contextVariablesProvider)
LookupElementFactory(resolutionFacade, receiverTypes, contextType, InsertHandlerProvider { expectedInfos }, contextVariablesProvider)
}
// LookupElementsCollector instantiation is deferred because virtual call to createSorter uses data from derived classes
@@ -22,7 +22,6 @@ import com.intellij.codeInsight.lookup.LookupElementDecorator
import com.intellij.codeInsight.lookup.LookupElementPresentation
import com.intellij.codeInsight.lookup.impl.LookupCellRenderer
import com.intellij.psi.PsiClass
import com.intellij.util.PlatformIcons
import com.intellij.util.SmartList
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.*
@@ -33,11 +32,7 @@ import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.idea.util.FuzzyType
import org.jetbrains.kotlin.idea.util.fuzzyReturnType
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.JetProperty
import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
import org.jetbrains.kotlin.synthetic.SamAdapterExtensionFunctionDescriptor
@@ -50,7 +45,6 @@ class LookupElementFactory(
private val resolutionFacade: ResolutionFacade,
private val receiverTypes: Collection<JetType>,
private val contextType: LookupElementFactory.ContextType,
private val inDescriptor: DeclarationDescriptor?,
public val insertHandlerProvider: InsertHandlerProvider,
contextVariablesProvider: () -> Collection<VariableDescriptor>
) {
@@ -80,16 +74,6 @@ class LookupElementFactory(
result.addSpecialFunctionCallElements(descriptor, useReceiverTypes)
}
if (descriptor is PropertyDescriptor && inDescriptor != null) {
var backingFieldElement = createBackingFieldLookupElement(descriptor, useReceiverTypes)
if (backingFieldElement != null) {
if (contextType == ContextType.STRING_TEMPLATE_AFTER_DOLLAR) {
backingFieldElement = backingFieldElement.withBracesSurrounding()
}
result.add(backingFieldElement)
}
}
return result
}
@@ -199,35 +183,6 @@ class LookupElementFactory(
}
}
private fun createBackingFieldLookupElement(property: PropertyDescriptor, useReceiverTypes: Boolean): LookupElement? {
if (inDescriptor == null) return null
val insideAccessor = inDescriptor is PropertyAccessorDescriptor && inDescriptor.getCorrespondingProperty() == property
if (!insideAccessor) {
val container = property.getContainingDeclaration()
if (container !is ClassDescriptor || !DescriptorUtils.isAncestor(container, inDescriptor, false)) return null // backing field not accessible
}
val declaration = (DescriptorToSourceUtils.descriptorToDeclaration(property) as? JetProperty) ?: return null
val accessors = declaration.getAccessors()
if (accessors.all { it.getBodyExpression() == null }) return null // makes no sense to access backing field - it's the same as accessing property directly
val bindingContext = resolutionFacade.analyze(declaration)
if (!bindingContext[BindingContext.BACKING_FIELD_REQUIRED, property]!!) return null
val lookupElement = createLookupElement(property, useReceiverTypes)
return object : LookupElementDecorator<LookupElement>(lookupElement) {
override fun getLookupString() = "$" + super.getLookupString()
override fun getAllLookupStrings() = setOf(getLookupString())
override fun renderElement(presentation: LookupElementPresentation) {
super.renderElement(presentation)
presentation.setItemText("$" + presentation.getItemText())
presentation.setIcon(PlatformIcons.FIELD_ICON) //TODO: special icon
}
}.assignPriority(ItemPriority.BACKING_FIELD)
}
public fun createLookupElement(
descriptor: DeclarationDescriptor,
useReceiverTypes: Boolean,
@@ -1,26 +0,0 @@
var globalProperty = "abc" // has backing field and accessor but backing field is not accessible
get() = $globalProperty + 1
class C {
var property1 = "abc" // has backing field but accessors are default - no sense to show in completion
var property2 = "abc" // has backing field but accessors are also default
private set
var property3: String // no backing field
get() = "abc"
set(value){}
var property4 = "abc" // has backing field and accessor
get() = $property4 + 1
fun foo(){
<caret>
}
}
// ABSENT: $globalProperty
// ABSENT: $property1
// ABSENT: $property2
// ABSENT: $property3
// EXIST: { lookupString: "$property4", itemText: "$property4", tailText: null, typeText: "String" }
@@ -1,4 +0,0 @@
var globalProperty = "abc"
get() = <caret>
// EXIST: $globalProperty
@@ -1,11 +0,0 @@
class C {
var property = "abc"
get() = $property + 1
}
fun foo(c: C){
c.<caret>
}
// ABSENT: $property
@@ -1,10 +0,0 @@
class C {
var property = "abc"
get() = $property + 1
fun foo() {
this.<caret>
}
}
// EXIST: $property
@@ -1,15 +0,0 @@
class C {
var property1 = "abc"
get() = $property1 + 1
var property2 = "abc"
get() = $property2 + 1
fun foo(){
$<caret>
}
}
// EXIST: $property1
// EXIST: $property2
// ABSENT: property1
// ABSENT: property2
@@ -1,13 +0,0 @@
class C {
var aProperty = "abc"
get() {}
var bProperty = "abc"
get() {}
fun foo(){
$a<caret>
}
}
// EXIST: $aProperty
// ABSENT: $bProperty
@@ -1,15 +0,0 @@
class C {
var property1 = "abc"
get() = $property1 + 1
var property2 = "abc"
get() = $property2 + 1
fun foo(){
"${$<caret>}"
}
}
// EXIST: $property1
// EXIST: $property2
// ABSENT: property1
// ABSENT: property2
@@ -1,10 +0,0 @@
class C {
var property = "abc"
get() = $property + 1
fun foo(){
"$<caret>"
}
}
// ELEMENT: $property
@@ -1,10 +0,0 @@
class C {
var property = "abc"
get() = $property + 1
fun foo(){
"${$property<caret>}"
}
}
// ELEMENT: $property
-27
View File
@@ -1,27 +0,0 @@
class C {
var property1 = "abc" // has backing field but accessors are default - no sense to show in completion
var property2: String // no backing field
get() = "abc"
set(value){}
var property3 = "abc" // has backing field and accessor
get() = $property3 + 1
var property4 = 1
get() = $property4 + 1
var property5: String? = null
get() = $property3 + 1
fun foo(): String {
return <caret>
}
}
// ABSENT: $property1
// ABSENT: $property2
// EXIST: $property3
// ABSENT: $property4
// EXIST: { itemText: "!! $property5" }
// EXIST: { itemText: "?: $property5" }
@@ -955,57 +955,6 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes
}
}
@TestMetadata("idea/idea-completion/testData/basic/common/backingFields")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class BackingFields extends AbstractJSBasicCompletionTest {
public void testAllFilesPresentInBackingFields() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/basic/common/backingFields"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("BackingFields1.kt")
public void testBackingFields1() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/backingFields/BackingFields1.kt");
doTest(fileName);
}
@TestMetadata("BackingFields2.kt")
public void testBackingFields2() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/backingFields/BackingFields2.kt");
doTest(fileName);
}
@TestMetadata("BackingFields3.kt")
public void testBackingFields3() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/backingFields/BackingFields3.kt");
doTest(fileName);
}
@TestMetadata("BackingFields4.kt")
public void testBackingFields4() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/backingFields/BackingFields4.kt");
doTest(fileName);
}
@TestMetadata("BackingFields5.kt")
public void testBackingFields5() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/backingFields/BackingFields5.kt");
doTest(fileName);
}
@TestMetadata("BackingFields6.kt")
public void testBackingFields6() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/backingFields/BackingFields6.kt");
doTest(fileName);
}
@TestMetadata("BackingFieldsInStringTemplate.kt")
public void testBackingFieldsInStringTemplate() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/backingFields/BackingFieldsInStringTemplate.kt");
doTest(fileName);
}
}
@TestMetadata("idea/idea-completion/testData/basic/common/boldOrGrayed")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -955,57 +955,6 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT
}
}
@TestMetadata("idea/idea-completion/testData/basic/common/backingFields")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class BackingFields extends AbstractJvmBasicCompletionTest {
public void testAllFilesPresentInBackingFields() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/basic/common/backingFields"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("BackingFields1.kt")
public void testBackingFields1() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/backingFields/BackingFields1.kt");
doTest(fileName);
}
@TestMetadata("BackingFields2.kt")
public void testBackingFields2() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/backingFields/BackingFields2.kt");
doTest(fileName);
}
@TestMetadata("BackingFields3.kt")
public void testBackingFields3() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/backingFields/BackingFields3.kt");
doTest(fileName);
}
@TestMetadata("BackingFields4.kt")
public void testBackingFields4() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/backingFields/BackingFields4.kt");
doTest(fileName);
}
@TestMetadata("BackingFields5.kt")
public void testBackingFields5() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/backingFields/BackingFields5.kt");
doTest(fileName);
}
@TestMetadata("BackingFields6.kt")
public void testBackingFields6() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/backingFields/BackingFields6.kt");
doTest(fileName);
}
@TestMetadata("BackingFieldsInStringTemplate.kt")
public void testBackingFieldsInStringTemplate() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/backingFields/BackingFieldsInStringTemplate.kt");
doTest(fileName);
}
}
@TestMetadata("idea/idea-completion/testData/basic/common/boldOrGrayed")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -65,12 +65,6 @@ public class JvmSmartCompletionTestGenerated extends AbstractJvmSmartCompletionT
doTest(fileName);
}
@TestMetadata("BackingFields.kt")
public void testBackingFields() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/smart/BackingFields.kt");
doTest(fileName);
}
@TestMetadata("BeforeArgumentWithBinaryOperation.kt")
public void testBeforeArgumentWithBinaryOperation() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/smart/BeforeArgumentWithBinaryOperation.kt");
@@ -475,12 +475,6 @@ public class BasicCompletionHandlerTestGenerated extends AbstractBasicCompletion
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/handlers/basic/stringTemplate"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("BackingField.kt")
public void testBackingField() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/stringTemplate/BackingField.kt");
doTest(fileName);
}
@TestMetadata("NotEmptyPrefix.kt")
public void testNotEmptyPrefix() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/stringTemplate/NotEmptyPrefix.kt");