diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java index 4f96f6067d9..39e15ec5b72 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java @@ -194,9 +194,15 @@ public class ExpressionTypingUtils { public static boolean checkIsExtensionCallable ( @NotNull ReceiverValue receiverArgument, @NotNull CallableDescriptor callableDescriptor, + boolean isInfixCall, @NotNull BindingContext bindingContext, @NotNull DataFlowInfo dataFlowInfo ) { + if (isInfixCall + && (!(callableDescriptor instanceof SimpleFunctionDescriptor) || callableDescriptor.getValueParameters().size() != 1)) { + return false; + } + List types = AutoCastUtils.getAutoCastVariants(receiverArgument, bindingContext, dataFlowInfo); for (JetType type : types) { diff --git a/idea/src/org/jetbrains/jet/plugin/caches/KotlinIndicesHelper.kt b/idea/src/org/jetbrains/jet/plugin/caches/KotlinIndicesHelper.kt index 942fd9be07e..266e3742f80 100644 --- a/idea/src/org/jetbrains/jet/plugin/caches/KotlinIndicesHelper.kt +++ b/idea/src/org/jetbrains/jet/plugin/caches/KotlinIndicesHelper.kt @@ -133,6 +133,7 @@ public class KotlinIndicesHelper(private val project: Project) { scope: GlobalSearchScope): Collection { val context = resolveSession.resolveToElement(expression) val receiverExpression = expression.getReceiverExpression() ?: return listOf() + val isInfixCall = expression.getParent() is JetBinaryExpression val expressionType = context.get(BindingContext.EXPRESSION_TYPE, receiverExpression) val jetScope = context.get(BindingContext.RESOLUTION_SCOPE, receiverExpression) @@ -147,7 +148,7 @@ public class KotlinIndicesHelper(private val project: Project) { return allFqNames .filter { nameFilter(it.shortName().asString()) } .toSet() - .flatMap { findSuitableExtensions(it, receiverExpression, expressionType, jetScope, resolveSession.getModuleDescriptor(), context) } + .flatMap { findSuitableExtensions(it, receiverExpression, expressionType, isInfixCall, jetScope, resolveSession.getModuleDescriptor(), context) } } /** @@ -156,6 +157,7 @@ public class KotlinIndicesHelper(private val project: Project) { private fun findSuitableExtensions(callableFQN: FqName, receiverExpression: JetExpression, receiverType: JetType, + isInfixCall: Boolean, scope: JetScope, module: ModuleDescriptor, bindingContext: BindingContext): List { @@ -167,7 +169,7 @@ public class KotlinIndicesHelper(private val project: Project) { return declarationDescriptors .filterIsInstance(javaClass()) - .filter { it.getReceiverParameter() != null && ExpressionTypingUtils.checkIsExtensionCallable(receiverValue, it, bindingContext, dataFlowInfo) } + .filter { it.getReceiverParameter() != null && ExpressionTypingUtils.checkIsExtensionCallable(receiverValue, it, isInfixCall, bindingContext, dataFlowInfo) } } public fun getClassDescriptors(nameFilter: (String) -> Boolean, analyzer: KotlinCodeAnalyzer, scope: GlobalSearchScope): Collection { diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/TipsManager.kt b/idea/src/org/jetbrains/jet/plugin/codeInsight/TipsManager.kt index 9dfbb0330f8..767bb33835b 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/TipsManager.kt +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/TipsManager.kt @@ -25,7 +25,6 @@ import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo import org.jetbrains.jet.lang.resolve.scopes.JetScope import org.jetbrains.jet.lang.resolve.scopes.JetScopeUtils import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver -import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils import java.util.* @@ -38,15 +37,21 @@ public object TipsManager{ val parent = expression.getParent() val resolutionScope = context[BindingContext.RESOLUTION_SCOPE, expression] ?: return listOf() - val inPositionForCompletionWithReceiver = parent is JetCallExpression || parent is JetQualifiedExpression + val inPositionForCompletionWithReceiver = parent is JetCallExpression + || parent is JetQualifiedExpression + || parent is JetBinaryExpression if (receiverExpression != null && inPositionForCompletionWithReceiver) { + val isInfixCall = parent is JetBinaryExpression + fun filterIfInfix(descriptor: DeclarationDescriptor) + = if (isInfixCall) descriptor is SimpleFunctionDescriptor && descriptor.getValueParameters().size == 1 else true + // Process as call expression val descriptors = HashSet() val qualifier = context[BindingContext.QUALIFIER, receiverExpression] if (qualifier != null) { // It's impossible to add extension function for package or class (if it's class object, expression type is not null) - descriptors.addAll(qualifier.scope.getAllDescriptors()) + qualifier.scope.getAllDescriptors().filterTo(descriptors, ::filterIfInfix) } val expressionType = context[BindingContext.EXPRESSION_TYPE, receiverExpression] @@ -55,11 +60,11 @@ public object TipsManager{ val dataFlowInfo = context.getDataFlowInfo(expression) for (variant in AutoCastUtils.getAutoCastVariants(receiverValue, context, dataFlowInfo)) { - descriptors.addAll(variant.getMemberScope().getAllDescriptors()) + variant.getMemberScope().getAllDescriptors().filterTo(descriptors, ::filterIfInfix) } JetScopeUtils.getAllExtensions(resolutionScope).filterTo(descriptors) { - ExpressionTypingUtils.checkIsExtensionCallable(receiverValue, it, context, dataFlowInfo) + ExpressionTypingUtils.checkIsExtensionCallable(receiverValue, it, isInfixCall, context, dataFlowInfo) } } @@ -90,16 +95,21 @@ public object TipsManager{ return excludeNonPackageDescriptors(resolutionScope.getAllDescriptors()) } - public fun excludeNotCallableExtensions(descriptors: Collection, scope: JetScope, context: BindingContext, dataFlowInfo: DataFlowInfo): Collection { + public fun excludeNotCallableExtensions(descriptors: Collection, + scope: JetScope, + context: BindingContext, + dataFlowInfo: DataFlowInfo): Collection { val set = HashSet(descriptors) set.excludeNotCallableExtensions(scope, context, dataFlowInfo) return set } - private fun MutableSet.excludeNotCallableExtensions(scope: JetScope, context: BindingContext, dataFlowInfo: DataFlowInfo) { + private fun MutableSet.excludeNotCallableExtensions(scope: JetScope, + context: BindingContext, + dataFlowInfo: DataFlowInfo) { val implicitReceivers = scope.getImplicitReceiversHierarchy() removeAll(JetScopeUtils.getAllExtensions(scope).filter { callable -> - implicitReceivers.none { ExpressionTypingUtils.checkIsExtensionCallable(it.getValue(), callable, context, dataFlowInfo) } + implicitReceivers.none { ExpressionTypingUtils.checkIsExtensionCallable(it.getValue(), callable, false, context, dataFlowInfo) } }) } diff --git a/idea/src/org/jetbrains/jet/plugin/completion/handlers/JetCallableInsertHandler.kt b/idea/src/org/jetbrains/jet/plugin/completion/handlers/JetCallableInsertHandler.kt index 4115d8a2f31..3be68755648 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/handlers/JetCallableInsertHandler.kt +++ b/idea/src/org/jetbrains/jet/plugin/completion/handlers/JetCallableInsertHandler.kt @@ -36,6 +36,8 @@ import org.jetbrains.jet.lang.types.JetType import com.intellij.openapi.util.TextRange import org.jetbrains.jet.plugin.completion.DeclarationLookupObject import org.jetbrains.jet.lang.descriptors.CallableDescriptor +import org.jetbrains.jet.lang.psi.JetBinaryExpression +import org.jetbrains.jet.lang.psi.JetSimpleNameExpression public abstract class JetCallableInsertHandler : BaseDeclarationInsertHandler() { public override fun handleInsert(context: InsertionContext, item: LookupElement) { @@ -97,19 +99,33 @@ public class JetFunctionInsertHandler(val caretPosition : CaretPosition, val lam psiDocumentManager.commitAllDocuments() psiDocumentManager.doPostponedOperationsAndUnblockDocument(context.getDocument()) - if (context.getCompletionChar() == '(') { - context.setAddCompletionChar(false) - } - val startOffset = context.getStartOffset() val element = context.getFile().findElementAt(startOffset) - if (element != null && shouldAddBrackets(element)) { - addBrackets(context, element) + if (element != null) { + if (PsiTreeUtil.getParentOfType(element, javaClass()) != null) return + val parent = element.getParent() + val grandParent = parent?.getParent() + if (parent is JetSimpleNameExpression && grandParent is JetBinaryExpression && parent == grandParent.getOperationReference()) { // infix call + if (context.getCompletionChar() == ' ') { + context.setAddCompletionChar(false) + } + + val tailOffset = context.getTailOffset() + context.getDocument().insertString(tailOffset, " ") + context.getEditor().getCaretModel().moveToOffset(tailOffset + 1) + } + else { + addBrackets(context, element) + } } } private fun addBrackets(context : InsertionContext, offsetElement : PsiElement) { + if (context.getCompletionChar() == '(') { //TODO: more correct behavior related to braces type + context.setAddCompletionChar(false) + } + val offset = context.getTailOffset() val document = context.getDocument() val completionChar = context.getCompletionChar() diff --git a/idea/testData/completion/basic/common/AfterIntSeparatedWithComments.kt b/idea/testData/completion/basic/common/AfterIntSeparatedWithComments.kt index e6b250ee53a..e634666d510 100644 --- a/idea/testData/completion/basic/common/AfterIntSeparatedWithComments.kt +++ b/idea/testData/completion/basic/common/AfterIntSeparatedWithComments.kt @@ -1,7 +1,8 @@ +fun Int.func(s: String): Int{} + fun test() { val floor = "Floor" val a = 1/**/f } -// EXIST: floor -// EXIST: false \ No newline at end of file +// EXIST: func diff --git a/idea/testData/completion/basic/common/InfixCall.kt b/idea/testData/completion/basic/common/InfixCall.kt new file mode 100644 index 00000000000..48c6c8a18b6 --- /dev/null +++ b/idea/testData/completion/basic/common/InfixCall.kt @@ -0,0 +1,33 @@ +class C { + fun foo(){} + fun bar(p: Int) {} + fun zoo(p1: Int, p2: Int){} + val prop: Int = 1 +} + +fun C.xxx() {} +fun C.yyy(p: Int) {} +fun C.zzz(p1: Int, p2: Int) {} +val C.extensionProp: Int get() = 1 + +fun A.and(that: B): Pair = Pair(this, that) + +fun String.ttt(p: Int) {} + +fun f() { + C() +} + +// ABSENT: "foo" +// EXIST: "bar" +// ABSENT: "zoo" +// ABSENT: "prop" + +// ABSENT: "xxx" +// EXIST: "yyy" +// ABSENT: "zzz" +// ABSENT: "extensionProp" + +// EXIST: "and" + +// ABSENT: "ttt" diff --git a/idea/testData/completion/basic/multifile/NotImportedInfixExtension/NotImportedInfixExtension.dependency.kt b/idea/testData/completion/basic/multifile/NotImportedInfixExtension/NotImportedInfixExtension.dependency.kt new file mode 100644 index 00000000000..ae0fecdc1e7 --- /dev/null +++ b/idea/testData/completion/basic/multifile/NotImportedInfixExtension/NotImportedInfixExtension.dependency.kt @@ -0,0 +1,10 @@ +package other + +import pack.C + +fun C.xxx() {} +fun C.yyy(p: Int) {} +fun C.zzz(p1: Int, p2: Int) {} +val C.extensionProp: Int get() = 1 + +// ALLOW_AST_ACCESS diff --git a/idea/testData/completion/basic/multifile/NotImportedInfixExtension/NotImportedInfixExtension.kt b/idea/testData/completion/basic/multifile/NotImportedInfixExtension/NotImportedInfixExtension.kt new file mode 100644 index 00000000000..1c873b140d3 --- /dev/null +++ b/idea/testData/completion/basic/multifile/NotImportedInfixExtension/NotImportedInfixExtension.kt @@ -0,0 +1,13 @@ +package pack + +class C + +fun f() { + C() +} + +// INVOCATION_COUNT: 2 +// ABSENT: "xxx" +// EXIST: "yyy" +// ABSENT: "zzz" +// ABSENT: "extensionProp" diff --git a/idea/testData/completion/handlers/InfixCall.kt b/idea/testData/completion/handlers/InfixCall.kt new file mode 100644 index 00000000000..8d3ddf5cb26 --- /dev/null +++ b/idea/testData/completion/handlers/InfixCall.kt @@ -0,0 +1,5 @@ +fun A.to(that: B): Pair = Pair(this, that) + +fun foo() { + val pair = 1 to +} diff --git a/idea/testData/completion/handlers/InfixCall.kt.after b/idea/testData/completion/handlers/InfixCall.kt.after new file mode 100644 index 00000000000..08973d8e874 --- /dev/null +++ b/idea/testData/completion/handlers/InfixCall.kt.after @@ -0,0 +1,5 @@ +fun A.to(that: B): Pair = Pair(this, that) + +fun foo() { + val pair = 1 to +} diff --git a/idea/testData/completion/handlers/InfixCallOnSpace.kt b/idea/testData/completion/handlers/InfixCallOnSpace.kt new file mode 100644 index 00000000000..8d3ddf5cb26 --- /dev/null +++ b/idea/testData/completion/handlers/InfixCallOnSpace.kt @@ -0,0 +1,5 @@ +fun A.to(that: B): Pair = Pair(this, that) + +fun foo() { + val pair = 1 to +} diff --git a/idea/testData/completion/handlers/InfixCallOnSpace.kt.after b/idea/testData/completion/handlers/InfixCallOnSpace.kt.after new file mode 100644 index 00000000000..08973d8e874 --- /dev/null +++ b/idea/testData/completion/handlers/InfixCallOnSpace.kt.after @@ -0,0 +1,5 @@ +fun A.to(that: B): Pair = Pair(this, that) + +fun foo() { + val pair = 1 to +} diff --git a/idea/testData/completion/handlers/multifile/InfixExtensionCallImport-1.kt b/idea/testData/completion/handlers/multifile/InfixExtensionCallImport-1.kt new file mode 100644 index 00000000000..aaedc721c13 --- /dev/null +++ b/idea/testData/completion/handlers/multifile/InfixExtensionCallImport-1.kt @@ -0,0 +1,3 @@ +fun foo() { + val pair = 1 makeP +} diff --git a/idea/testData/completion/handlers/multifile/InfixExtensionCallImport-2.kt b/idea/testData/completion/handlers/multifile/InfixExtensionCallImport-2.kt new file mode 100644 index 00000000000..1e1e13d1752 --- /dev/null +++ b/idea/testData/completion/handlers/multifile/InfixExtensionCallImport-2.kt @@ -0,0 +1,3 @@ +package other + +fun A.makePair(that: B): Pair = Pair(this, that) diff --git a/idea/testData/completion/handlers/multifile/InfixExtensionCallImport.kt.after b/idea/testData/completion/handlers/multifile/InfixExtensionCallImport.kt.after new file mode 100644 index 00000000000..80f6bd44ddd --- /dev/null +++ b/idea/testData/completion/handlers/multifile/InfixExtensionCallImport.kt.after @@ -0,0 +1,5 @@ +import other.makePair + +fun foo() { + val pair = 1 makePair +} diff --git a/idea/tests/org/jetbrains/jet/completion/ExpectedCompletionUtils.java b/idea/tests/org/jetbrains/jet/completion/ExpectedCompletionUtils.java index 41728ef6d0c..0327db08d82 100644 --- a/idea/tests/org/jetbrains/jet/completion/ExpectedCompletionUtils.java +++ b/idea/tests/org/jetbrains/jet/completion/ExpectedCompletionUtils.java @@ -30,6 +30,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.InTextDirectivesUtils; import org.jetbrains.jet.plugin.project.TargetPlatform; +import org.jetbrains.jet.plugin.stubs.AstAccessControl; import org.junit.Assert; import java.util.*; @@ -126,7 +127,8 @@ public class ExpectedCompletionUtils { NUMBER_JS_LINE_PREFIX, NUMBER_JAVA_LINE_PREFIX, INVOCATION_COUNT_PREFIX, - WITH_ORDER_PREFIX); + WITH_ORDER_PREFIX, + AstAccessControl.INSTANCE$.getALLOW_AST_ACCESS_DIRECTIVE()); @NotNull public static CompletionProposal[] itemsShouldExist(String fileText, @Nullable TargetPlatform platform) { diff --git a/idea/tests/org/jetbrains/jet/completion/JSBasicCompletionTestGenerated.java b/idea/tests/org/jetbrains/jet/completion/JSBasicCompletionTestGenerated.java index ec0aaa81ac5..df34109c65f 100644 --- a/idea/tests/org/jetbrains/jet/completion/JSBasicCompletionTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/completion/JSBasicCompletionTestGenerated.java @@ -378,6 +378,12 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes doTest(fileName); } + @TestMetadata("InfixCall.kt") + public void testInfixCall() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/InfixCall.kt"); + doTest(fileName); + } + @TestMetadata("JavaPackage.kt") public void testJavaPackage() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/JavaPackage.kt"); diff --git a/idea/tests/org/jetbrains/jet/completion/JvmBasicCompletionTestGenerated.java b/idea/tests/org/jetbrains/jet/completion/JvmBasicCompletionTestGenerated.java index c38980c0d45..770e80fb3c9 100644 --- a/idea/tests/org/jetbrains/jet/completion/JvmBasicCompletionTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/completion/JvmBasicCompletionTestGenerated.java @@ -378,6 +378,12 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT doTest(fileName); } + @TestMetadata("InfixCall.kt") + public void testInfixCall() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/InfixCall.kt"); + doTest(fileName); + } + @TestMetadata("JavaPackage.kt") public void testJavaPackage() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/JavaPackage.kt"); diff --git a/idea/tests/org/jetbrains/jet/completion/JvmSmartCompletionTestGenerated.java b/idea/tests/org/jetbrains/jet/completion/JvmSmartCompletionTestGenerated.java index 9c66304f19e..ca9965bd250 100644 --- a/idea/tests/org/jetbrains/jet/completion/JvmSmartCompletionTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/completion/JvmSmartCompletionTestGenerated.java @@ -17,9 +17,13 @@ package org.jetbrains.jet.completion; import com.intellij.testFramework.TestDataPath; -import org.jetbrains.jet.JetTestUtils; -import org.jetbrains.jet.test.TestMetadata; +import junit.framework.Test; +import junit.framework.TestSuite; import org.junit.runner.RunWith; +import org.jetbrains.jet.JetTestUtils; +import org.jetbrains.jet.test.InnerTestClasses; +import org.jetbrains.jet.test.TestMetadata; +import org.jetbrains.jet.JUnit3RunnerWithInners; import java.io.File; import java.util.regex.Pattern; diff --git a/idea/tests/org/jetbrains/jet/completion/MultiFileJvmBasicCompletionTestGenerated.java b/idea/tests/org/jetbrains/jet/completion/MultiFileJvmBasicCompletionTestGenerated.java index a13b2a52b83..47658f502ce 100644 --- a/idea/tests/org/jetbrains/jet/completion/MultiFileJvmBasicCompletionTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/completion/MultiFileJvmBasicCompletionTestGenerated.java @@ -17,13 +17,9 @@ package org.jetbrains.jet.completion; import com.intellij.testFramework.TestDataPath; -import junit.framework.Test; -import junit.framework.TestSuite; -import org.junit.runner.RunWith; import org.jetbrains.jet.JetTestUtils; -import org.jetbrains.jet.test.InnerTestClasses; import org.jetbrains.jet.test.TestMetadata; -import org.jetbrains.jet.JUnit3RunnerWithInners; +import org.junit.runner.RunWith; import java.io.File; import java.util.regex.Pattern; @@ -134,6 +130,12 @@ public class MultiFileJvmBasicCompletionTestGenerated extends AbstractMultiFileJ doTest(fileName); } + @TestMetadata("NotImportedInfixExtension") + public void testNotImportedInfixExtension() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/multifile/NotImportedInfixExtension/"); + doTest(fileName); + } + @TestMetadata("NotImportedJavaClass") public void testNotImportedJavaClass() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/multifile/NotImportedJavaClass/"); diff --git a/idea/tests/org/jetbrains/jet/completion/handlers/BasicCompletionHandlerTest.kt b/idea/tests/org/jetbrains/jet/completion/handlers/BasicCompletionHandlerTest.kt index 6145ce9fe11..d9fa701a681 100644 --- a/idea/tests/org/jetbrains/jet/completion/handlers/BasicCompletionHandlerTest.kt +++ b/idea/tests/org/jetbrains/jet/completion/handlers/BasicCompletionHandlerTest.kt @@ -150,4 +150,7 @@ public class BasicCompletionHandlerTest : CompletionHandlerTestBase(){ fun testKeywordClassName() = doTest(1, "class", null, '\n') fun testKeywordFunctionName() = doTest(1, "fun", "fun()", null, '\n') + + fun testInfixCall() = doTest(1, "to", null, null, '\n') + fun testInfixCallOnSpace() = doTest(1, "to", null, null, ' ') } \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/completion/handlers/CompletionMultifileHandlerTest.java b/idea/tests/org/jetbrains/jet/completion/handlers/CompletionMultifileHandlerTest.java index 0b59c4faf16..2a6e019c052 100644 --- a/idea/tests/org/jetbrains/jet/completion/handlers/CompletionMultifileHandlerTest.java +++ b/idea/tests/org/jetbrains/jet/completion/handlers/CompletionMultifileHandlerTest.java @@ -58,6 +58,10 @@ public class CompletionMultifileHandlerTest extends KotlinCompletionTestCase { doTest(); } + public void testInfixExtensionCallImport() throws Exception { + doTest(); + } + public void doTest() throws Exception { String fileName = getTestName(false); diff --git a/idea/tests/org/jetbrains/jet/plugin/stubs/AstAccessControl.kt b/idea/tests/org/jetbrains/jet/plugin/stubs/AstAccessControl.kt index 55d6f8155e0..ee4511e2885 100644 --- a/idea/tests/org/jetbrains/jet/plugin/stubs/AstAccessControl.kt +++ b/idea/tests/org/jetbrains/jet/plugin/stubs/AstAccessControl.kt @@ -23,15 +23,12 @@ import com.intellij.openapi.vfs.VirtualFile import org.jetbrains.jet.plugin.JetFileType import com.intellij.openapi.project.Project import com.intellij.openapi.Disposable -import com.intellij.openapi.util.io.FileUtil -import com.intellij.openapi.vfs.VfsUtil import com.intellij.openapi.vfs.VfsUtilCore import org.jetbrains.jet.InTextDirectivesUtils -import junit.framework.TestCase import kotlin.test.fail -object AstAccessControl { - private val ALLOW_AST_ACCESS_DIRECTIVE = "ALLOW_AST_ACCESS" +public object AstAccessControl { + public val ALLOW_AST_ACCESS_DIRECTIVE: String = "ALLOW_AST_ACCESS" // Please provide at least one test that fails ast switch check (shouldFail should be true for at least one test) // This kind of inconvenience is justified by the fact that the check can be invalidated by slight misconfiguration of the test