KT-6050 Support completion for super qualifier
#KT-6050 Fixed
This commit is contained in:
+37
-5
@@ -27,6 +27,7 @@ import com.intellij.psi.JavaPsiFacade
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.intellij.util.ProcessingContext
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
|
||||
@@ -39,12 +40,10 @@ import org.jetbrains.kotlin.idea.stubindex.PackageIndexUtil
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindExclude
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||
|
||||
class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
||||
parameters: CompletionParameters,
|
||||
@@ -79,7 +78,9 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
||||
|
||||
NAMED_ARGUMENTS_ONLY(descriptorKindFilter = null, classKindFilter = null),
|
||||
|
||||
PARAMETER_NAME(descriptorKindFilter = null, classKindFilter = null)
|
||||
PARAMETER_NAME(descriptorKindFilter = null, classKindFilter = null),
|
||||
|
||||
SUPER_QUALIFIER(descriptorKindFilter = DescriptorKindFilter.NON_SINGLETON_CLASSIFIERS, classKindFilter = null)
|
||||
}
|
||||
|
||||
private val completionKind = calcCompletionKind()
|
||||
@@ -136,6 +137,10 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
||||
// expression we are at first of it
|
||||
val typeReference = position.getStrictParentOfType<JetTypeReference>()
|
||||
if (typeReference != null) {
|
||||
if (typeReference.parent is JetSuperExpression) {
|
||||
return CompletionKind.SUPER_QUALIFIER
|
||||
}
|
||||
|
||||
val firstPartReference = PsiTreeUtil.findChildOfType(typeReference, javaClass<JetSimpleNameExpression>())
|
||||
if (firstPartReference == nameExpression) {
|
||||
return CompletionKind.TYPES
|
||||
@@ -182,6 +187,11 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
||||
}
|
||||
}
|
||||
|
||||
if (completionKind == CompletionKind.SUPER_QUALIFIER) {
|
||||
completeSuperQualifier()
|
||||
return
|
||||
}
|
||||
|
||||
// if we are typing parameter name, restart completion each time we type an upper case letter because new suggestions will appear (previous words can be used as user prefix)
|
||||
if (parameterNameAndTypeCompletion != null) {
|
||||
val prefixPattern = StandardPatterns.string().with(object : PatternCondition<String>("Prefix ends with uppercase letter") {
|
||||
@@ -306,6 +316,28 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
||||
parameterNameAndTypeCompletion?.addFromAllClasses(parameters, indicesHelper)
|
||||
}
|
||||
|
||||
private fun completeSuperQualifier() {
|
||||
val classOrObject = position.parents.firstIsInstanceOrNull<JetClassOrObject>() ?: return
|
||||
val classDescriptor = resolutionFacade.resolveToDescriptor(classOrObject) as ClassDescriptor
|
||||
var superClasses = classDescriptor.defaultType.constructor.supertypes
|
||||
.map { it.constructor.declarationDescriptor as? ClassDescriptor }
|
||||
.filterNotNull()
|
||||
|
||||
//TODO: IMO it's not good that Any is to be added manually
|
||||
if (superClasses.all { it.kind == ClassKind.INTERFACE }) {
|
||||
superClasses += KotlinBuiltIns.getInstance().any
|
||||
}
|
||||
|
||||
if (!isNoQualifierContext()) {
|
||||
val referenceVariantsSet = referenceVariants.toSet()
|
||||
superClasses = superClasses.filter { it in referenceVariantsSet }
|
||||
}
|
||||
|
||||
superClasses
|
||||
.map { lookupElementFactory.createLookupElement(it, boldImmediateMembers = false, qualifyNestedClasses = true, includeClassTypeArguments = false) }
|
||||
.forEach { collector.addElement(it) }
|
||||
}
|
||||
|
||||
override fun createSorter(): CompletionSorter {
|
||||
var sorter = super.createSorter()
|
||||
|
||||
|
||||
+12
@@ -74,6 +74,8 @@ public class KotlinCompletionContributor : CompletionContributor() {
|
||||
|
||||
isInClassHeader(tokenBefore) -> CompletionUtilCore.DUMMY_IDENTIFIER // do not add '$' to not interrupt class declaration parsing
|
||||
|
||||
isInUnclosedSuperQualifier(tokenBefore) -> CompletionUtilCore.DUMMY_IDENTIFIER_TRIMMED + ">"
|
||||
|
||||
else -> specialLambdaSignatureDummyIdentifier(tokenBefore)
|
||||
?: specialExtensionReceiverDummyIdentifier(tokenBefore)
|
||||
?: specialInTypeArgsDummyIdentifier(tokenBefore)
|
||||
@@ -415,4 +417,14 @@ public class KotlinCompletionContributor : CompletionContributor() {
|
||||
}
|
||||
return balance
|
||||
}
|
||||
|
||||
private fun isInUnclosedSuperQualifier(tokenBefore: PsiElement?): Boolean {
|
||||
if (tokenBefore == null) return false
|
||||
val tokensToSkip = TokenSet.orSet(TokenSet.create(JetTokens.IDENTIFIER, JetTokens.DOT ), JetTokens.WHITE_SPACE_OR_COMMENT_BIT_SET)
|
||||
val tokens = sequence(tokenBefore) { it.prevLeaf() }
|
||||
val ltToken = tokens.firstOrNull { it.node.elementType !in tokensToSkip } ?: return false
|
||||
if (ltToken.node.elementType != JetTokens.LT) return false
|
||||
val superToken = ltToken.prevLeaf { it !is PsiWhiteSpace && it !is PsiComment }
|
||||
return superToken?.node?.elementType == JetTokens.SUPER_KEYWORD
|
||||
}
|
||||
}
|
||||
|
||||
+4
-1
@@ -146,7 +146,9 @@ public class LookupElementFactory(
|
||||
if (nestLevel > 0) {
|
||||
var itemText = psiClass.getName()
|
||||
for (i in 1..nestLevel) {
|
||||
itemText = containerName.substringAfterLast('.') + "." + itemText
|
||||
val outerClassName = containerName.substringAfterLast('.')
|
||||
element = element.withLookupString(outerClassName)
|
||||
itemText = outerClassName + "." + itemText
|
||||
containerName = containerName.substringBeforeLast('.', FqName.ROOT.toString())
|
||||
}
|
||||
element = element.withPresentableText(itemText!!)
|
||||
@@ -246,6 +248,7 @@ public class LookupElementFactory(
|
||||
element = element.withPresentableText(DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderClassifierName(descriptor))
|
||||
|
||||
while (container is ClassDescriptor) {
|
||||
element = element.withLookupString(container.name.asString())
|
||||
container = container.getContainingDeclaration()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package Test
|
||||
|
||||
import <caret>
|
||||
|
||||
// EXIST: java,
|
||||
// EXIST: java
|
||||
// EXIST_JAVA_ONLY: javax
|
||||
// EXIST_JS_ONLY: jquery, html5
|
||||
// ABSENT: Array, Integer
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
open class Base
|
||||
|
||||
open class A : Base
|
||||
|
||||
interface I
|
||||
|
||||
class B : A(), I {
|
||||
fun foo() {
|
||||
super<<caret>
|
||||
}
|
||||
}
|
||||
|
||||
// EXIST: A
|
||||
// EXIST: I
|
||||
// NOTHING_ELSE
|
||||
@@ -0,0 +1,13 @@
|
||||
open class A
|
||||
|
||||
interface I
|
||||
|
||||
class B : A(), I {
|
||||
fun foo() {
|
||||
super<<caret>>
|
||||
}
|
||||
}
|
||||
|
||||
// EXIST: A
|
||||
// EXIST: I
|
||||
// NOTHING_ELSE
|
||||
@@ -0,0 +1,13 @@
|
||||
open class AA
|
||||
|
||||
interface AI
|
||||
|
||||
class B : AA(), AI {
|
||||
fun foo() {
|
||||
super<A<caret>
|
||||
}
|
||||
}
|
||||
|
||||
// EXIST: AA
|
||||
// EXIST: AI
|
||||
// NOTHING_ELSE
|
||||
@@ -0,0 +1,17 @@
|
||||
package p
|
||||
|
||||
open class A
|
||||
|
||||
interface I {
|
||||
interface Nested
|
||||
}
|
||||
|
||||
class B : A(), I.Nested {
|
||||
fun foo() {
|
||||
super<<caret>
|
||||
}
|
||||
}
|
||||
|
||||
// EXIST: A
|
||||
// EXIST: { lookupString: "Nested", allLookupStrings: "I, Nested", itemText: "I.Nested", tailText: " (p)" }
|
||||
// NOTHING_ELSE
|
||||
@@ -0,0 +1,16 @@
|
||||
package p
|
||||
|
||||
open class A
|
||||
|
||||
interface I {
|
||||
interface Nested
|
||||
}
|
||||
|
||||
class B : A(), I.Nested {
|
||||
fun foo() {
|
||||
super<I<caret>
|
||||
}
|
||||
}
|
||||
|
||||
// EXIST: { lookupString: "Nested", allLookupStrings: "I, Nested", itemText: "I.Nested", tailText: " (p)" }
|
||||
// NOTHING_ELSE
|
||||
@@ -0,0 +1,17 @@
|
||||
package p
|
||||
|
||||
open class A
|
||||
|
||||
interface I {
|
||||
interface Nested1
|
||||
interface Nested2
|
||||
}
|
||||
|
||||
class B : A(), I.Nested1 {
|
||||
fun foo() {
|
||||
super<I.<caret>
|
||||
}
|
||||
}
|
||||
|
||||
// EXIST: Nested1
|
||||
// NOTHING_ELSE
|
||||
@@ -0,0 +1,11 @@
|
||||
interface I
|
||||
|
||||
class B : I {
|
||||
fun foo() {
|
||||
super<<caret>
|
||||
}
|
||||
}
|
||||
|
||||
// EXIST: Any
|
||||
// EXIST: I
|
||||
// NOTHING_ELSE
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
interface X
|
||||
|
||||
interface I : X {
|
||||
fun foo() {
|
||||
super<<caret>
|
||||
}
|
||||
}
|
||||
|
||||
// EXIST: Any
|
||||
// EXIST: X
|
||||
// NOTHING_ELSE
|
||||
@@ -0,0 +1,11 @@
|
||||
open class A<T>
|
||||
|
||||
interface I
|
||||
|
||||
class B : A<String>(), I {
|
||||
fun foo() {
|
||||
super<<caret>
|
||||
}
|
||||
}
|
||||
|
||||
// EXIST: { itemText: "A", tailText: " (<root>)" }
|
||||
-370
@@ -1,370 +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.completion.test;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Collections2;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupElementPresentation;
|
||||
import com.intellij.codeInsight.lookup.impl.LookupCellRenderer;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.JBColor;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.idea.test.AstAccessControl;
|
||||
import org.jetbrains.kotlin.js.resolve.JsPlatform;
|
||||
import org.jetbrains.kotlin.resolve.TargetPlatform;
|
||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform;
|
||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils;
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Extract a number of statements about completion from the given text. Those statements
|
||||
* should be asserted during test execution.
|
||||
*/
|
||||
public class ExpectedCompletionUtils {
|
||||
private ExpectedCompletionUtils() {
|
||||
}
|
||||
|
||||
public static class CompletionProposal {
|
||||
public static final String LOOKUP_STRING = "lookupString";
|
||||
public static final String PRESENTATION_ITEM_TEXT = "itemText";
|
||||
public static final String PRESENTATION_TYPE_TEXT = "typeText";
|
||||
public static final String PRESENTATION_TAIL_TEXT = "tailText";
|
||||
public static final String PRESENTATION_TEXT_ATTRIBUTES = "attributes";
|
||||
public static final Set<String> validKeys = new HashSet<String>(
|
||||
Arrays.asList(LOOKUP_STRING, PRESENTATION_ITEM_TEXT, PRESENTATION_TYPE_TEXT, PRESENTATION_TAIL_TEXT,
|
||||
PRESENTATION_TEXT_ATTRIBUTES)
|
||||
);
|
||||
|
||||
private final Map<String, String> map;
|
||||
|
||||
public CompletionProposal(@NotNull String lookupString) {
|
||||
map = new HashMap<String, String>();
|
||||
map.put(LOOKUP_STRING, lookupString);
|
||||
}
|
||||
|
||||
public CompletionProposal(@NotNull Map<String, String> map) {
|
||||
this.map = map;
|
||||
for (String key : map.keySet()) {
|
||||
if (!validKeys.contains(key)){
|
||||
throw new RuntimeException("Invalid key '" + key + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public CompletionProposal(@NotNull JsonObject json) {
|
||||
map = new HashMap<String, String>();
|
||||
for (Map.Entry<String, JsonElement> entry : json.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
if (!validKeys.contains(key)) {
|
||||
throw new RuntimeException("Invalid json property '" + key + "'");
|
||||
}
|
||||
JsonElement value = entry.getValue();
|
||||
if (!(value instanceof JsonNull)) {
|
||||
map.put(key, value.getAsString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean matches(CompletionProposal expectedProposal) {
|
||||
for (Map.Entry<String, String> entry : expectedProposal.map.entrySet()) {
|
||||
if (!entry.getValue().equals(map.get(entry.getKey()))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
for (Map.Entry<String, String> entry : map.entrySet()) {
|
||||
jsonObject.addProperty(entry.getKey(), entry.getValue());
|
||||
}
|
||||
return jsonObject.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private static final String UNSUPPORTED_PLATFORM_MESSAGE = String.format("Only %s and %s platforms are supported", JvmPlatform.INSTANCE$, JsPlatform.INSTANCE$);
|
||||
|
||||
private static final String EXIST_LINE_PREFIX = "EXIST:";
|
||||
|
||||
private static final String ABSENT_LINE_PREFIX = "ABSENT:";
|
||||
private static final String ABSENT_JS_LINE_PREFIX = "ABSENT_JS:";
|
||||
private static final String ABSENT_JAVA_LINE_PREFIX = "ABSENT_JAVA:";
|
||||
|
||||
private static final String EXIST_JAVA_ONLY_LINE_PREFIX = "EXIST_JAVA_ONLY:";
|
||||
private static final String EXIST_JS_ONLY_LINE_PREFIX = "EXIST_JS_ONLY:";
|
||||
|
||||
private static final String NUMBER_LINE_PREFIX = "NUMBER:";
|
||||
private static final String NUMBER_JS_LINE_PREFIX = "NUMBER_JS:";
|
||||
private static final String NUMBER_JAVA_LINE_PREFIX = "NUMBER_JAVA:";
|
||||
|
||||
private static final String NOTHING_ELSE_PREFIX = "NOTHING_ELSE";
|
||||
|
||||
private static final String INVOCATION_COUNT_PREFIX = "INVOCATION_COUNT:";
|
||||
private static final String WITH_ORDER_PREFIX = "WITH_ORDER";
|
||||
private static final String AUTOCOMPLETE_SETTING_PREFIX = "AUTOCOMPLETE_SETTING:";
|
||||
|
||||
public static final String RUNTIME_TYPE = "RUNTIME_TYPE:";
|
||||
|
||||
public static final List<String> KNOWN_PREFIXES = ImmutableList.of(
|
||||
EXIST_LINE_PREFIX,
|
||||
ABSENT_LINE_PREFIX,
|
||||
ABSENT_JS_LINE_PREFIX,
|
||||
ABSENT_JAVA_LINE_PREFIX,
|
||||
EXIST_JAVA_ONLY_LINE_PREFIX,
|
||||
EXIST_JS_ONLY_LINE_PREFIX,
|
||||
NUMBER_LINE_PREFIX,
|
||||
NUMBER_JS_LINE_PREFIX,
|
||||
NUMBER_JAVA_LINE_PREFIX,
|
||||
INVOCATION_COUNT_PREFIX,
|
||||
WITH_ORDER_PREFIX,
|
||||
AUTOCOMPLETE_SETTING_PREFIX,
|
||||
NOTHING_ELSE_PREFIX,
|
||||
RUNTIME_TYPE,
|
||||
AstAccessControl.INSTANCE$.getALLOW_AST_ACCESS_DIRECTIVE());
|
||||
|
||||
@NotNull
|
||||
public static CompletionProposal[] itemsShouldExist(String fileText, @Nullable TargetPlatform platform) {
|
||||
if (platform == null) {
|
||||
return processProposalAssertions(fileText, EXIST_LINE_PREFIX);
|
||||
}
|
||||
else if (platform == JvmPlatform.INSTANCE$) {
|
||||
return processProposalAssertions(fileText, EXIST_LINE_PREFIX, EXIST_JAVA_ONLY_LINE_PREFIX);
|
||||
}
|
||||
else if (platform == JsPlatform.INSTANCE$) {
|
||||
return processProposalAssertions(fileText, EXIST_LINE_PREFIX, EXIST_JS_ONLY_LINE_PREFIX);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException(UNSUPPORTED_PLATFORM_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static CompletionProposal[] itemsShouldAbsent(String fileText, @Nullable TargetPlatform platform) {
|
||||
if (platform == null) {
|
||||
return processProposalAssertions(fileText, ABSENT_LINE_PREFIX);
|
||||
}
|
||||
else if (platform == JvmPlatform.INSTANCE$) {
|
||||
return processProposalAssertions(fileText, ABSENT_LINE_PREFIX, ABSENT_JAVA_LINE_PREFIX, EXIST_JS_ONLY_LINE_PREFIX);
|
||||
}
|
||||
else if (platform == JsPlatform.INSTANCE$) {
|
||||
return processProposalAssertions(fileText, ABSENT_LINE_PREFIX, ABSENT_JS_LINE_PREFIX, EXIST_JAVA_ONLY_LINE_PREFIX);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException(UNSUPPORTED_PLATFORM_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
public static CompletionProposal[] processProposalAssertions(String fileText, String... prefixes) {
|
||||
Collection<CompletionProposal> proposals = new ArrayList<CompletionProposal>();
|
||||
for (String proposalStr : InTextDirectivesUtils.findLinesWithPrefixesRemoved(fileText, prefixes)) {
|
||||
if (proposalStr.startsWith("{")){
|
||||
JsonParser parser = new JsonParser();
|
||||
JsonElement json = parser.parse(proposalStr);
|
||||
proposals.add(new CompletionProposal((JsonObject) json));
|
||||
}
|
||||
else if (proposalStr.startsWith("\"") && proposalStr.endsWith("\"")) {
|
||||
proposals.add(new CompletionProposal(proposalStr.substring(1, proposalStr.length() - 1)));
|
||||
}
|
||||
else{
|
||||
for(String item : proposalStr.split(",")){
|
||||
proposals.add(new CompletionProposal(item.trim()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ArrayUtil.toObjectArray(proposals, CompletionProposal.class);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Integer getExpectedNumber(String fileText, @Nullable TargetPlatform platform) {
|
||||
if (platform == null) {
|
||||
return InTextDirectivesUtils.getPrefixedInt(fileText, NUMBER_LINE_PREFIX);
|
||||
}
|
||||
else if (platform == JvmPlatform.INSTANCE$) {
|
||||
return getPlatformExpectedNumber(fileText, NUMBER_JAVA_LINE_PREFIX);
|
||||
}
|
||||
else if (platform == JsPlatform.INSTANCE$) {
|
||||
return getPlatformExpectedNumber(fileText, NUMBER_JS_LINE_PREFIX);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException(UNSUPPORTED_PLATFORM_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isNothingElseExpected(String fileText) {
|
||||
return !InTextDirectivesUtils.findLinesWithPrefixesRemoved(fileText, NOTHING_ELSE_PREFIX).isEmpty();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Integer getInvocationCount(String fileText) {
|
||||
return InTextDirectivesUtils.getPrefixedInt(fileText, INVOCATION_COUNT_PREFIX);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Boolean getAutocompleteSetting(String fileText) {
|
||||
return InTextDirectivesUtils.getPrefixedBoolean(fileText, AUTOCOMPLETE_SETTING_PREFIX);
|
||||
}
|
||||
|
||||
public static boolean isWithOrder(String fileText) {
|
||||
return !InTextDirectivesUtils.findLinesWithPrefixesRemoved(fileText, WITH_ORDER_PREFIX).isEmpty();
|
||||
}
|
||||
|
||||
public static void assertDirectivesValid(String fileText) {
|
||||
InTextDirectivesUtils.assertHasUnknownPrefixes(fileText, KNOWN_PREFIXES);
|
||||
}
|
||||
|
||||
public static void assertContainsRenderedItems(CompletionProposal[] expected, LookupElement[] items, boolean checkOrder, boolean nothingElse) {
|
||||
List<CompletionProposal> itemsInformation = getItemsInformation(items);
|
||||
String allItemsString = listToString(itemsInformation);
|
||||
|
||||
Set<CompletionProposal> leftItems = nothingElse ? new LinkedHashSet<CompletionProposal>(itemsInformation) : null;
|
||||
|
||||
int indexOfPrevious = Integer.MIN_VALUE;
|
||||
|
||||
for (CompletionProposal expectedProposal : expected) {
|
||||
boolean isFound = false;
|
||||
|
||||
for (int index = 0; index < itemsInformation.size(); index++) {
|
||||
CompletionProposal proposal = itemsInformation.get(index);
|
||||
|
||||
if (proposal.matches(expectedProposal)) {
|
||||
isFound = true;
|
||||
|
||||
Assert.assertTrue("Invalid order of existent elements in " + allItemsString,
|
||||
!checkOrder || index > indexOfPrevious);
|
||||
indexOfPrevious = index;
|
||||
|
||||
if (leftItems != null) {
|
||||
leftItems.remove(proposal);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isFound) {
|
||||
if (allItemsString.isEmpty()) {
|
||||
Assert.fail("Completion is empty but " + expectedProposal + " is expected");
|
||||
}
|
||||
else {
|
||||
Assert.fail("Expected " + expectedProposal + " not found in:\n" + allItemsString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (leftItems != null && !leftItems.isEmpty()) {
|
||||
Assert.fail("No items not mentioned in EXIST directives expected but some found:\n" + listToString(leftItems));
|
||||
}
|
||||
}
|
||||
|
||||
private static Integer getPlatformExpectedNumber(String fileText, String platformNumberPrefix) {
|
||||
Integer prefixedInt = InTextDirectivesUtils.getPrefixedInt(fileText, platformNumberPrefix);
|
||||
if (prefixedInt != null) {
|
||||
Assert.assertNull(String.format("There shouldn't be %s and %s prefixes set in same time", NUMBER_LINE_PREFIX,
|
||||
platformNumberPrefix),
|
||||
InTextDirectivesUtils.getPrefixedInt(fileText, NUMBER_LINE_PREFIX));
|
||||
return prefixedInt;
|
||||
}
|
||||
|
||||
return InTextDirectivesUtils.getPrefixedInt(fileText, NUMBER_LINE_PREFIX);
|
||||
}
|
||||
|
||||
public static void assertNotContainsRenderedItems(CompletionProposal[] unexpected, LookupElement[] items) {
|
||||
List<CompletionProposal> itemsInformation = getItemsInformation(items);
|
||||
String allItemsString = listToString(itemsInformation);
|
||||
|
||||
for (CompletionProposal unexpectedProposal : unexpected) {
|
||||
for (CompletionProposal proposal : itemsInformation) {
|
||||
Assert.assertFalse("Unexpected '" + unexpectedProposal + "' presented in " + allItemsString,
|
||||
proposal.matches(unexpectedProposal));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static List<CompletionProposal> getItemsInformation(LookupElement[] items) {
|
||||
LookupElementPresentation presentation = new LookupElementPresentation();
|
||||
|
||||
List<CompletionProposal> result = new ArrayList<CompletionProposal>();
|
||||
if (items != null) {
|
||||
for (LookupElement item : items) {
|
||||
item.renderElement(presentation);
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
map.put(CompletionProposal.LOOKUP_STRING, item.getLookupString());
|
||||
if (presentation.getItemText() != null){
|
||||
map.put(CompletionProposal.PRESENTATION_ITEM_TEXT, presentation.getItemText());
|
||||
map.put(CompletionProposal.PRESENTATION_TEXT_ATTRIBUTES, textAttributes(presentation));
|
||||
}
|
||||
if (presentation.getTypeText() != null){
|
||||
map.put(CompletionProposal.PRESENTATION_TYPE_TEXT, presentation.getTypeText());
|
||||
}
|
||||
if (presentation.getTailText() != null){
|
||||
map.put(CompletionProposal.PRESENTATION_TAIL_TEXT, presentation.getTailText());
|
||||
}
|
||||
result.add(new ExpectedCompletionUtils.CompletionProposal(map));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static String textAttributes(LookupElementPresentation presentation) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
if (presentation.isItemTextBold()) {
|
||||
builder.append("bold");
|
||||
}
|
||||
if (presentation.isItemTextUnderlined()) {
|
||||
if (builder.length() > 0) builder.append(" ");
|
||||
builder.append("underlined");
|
||||
}
|
||||
Color foreground = presentation.getItemTextForeground();
|
||||
if (!foreground.equals(JBColor.foreground())) {
|
||||
assert foreground.equals(LookupCellRenderer.getGrayedForeground(false));
|
||||
if (builder.length() > 0) builder.append(" ");
|
||||
builder.append("grayed");
|
||||
}
|
||||
if (presentation.isStrikeout()) {
|
||||
if (builder.length() > 0) builder.append(" ");
|
||||
builder.append("strikeout");
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static String listToString(Collection<CompletionProposal> items) {
|
||||
return StringUtil.join(
|
||||
Collections2.transform(items, new Function<CompletionProposal, String>() {
|
||||
@Override
|
||||
public String apply(@Nullable CompletionProposal proposal) {
|
||||
assert proposal != null;
|
||||
return proposal.toString();
|
||||
}
|
||||
}), "\n");
|
||||
}
|
||||
}
|
||||
+321
@@ -0,0 +1,321 @@
|
||||
/*
|
||||
* 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.completion.test
|
||||
|
||||
import com.google.common.collect.ImmutableList
|
||||
import com.google.gson.JsonNull
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonParser
|
||||
import com.intellij.codeInsight.lookup.LookupElement
|
||||
import com.intellij.codeInsight.lookup.LookupElementPresentation
|
||||
import com.intellij.codeInsight.lookup.impl.LookupCellRenderer
|
||||
import com.intellij.ui.JBColor
|
||||
import com.intellij.util.ArrayUtil
|
||||
import org.jetbrains.kotlin.idea.test.AstAccessControl
|
||||
import org.jetbrains.kotlin.js.resolve.JsPlatform
|
||||
import org.jetbrains.kotlin.resolve.TargetPlatform
|
||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
|
||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
||||
import org.junit.Assert
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Extract a number of statements about completion from the given text. Those statements
|
||||
* should be asserted during test execution.
|
||||
*/
|
||||
public object ExpectedCompletionUtils {
|
||||
|
||||
public class CompletionProposal {
|
||||
private val map: Map<String, String?>
|
||||
|
||||
public constructor(lookupString: String) {
|
||||
map = HashMap<String, String?>()
|
||||
map.put(LOOKUP_STRING, lookupString)
|
||||
}
|
||||
|
||||
public constructor(map: MutableMap<String, String?>) {
|
||||
this.map = map
|
||||
for (key in map.keySet()) {
|
||||
if (key !in validKeys) {
|
||||
throw RuntimeException("Invalid key '$key'")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public constructor(json: JsonObject) {
|
||||
map = HashMap<String, String?>()
|
||||
for (entry in json.entrySet()) {
|
||||
val key = entry.getKey()
|
||||
if (key !in validKeys) {
|
||||
throw RuntimeException("Invalid json property '$key'")
|
||||
}
|
||||
val value = entry.value
|
||||
if (value !is JsonNull) {
|
||||
map.put(key, value.asString)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public fun matches(expectedProposal: CompletionProposal): Boolean
|
||||
= expectedProposal.map.entrySet().none { it.value != map[it.key] }
|
||||
|
||||
override fun toString(): String {
|
||||
val jsonObject = JsonObject()
|
||||
for ((key, value) in map) {
|
||||
jsonObject.addProperty(key, value)
|
||||
}
|
||||
return jsonObject.toString()
|
||||
}
|
||||
|
||||
companion object {
|
||||
public val LOOKUP_STRING: String = "lookupString"
|
||||
public val ALL_LOOKUP_STRINGS: String = "allLookupStrings"
|
||||
public val PRESENTATION_ITEM_TEXT: String = "itemText"
|
||||
public val PRESENTATION_TYPE_TEXT: String = "typeText"
|
||||
public val PRESENTATION_TAIL_TEXT: String = "tailText"
|
||||
public val PRESENTATION_TEXT_ATTRIBUTES: String = "attributes"
|
||||
public val validKeys: Set<String> = setOf(LOOKUP_STRING, ALL_LOOKUP_STRINGS, PRESENTATION_ITEM_TEXT, PRESENTATION_TYPE_TEXT, PRESENTATION_TAIL_TEXT, PRESENTATION_TEXT_ATTRIBUTES)
|
||||
}
|
||||
}
|
||||
|
||||
private val UNSUPPORTED_PLATFORM_MESSAGE = "Only $JvmPlatform and $JsPlatform platforms are supported"
|
||||
|
||||
private val EXIST_LINE_PREFIX = "EXIST:"
|
||||
|
||||
private val ABSENT_LINE_PREFIX = "ABSENT:"
|
||||
private val ABSENT_JS_LINE_PREFIX = "ABSENT_JS:"
|
||||
private val ABSENT_JAVA_LINE_PREFIX = "ABSENT_JAVA:"
|
||||
|
||||
private val EXIST_JAVA_ONLY_LINE_PREFIX = "EXIST_JAVA_ONLY:"
|
||||
private val EXIST_JS_ONLY_LINE_PREFIX = "EXIST_JS_ONLY:"
|
||||
|
||||
private val NUMBER_LINE_PREFIX = "NUMBER:"
|
||||
private val NUMBER_JS_LINE_PREFIX = "NUMBER_JS:"
|
||||
private val NUMBER_JAVA_LINE_PREFIX = "NUMBER_JAVA:"
|
||||
|
||||
private val NOTHING_ELSE_PREFIX = "NOTHING_ELSE"
|
||||
|
||||
private val INVOCATION_COUNT_PREFIX = "INVOCATION_COUNT:"
|
||||
private val WITH_ORDER_PREFIX = "WITH_ORDER"
|
||||
private val AUTOCOMPLETE_SETTING_PREFIX = "AUTOCOMPLETE_SETTING:"
|
||||
|
||||
public val RUNTIME_TYPE: String = "RUNTIME_TYPE:"
|
||||
|
||||
public val KNOWN_PREFIXES: List<String> = ImmutableList.of(
|
||||
EXIST_LINE_PREFIX,
|
||||
ABSENT_LINE_PREFIX,
|
||||
ABSENT_JS_LINE_PREFIX,
|
||||
ABSENT_JAVA_LINE_PREFIX,
|
||||
EXIST_JAVA_ONLY_LINE_PREFIX,
|
||||
EXIST_JS_ONLY_LINE_PREFIX,
|
||||
NUMBER_LINE_PREFIX,
|
||||
NUMBER_JS_LINE_PREFIX,
|
||||
NUMBER_JAVA_LINE_PREFIX,
|
||||
INVOCATION_COUNT_PREFIX,
|
||||
WITH_ORDER_PREFIX,
|
||||
AUTOCOMPLETE_SETTING_PREFIX,
|
||||
NOTHING_ELSE_PREFIX,
|
||||
RUNTIME_TYPE,
|
||||
AstAccessControl.ALLOW_AST_ACCESS_DIRECTIVE)
|
||||
|
||||
public fun itemsShouldExist(fileText: String, platform: TargetPlatform?): Array<CompletionProposal> {
|
||||
return when (platform) {
|
||||
JvmPlatform -> processProposalAssertions(fileText, EXIST_LINE_PREFIX, EXIST_JAVA_ONLY_LINE_PREFIX)
|
||||
JsPlatform -> processProposalAssertions(fileText, EXIST_LINE_PREFIX, EXIST_JS_ONLY_LINE_PREFIX)
|
||||
null -> processProposalAssertions(fileText, EXIST_LINE_PREFIX)
|
||||
else -> throw IllegalArgumentException(UNSUPPORTED_PLATFORM_MESSAGE)
|
||||
}
|
||||
}
|
||||
|
||||
public fun itemsShouldAbsent(fileText: String, platform: TargetPlatform?): Array<CompletionProposal> {
|
||||
return when (platform) {
|
||||
JvmPlatform -> processProposalAssertions(fileText, ABSENT_LINE_PREFIX, ABSENT_JAVA_LINE_PREFIX, EXIST_JS_ONLY_LINE_PREFIX)
|
||||
JsPlatform -> processProposalAssertions(fileText, ABSENT_LINE_PREFIX, ABSENT_JS_LINE_PREFIX, EXIST_JAVA_ONLY_LINE_PREFIX)
|
||||
null -> processProposalAssertions(fileText, ABSENT_LINE_PREFIX)
|
||||
else -> throw IllegalArgumentException(UNSUPPORTED_PLATFORM_MESSAGE)
|
||||
}
|
||||
}
|
||||
|
||||
public fun processProposalAssertions(fileText: String, vararg prefixes: String): Array<CompletionProposal> {
|
||||
val proposals = ArrayList<CompletionProposal>()
|
||||
for (proposalStr in InTextDirectivesUtils.findLinesWithPrefixesRemoved(fileText, *prefixes)) {
|
||||
if (proposalStr.startsWith("{")) {
|
||||
val parser = JsonParser()
|
||||
val json = parser.parse(proposalStr)
|
||||
proposals.add(CompletionProposal(json as JsonObject))
|
||||
}
|
||||
else if (proposalStr.startsWith("\"") && proposalStr.endsWith("\"")) {
|
||||
proposals.add(CompletionProposal(proposalStr.substring(1, proposalStr.length() - 1)))
|
||||
}
|
||||
else {
|
||||
for (item in proposalStr.split(",")) {
|
||||
proposals.add(CompletionProposal(item.trim()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ArrayUtil.toObjectArray(proposals, javaClass<CompletionProposal>())
|
||||
}
|
||||
|
||||
public fun getExpectedNumber(fileText: String, platform: TargetPlatform?): Int? {
|
||||
return when (platform) {
|
||||
null -> InTextDirectivesUtils.getPrefixedInt(fileText, NUMBER_LINE_PREFIX)
|
||||
JvmPlatform -> getPlatformExpectedNumber(fileText, NUMBER_JAVA_LINE_PREFIX)
|
||||
JsPlatform -> getPlatformExpectedNumber(fileText, NUMBER_JS_LINE_PREFIX)
|
||||
else -> throw IllegalArgumentException(UNSUPPORTED_PLATFORM_MESSAGE)
|
||||
}
|
||||
}
|
||||
|
||||
public fun isNothingElseExpected(fileText: String): Boolean {
|
||||
return !InTextDirectivesUtils.findLinesWithPrefixesRemoved(fileText, NOTHING_ELSE_PREFIX).isEmpty()
|
||||
}
|
||||
|
||||
public fun getInvocationCount(fileText: String): Int? {
|
||||
return InTextDirectivesUtils.getPrefixedInt(fileText, INVOCATION_COUNT_PREFIX)
|
||||
}
|
||||
|
||||
public fun getAutocompleteSetting(fileText: String): Boolean? {
|
||||
return InTextDirectivesUtils.getPrefixedBoolean(fileText, AUTOCOMPLETE_SETTING_PREFIX)
|
||||
}
|
||||
|
||||
public fun isWithOrder(fileText: String): Boolean {
|
||||
return !InTextDirectivesUtils.findLinesWithPrefixesRemoved(fileText, WITH_ORDER_PREFIX).isEmpty()
|
||||
}
|
||||
|
||||
public fun assertDirectivesValid(fileText: String) {
|
||||
InTextDirectivesUtils.assertHasUnknownPrefixes(fileText, KNOWN_PREFIXES)
|
||||
}
|
||||
|
||||
public fun assertContainsRenderedItems(expected: Array<CompletionProposal>, items: Array<LookupElement>, checkOrder: Boolean, nothingElse: Boolean) {
|
||||
val itemsInformation = getItemsInformation(items)
|
||||
val allItemsString = listToString(itemsInformation)
|
||||
|
||||
val leftItems = if (nothingElse) LinkedHashSet(itemsInformation) else null
|
||||
|
||||
var indexOfPrevious = Integer.MIN_VALUE
|
||||
|
||||
for (expectedProposal in expected) {
|
||||
var isFound = false
|
||||
|
||||
for (index in itemsInformation.indices) {
|
||||
val proposal = itemsInformation.get(index)
|
||||
|
||||
if (proposal.matches(expectedProposal)) {
|
||||
isFound = true
|
||||
|
||||
Assert.assertTrue("Invalid order of existent elements in $allItemsString",
|
||||
!checkOrder || index > indexOfPrevious)
|
||||
indexOfPrevious = index
|
||||
|
||||
leftItems?.remove(proposal)
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (!isFound) {
|
||||
if (allItemsString.isEmpty()) {
|
||||
Assert.fail("Completion is empty but $expectedProposal is expected")
|
||||
}
|
||||
else {
|
||||
Assert.fail("Expected $expectedProposal not found in:\n$allItemsString")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (leftItems != null && !leftItems.isEmpty()) {
|
||||
Assert.fail("No items not mentioned in EXIST directives expected but some found:\n" + listToString(leftItems))
|
||||
}
|
||||
}
|
||||
|
||||
private fun getPlatformExpectedNumber(fileText: String, platformNumberPrefix: String): Int? {
|
||||
val prefixedInt = InTextDirectivesUtils.getPrefixedInt(fileText, platformNumberPrefix)
|
||||
if (prefixedInt != null) {
|
||||
Assert.assertNull("There shouldn't be $NUMBER_LINE_PREFIX and $platformNumberPrefix prefixes set in same time",
|
||||
InTextDirectivesUtils.getPrefixedInt(fileText, NUMBER_LINE_PREFIX))
|
||||
return prefixedInt
|
||||
}
|
||||
|
||||
return InTextDirectivesUtils.getPrefixedInt(fileText, NUMBER_LINE_PREFIX)
|
||||
}
|
||||
|
||||
public fun assertNotContainsRenderedItems(unexpected: Array<CompletionProposal>, items: Array<LookupElement>) {
|
||||
val itemsInformation = getItemsInformation(items)
|
||||
val allItemsString = listToString(itemsInformation)
|
||||
|
||||
for (unexpectedProposal in unexpected) {
|
||||
for (proposal in itemsInformation) {
|
||||
Assert.assertFalse("Unexpected '$unexpectedProposal' presented in $allItemsString",
|
||||
proposal.matches(unexpectedProposal))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public fun getItemsInformation(items: Array<LookupElement>): List<CompletionProposal> {
|
||||
val presentation = LookupElementPresentation()
|
||||
|
||||
val result = ArrayList<CompletionProposal>(items.size())
|
||||
for (item in items) {
|
||||
item.renderElement(presentation)
|
||||
|
||||
val map = HashMap<String, String?>()
|
||||
map.put(CompletionProposal.LOOKUP_STRING, item.lookupString)
|
||||
|
||||
map.put(CompletionProposal.ALL_LOOKUP_STRINGS, item.allLookupStrings.sort().joinToString())
|
||||
|
||||
if (presentation.itemText != null) {
|
||||
map.put(CompletionProposal.PRESENTATION_ITEM_TEXT, presentation.itemText)
|
||||
map.put(CompletionProposal.PRESENTATION_TEXT_ATTRIBUTES, textAttributes(presentation))
|
||||
}
|
||||
|
||||
if (presentation.typeText != null) {
|
||||
map.put(CompletionProposal.PRESENTATION_TYPE_TEXT, presentation.typeText)
|
||||
}
|
||||
|
||||
if (presentation.tailText != null) {
|
||||
map.put(CompletionProposal.PRESENTATION_TAIL_TEXT, presentation.tailText)
|
||||
}
|
||||
|
||||
result.add(ExpectedCompletionUtils.CompletionProposal(map))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun textAttributes(presentation: LookupElementPresentation): String {
|
||||
return StringBuilder {
|
||||
if (presentation.isItemTextBold) {
|
||||
append("bold")
|
||||
}
|
||||
if (presentation.isItemTextUnderlined) {
|
||||
if (length() > 0) append(" ")
|
||||
append("underlined")
|
||||
}
|
||||
val foreground = presentation.itemTextForeground
|
||||
if (foreground != JBColor.foreground()) {
|
||||
assert(foreground == LookupCellRenderer.getGrayedForeground(false))
|
||||
if (length() > 0) append(" ")
|
||||
append("grayed")
|
||||
}
|
||||
if (presentation.isStrikeout) {
|
||||
if (length() > 0) append(" ")
|
||||
append("strikeout")
|
||||
}
|
||||
}.toString()
|
||||
}
|
||||
|
||||
public fun listToString(items: Collection<CompletionProposal>): String = items.joinToString("\n")
|
||||
}
|
||||
+63
@@ -1918,6 +1918,69 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/idea-completion/testData/basic/common/super")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Super extends AbstractJSBasicCompletionTest {
|
||||
public void testAllFilesPresentInSuper() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/basic/common/super"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("QualifierType1.kt")
|
||||
public void testQualifierType1() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/super/QualifierType1.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("QualifierType2.kt")
|
||||
public void testQualifierType2() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/super/QualifierType2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("QualifierType3.kt")
|
||||
public void testQualifierType3() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/super/QualifierType3.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("QualifierType4.kt")
|
||||
public void testQualifierType4() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/super/QualifierType4.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("QualifierType5.kt")
|
||||
public void testQualifierType5() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/super/QualifierType5.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("QualifierType6.kt")
|
||||
public void testQualifierType6() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/super/QualifierType6.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("QualifierTypeAny.kt")
|
||||
public void testQualifierTypeAny() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/super/QualifierTypeAny.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("QualifierTypeAnyInInterface.kt")
|
||||
public void testQualifierTypeAnyInInterface() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/super/QualifierTypeAnyInInterface.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("QualifierTypeGeneric.kt")
|
||||
public void testQualifierTypeGeneric() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/super/QualifierTypeGeneric.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/idea-completion/testData/basic/common/typeArgsOrNot")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
+63
@@ -1918,6 +1918,69 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/idea-completion/testData/basic/common/super")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Super extends AbstractJvmBasicCompletionTest {
|
||||
public void testAllFilesPresentInSuper() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/basic/common/super"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("QualifierType1.kt")
|
||||
public void testQualifierType1() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/super/QualifierType1.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("QualifierType2.kt")
|
||||
public void testQualifierType2() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/super/QualifierType2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("QualifierType3.kt")
|
||||
public void testQualifierType3() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/super/QualifierType3.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("QualifierType4.kt")
|
||||
public void testQualifierType4() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/super/QualifierType4.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("QualifierType5.kt")
|
||||
public void testQualifierType5() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/super/QualifierType5.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("QualifierType6.kt")
|
||||
public void testQualifierType6() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/super/QualifierType6.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("QualifierTypeAny.kt")
|
||||
public void testQualifierTypeAny() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/super/QualifierTypeAny.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("QualifierTypeAnyInInterface.kt")
|
||||
public void testQualifierTypeAnyInInterface() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/super/QualifierTypeAnyInInterface.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("QualifierTypeGeneric.kt")
|
||||
public void testQualifierTypeGeneric() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/super/QualifierTypeGeneric.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/idea-completion/testData/basic/common/typeArgsOrNot")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Reference in New Issue
Block a user