Resource Bundles: Implement references on Kotlin string literals

#KT-6946 In Progress
This commit is contained in:
Alexey Sedunov
2015-09-17 16:27:54 +03:00
parent 9c7d6c1649
commit 5af4101f7d
29 changed files with 380 additions and 20 deletions
@@ -405,3 +405,5 @@ public fun JetDeclaration.visibilityModifier(): PsiElement? {
public fun JetDeclaration.visibilityModifierType(): JetModifierKeywordToken?
= visibilityModifier()?.node?.elementType as JetModifierKeywordToken?
public fun JetStringTemplateExpression.isPlain() = entries.all { it is JetLiteralStringTemplateEntry }
@@ -158,7 +158,7 @@ public final class InTextDirectivesUtils {
List<String> resultPrefixes = Lists.newArrayList();
for (String prefix : prefixes) {
if (prefix.startsWith("//")) {
if (prefix.startsWith("//") || prefix.startsWith("##")) {
resultPrefixes.add(StringUtil.trimLeading(prefix.substring(2)));
}
else {
@@ -181,7 +181,7 @@ public final class InTextDirectivesUtils {
while ((line = reader.readLine()) != null) {
line = line.trim();
if (line.startsWith("//")) {
if (line.startsWith("//") || line.startsWith("##")) {
String uncommentedLine = line.substring(2).trim();
if (!uncommentedLine.isEmpty()) {
result.add(uncommentedLine);
@@ -525,6 +525,7 @@ fun main(args: Array<String>) {
testClass(javaClass<AbstractJetFindUsagesTest>()) {
model("findUsages/kotlin", pattern = """^(.+)\.0\.kt$""")
model("findUsages/java", pattern = """^(.+)\.0\.java$""")
model("findUsages/propertyFiles", pattern = """^(.+)\.0\.properties$""")
}
testClass(javaClass<AbstractKotlinFindUsagesWithLibraryTest>()) {
@@ -17,22 +17,17 @@
package org.jetbrains.kotlin.idea.findUsages
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
import com.intellij.psi.PsiPackage
import com.intellij.psi.PsiReferenceExpression
import org.jetbrains.kotlin.descriptors.VariableDescriptor
import org.jetbrains.kotlin.idea.findUsages.UsageTypeEnum.*
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.findUsages.UsageTypeEnum.*
import org.jetbrains.kotlin.idea.references.*
import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.*
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypeAndBranch
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils
public object UsageTypeUtils {
@@ -41,6 +36,7 @@ public object UsageTypeUtils {
is JetForExpression -> return IMPLICIT_ITERATION
is JetMultiDeclaration -> return READ
is JetPropertyDelegate -> return PROPERTY_DELEGATION
is JetStringTemplateExpression -> return USAGE_IN_STRING_LITERAL
}
val refExpr = element?.getNonStrictParentOfType<JetReferenceExpression>()
@@ -249,5 +245,7 @@ enum class UsageTypeEnum {
CLASS_CAST_TO,
ANNOTATION,
CLASS_NEW_OPERATOR,
NAMED_ARGUMENT
NAMED_ARGUMENT,
USAGE_IN_STRING_LITERAL
}
+1
View File
@@ -361,6 +361,7 @@
<weigher key="completion" implementationClass="org.jetbrains.kotlin.idea.completion.KotlinLookupElementProximityWeigher" id="kotlin.proximity" order="after proximity"/>
<psi.referenceContributor language="jet" implementation="org.jetbrains.kotlin.idea.references.JetReferenceContributor"/>
<psi.referenceContributor language="jet" implementation="org.jetbrains.kotlin.idea.properties.KotlinPropertiesReferenceContributor"/>
<renamePsiElementProcessor id="KotlinClass"
implementation="org.jetbrains.kotlin.idea.refactoring.rename.RenameKotlinClassProcessor"
@@ -72,6 +72,8 @@ public object JetUsageTypeProvider : UsageTypeProviderEx {
ANNOTATION -> UsageType.ANNOTATION
CLASS_NEW_OPERATOR -> UsageType.CLASS_NEW_OPERATOR
NAMED_ARGUMENT -> JetUsageTypes.NAMED_ARGUMENT
USAGE_IN_STRING_LITERAL -> UsageType.LITERAL_USAGE
}
}
}
@@ -0,0 +1,37 @@
/*
* 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.properties
import com.intellij.patterns.PlatformPatterns
import com.intellij.psi.PsiReferenceContributor
import com.intellij.psi.PsiReferenceRegistrar
import org.jetbrains.kotlin.psi.JetLiteralStringTemplateEntry
import org.jetbrains.kotlin.psi.JetStringTemplateExpression
public class KotlinPropertiesReferenceContributor : PsiReferenceContributor() {
override fun registerReferenceProviders(registrar: PsiReferenceRegistrar) {
registrar.registerReferenceProvider(
PlatformPatterns.psiElement(JetStringTemplateExpression::class.java),
KotlinPropertyKeyReferenceProvider
)
registrar.registerReferenceProvider(
PlatformPatterns.psiElement(JetStringTemplateExpression::class.java),
KotlinResourceBundleNameReferenceProvider
)
}
}
@@ -0,0 +1,142 @@
/*
* 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.properties
import com.intellij.codeInsight.AnnotationUtil
import com.intellij.lang.properties.ResourceBundleReference
import com.intellij.lang.properties.references.PropertyReference
import com.intellij.psi.ElementManipulators
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiReference
import com.intellij.psi.PsiReferenceProvider
import com.intellij.psi.search.LocalSearchScope
import com.intellij.util.ProcessingContext
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
import org.jetbrains.kotlin.idea.imports.importableFqName
import org.jetbrains.kotlin.idea.references.mainReference
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.psi.psiUtil.isPlain
import org.jetbrains.kotlin.resolve.calls.callUtil.getParentResolvedCall
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch
import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
private val PROPERTY_KEY = FqName(AnnotationUtil.PROPERTY_KEY)
private val PROPERTY_KEY_RESOURCE_BUNDLE = Name.identifier(AnnotationUtil.PROPERTY_KEY_RESOURCE_BUNDLE_PARAMETER)
private fun AnnotationDescriptor.getBundleName(): String? {
return allValueArguments.entrySet().singleOrNull { it.key.name == PROPERTY_KEY_RESOURCE_BUNDLE }?.value?.value as? String
}
private fun DeclarationDescriptor.getBundleNameByAnnotation(): String? {
return (annotations.findAnnotation(PROPERTY_KEY) ?: annotations.findExternalAnnotation(PROPERTY_KEY))?.getBundleName()
}
private fun JetExpression.getBundleNameByContext(): String? {
val expression = JetPsiUtil.safeDeparenthesize(this)
val parent = expression.parent
(parent as? JetProperty)?.let { return it.resolveToDescriptor().getBundleNameByAnnotation() }
val bindingContext = expression.analyze(BodyResolveMode.PARTIAL)
val resolvedCall =
if (parent is JetQualifiedExpression && expression == parent.receiverExpression) {
parent.selectorExpression.getResolvedCall(bindingContext)
}
else {
expression.getParentResolvedCall(bindingContext)
} ?: return null
val callable = resolvedCall.resultingDescriptor
if ((resolvedCall.extensionReceiver as? ExpressionReceiver)?.expression == expression) {
val returnTypeAnnotations = callable.returnType?.annotations ?: return null
return Annotations
.findUseSiteTargetedAnnotation(returnTypeAnnotations, AnnotationUseSiteTarget.RECEIVER, PROPERTY_KEY)
?.getBundleName()
}
return resolvedCall.valueArguments.entrySet()
.singleOrNull { it.value.arguments.any { it.getArgumentExpression() == expression } }
?.key
?.getBundleNameByAnnotation()
}
private fun JetAnnotationEntry.getPropertyKeyResolvedCall(): ResolvedCall<*>? {
val resolvedCall = getResolvedCall(analyze(BodyResolveMode.PARTIAL)) ?: return null
val klass = (resolvedCall.resultingDescriptor as? ConstructorDescriptor)?.containingDeclaration ?: return null
if (klass.kind != ClassKind.ANNOTATION_CLASS || klass.importableFqName != PROPERTY_KEY) return null
return resolvedCall
}
private fun JetStringTemplateExpression.isBundleName(): Boolean {
val parent = JetPsiUtil.safeDeparenthesize(this).parent
when (parent) {
is JetValueArgument -> {
val resolvedCall = parent.getStrictParentOfType<JetAnnotationEntry>()?.getPropertyKeyResolvedCall() ?: return false
val valueParameter = (resolvedCall.getArgumentMapping(parent) as? ArgumentMatch)?.valueParameter ?: return false
if (valueParameter.name != PROPERTY_KEY_RESOURCE_BUNDLE) return false
return true
}
is JetProperty -> {
val contexts = (parent.useScope as? LocalSearchScope)?.scope ?: arrayOf(parent.containingFile)
return contexts.any {
it.anyDescendantOfType<JetAnnotationEntry> f@ { entry ->
if (!entry.valueArguments.any { it.getArgumentName()?.asName == PROPERTY_KEY_RESOURCE_BUNDLE }) return@f false
val resolvedCall = entry.getPropertyKeyResolvedCall() ?: return@f false
val parameter = resolvedCall.resultingDescriptor.valueParameters.singleOrNull { it.name == PROPERTY_KEY_RESOURCE_BUNDLE }
?: return@f false
val valueArgument = resolvedCall.valueArguments[parameter] as? ExpressionValueArgument ?: return@f false
val bundleNameExpression = valueArgument.valueArgument?.getArgumentExpression() ?: return@f false
bundleNameExpression is JetSimpleNameExpression && bundleNameExpression.mainReference.resolve() == parent
}
}
}
}
return false
}
public object KotlinPropertyKeyReferenceProvider : PsiReferenceProvider() {
override fun getReferencesByElement(element: PsiElement, context: ProcessingContext): Array<out PsiReference> {
if (!(element is JetStringTemplateExpression && element.isPlain())) return PsiReference.EMPTY_ARRAY
val bundleName = element.getBundleNameByContext() ?: return PsiReference.EMPTY_ARRAY
return arrayOf(PropertyReference(ElementManipulators.getValueText(element), element, bundleName, false))
}
}
public object KotlinResourceBundleNameReferenceProvider : PsiReferenceProvider() {
override fun getReferencesByElement(element: PsiElement, context: ProcessingContext): Array<out PsiReference> {
if (!(element is JetStringTemplateExpression && element.isPlain() && element.isBundleName())) return PsiReference.EMPTY_ARRAY
return arrayOf(ResourceBundleReference(element))
}
}
@@ -0,0 +1,9 @@
// PSI_ELEMENT: com.intellij.lang.properties.psi.PropertiesFile
// FIND_BY_REF
import org.jetbrains.annotations.PropertyKey
public fun message(@PropertyKey(resourceBundle = "<caret>idea.testData.findUsages.kotlin.propertyFiles.propertyFileUsagesByRef.2") key: String) = key
fun test() {
message("foo.bar")
}
@@ -0,0 +1,11 @@
import org.jetbrains.annotations.PropertyKey;
class A {
static String message(@PropertyKey(resourceBundle = "idea.testData.findUsages.kotlin.propertyFiles.propertyFileUsagesByRef.2") String key, Object... args) {
return key;
}
void test() {
message("foo.bar");
}
}
@@ -0,0 +1 @@
foo.bar = test
@@ -0,0 +1,5 @@
package org.jetbrains.annotations
@Retention(AnnotationRetention.BINARY)
@Target(AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.LOCAL_VARIABLE, AnnotationTarget.FIELD)
public annotation class PropertyKey(public val resourceBundle: String)
@@ -0,0 +1,2 @@
[propertyFileUsagesByRef.0.kt] Usage in string constants (5: 51) public fun message(@PropertyKey(resourceBundle = "idea.testData.findUsages.kotlin.propertyFiles.propertyFileUsagesByRef.2") key: String) = key
[propertyFileUsagesByRef.1.java] Method parameter declaration (4: 58) static String message(@PropertyKey(resourceBundle = "idea.testData.findUsages.kotlin.propertyFiles.propertyFileUsagesByRef.2") String key, Object... args) {
@@ -0,0 +1,9 @@
// PSI_ELEMENT: com.intellij.lang.properties.psi.Property
// FIND_BY_REF
import org.jetbrains.annotations.PropertyKey
public fun message(@PropertyKey(resourceBundle = "idea.testData.findUsages.kotlin.propertyFiles.propertyUsagesByRef.2") key: String) = key
fun test() {
message("<caret>foo.bar")
}
@@ -0,0 +1,5 @@
class A {
void test() {
PropertyUsages_1Kt.message("foo.bar");
}
}
@@ -0,0 +1 @@
foo.bar = test
@@ -0,0 +1,5 @@
package org.jetbrains.annotations
@Retention(AnnotationRetention.BINARY)
@Target(AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.LOCAL_VARIABLE, AnnotationTarget.FIELD)
public annotation class PropertyKey(public val resourceBundle: String)
@@ -0,0 +1,2 @@
[propertyUsagesByRef.0.kt] Usage in string constants (8: 14) message("foo.bar")
[propertyUsagesByRef.1.java] Usage in string constants (3: 37) PropertyUsages_1Kt.message("foo.bar");
@@ -0,0 +1,2 @@
## FIND_FILE_USAGES
foo.bar = test
@@ -0,0 +1,10 @@
import org.jetbrains.annotations.PropertyKey
private val BUNDLE_NAME = "idea.testData.findUsages.propertyFiles.propertyFileUsages.0"
public fun message(@PropertyKey(resourceBundle = "idea.testData.findUsages.propertyFiles.propertyFileUsages.0") key: String) = key
public fun message2(@PropertyKey(resourceBundle = BUNDLE_NAME) key: String) = key
fun test() {
message("foo.bar")
}
@@ -0,0 +1,5 @@
package org.jetbrains.annotations
@Retention(AnnotationRetention.BINARY)
@Target(AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.LOCAL_VARIABLE, AnnotationTarget.FIELD)
public annotation class PropertyKey(public val resourceBundle: String)
@@ -0,0 +1,2 @@
Usage in string constants (3: 28) private val BUNDLE_NAME = "idea.testData.findUsages.propertyFiles.propertyFileUsages.0"
Usage in string constants (5: 51) public fun message(@PropertyKey(resourceBundle = "idea.testData.findUsages.propertyFiles.propertyFileUsages.0") key: String) = key
@@ -0,0 +1 @@
foo<caret>.bar = test
@@ -0,0 +1,30 @@
import org.jetbrains.annotations.PropertyKey
public fun message(@PropertyKey(resourceBundle = "idea.testData.findUsages.propertyFiles.propertyUsages.0") key: String) = key
public fun String.infixMessage(@PropertyKey(resourceBundle = "idea.testData.findUsages.propertyFiles.propertyUsages.0") key: String) = key
public fun @receiver:PropertyKey(resourceBundle = "idea.testData.findUsages.propertyFiles.propertyUsages.0") String.infixMessage2(s: String) = this
public fun @receiver:PropertyKey(resourceBundle = "idea.testData.findUsages.propertyFiles.propertyUsages.0") String.minus() = this
public fun Int.get(@PropertyKey(resourceBundle = "idea.testData.findUsages.propertyFiles.propertyUsages.0") key: String) = this
public fun @receiver:PropertyKey(resourceBundle = "idea.testData.findUsages.propertyFiles.propertyUsages.0") String.get(s: String) = this
fun test() {
@PropertyKey(resourceBundle = "idea.testData.findUsages.propertyFiles.propertyUsages.0") val s1 = "foo.bar"
@PropertyKey(resourceBundle = "idea.testData.findUsages.propertyFiles.propertyUsages.0") val s2 = "foo.baz"
message("foo.bar")
message("foo.baz")
"test" infixMessage "foo.bar"
"foo.bar" infixMessage "test"
"foo.bar" infixMessage2 "test"
"test" infixMessage2 "foo.bar"
"foo.bar".infixMessage2("test")
-"foo.bar"
1["foo.bar"]
"foo.bar"["test"]
"test"["foo.bar"]
}
@@ -0,0 +1,8 @@
class A {
void test() {
@PropertyKey(resourceBundle = "idea.testData.findUsages.propertyFiles.propertyUsages.0") String s1 = "foo.bar"
@PropertyKey(resourceBundle = "idea.testData.findUsages.propertyFiles.propertyUsages.0") String s2 = "foo.baz"
PropertyUsages_1Kt.message("foo.bar");
PropertyUsages_1Kt.message("foo.baz");
}
}
@@ -0,0 +1,5 @@
package org.jetbrains.annotations
@Retention(AnnotationRetention.BINARY)
@Target(AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.LOCAL_VARIABLE, AnnotationTarget.FIELD)
public annotation class PropertyKey(public val resourceBundle: String)
@@ -0,0 +1,10 @@
[propertyUsages.1.kt] Usage in string constants (16: 104) @PropertyKey(resourceBundle = "idea.testData.findUsages.propertyFiles.propertyUsages.0") val s1 = "foo.bar"
[propertyUsages.1.kt] Usage in string constants (18: 14) message("foo.bar")
[propertyUsages.1.kt] Usage in string constants (21: 26) "test" infixMessage "foo.bar"
[propertyUsages.1.kt] Usage in string constants (23: 6) "foo.bar" infixMessage2 "test"
[propertyUsages.1.kt] Usage in string constants (25: 6) "foo.bar".infixMessage2("test")
[propertyUsages.1.kt] Usage in string constants (26: 7) -"foo.bar"
[propertyUsages.1.kt] Usage in string constants (27: 8) 1["foo.bar"]
[propertyUsages.1.kt] Usage in string constants (28: 6) "foo.bar"["test"]
[propertyUsages.2.java] Usage in string constants (3: 111) @PropertyKey(resourceBundle = "idea.testData.findUsages.propertyFiles.propertyUsages.0") String s1 = "foo.bar"
[propertyUsages.2.java] Usage in string constants (5: 37) PropertyUsages_1Kt.message("foo.bar");
@@ -22,11 +22,12 @@ import com.google.common.base.Predicates;
import com.google.common.collect.Collections2;
import com.google.common.collect.Ordering;
import com.intellij.codeInsight.JavaTargetElementEvaluator;
import com.intellij.codeInsight.TargetElementUtil;
import com.intellij.codeInsight.TargetElementUtilBase;
import com.intellij.find.FindManager;
import com.intellij.find.findUsages.*;
import com.intellij.find.impl.FindManagerImpl;
import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.lang.properties.psi.Property;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
@@ -296,11 +297,21 @@ public abstract class AbstractJetFindUsagesTest extends JetLightCodeInsightFixtu
String mainFileText = FileUtil.loadFile(mainFile, true);
final String prefix = mainFileName.substring(0, mainFileName.indexOf('.') + 1);
List<String> caretElementClassNames = InTextDirectivesUtils.findLinesWithPrefixesRemoved(mainFileText, "// PSI_ELEMENT: ");
assert caretElementClassNames.size() == 1;
//noinspection unchecked
boolean isPropertiesFile = FileUtilRt.getExtension(path).equals("properties");
Class<T> caretElementClass = (Class<T>)Class.forName(caretElementClassNames.get(0));
Class<T> caretElementClass;
if (!isPropertiesFile) {
List<String> caretElementClassNames = InTextDirectivesUtils.findLinesWithPrefixesRemoved(mainFileText, "// PSI_ELEMENT: ");
assert caretElementClassNames.size() == 1;
//noinspection unchecked
caretElementClass = (Class<T>)Class.forName(caretElementClassNames.get(0));
}
else {
//noinspection unchecked
caretElementClass = (Class<T>) (InTextDirectivesUtils.isDirectiveDefined(mainFileText, "## FIND_FILE_USAGES")
? PropertiesFile.class
: Property.class);
}
OptionsParser parser = OptionsParser.getParserByPsiElementClass(caretElementClass);
@@ -317,6 +328,7 @@ public abstract class AbstractJetFindUsagesTest extends JetLightCodeInsightFixtu
return ext.equals("kt")
|| ext.equals("java")
|| ext.equals("xml")
|| ext.equals("properties")
|| (ext.equals("txt") && !name.endsWith(".results.txt"));
}
}
@@ -1036,6 +1036,27 @@ public class JetFindUsagesTestGenerated extends AbstractJetFindUsagesTest {
}
}
@TestMetadata("idea/testData/findUsages/kotlin/propertyFiles")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class PropertyFiles extends AbstractJetFindUsagesTest {
public void testAllFilesPresentInPropertyFiles() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/findUsages/kotlin/propertyFiles"), Pattern.compile("^(.+)\\.0\\.kt$"), true);
}
@TestMetadata("propertyFileUsagesByRef.0.kt")
public void testPropertyFileUsagesByRef() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/findUsages/kotlin/propertyFiles/propertyFileUsagesByRef.0.kt");
doTest(fileName);
}
@TestMetadata("propertyUsagesByRef.0.kt")
public void testPropertyUsagesByRef() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/findUsages/kotlin/propertyFiles/propertyUsagesByRef.0.kt");
doTest(fileName);
}
}
@TestMetadata("idea/testData/findUsages/kotlin/unresolvedAnnotation")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -1315,4 +1336,25 @@ public class JetFindUsagesTestGenerated extends AbstractJetFindUsagesTest {
}
}
}
@TestMetadata("idea/testData/findUsages/propertyFiles")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class PropertyFiles extends AbstractJetFindUsagesTest {
public void testAllFilesPresentInPropertyFiles() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/findUsages/propertyFiles"), Pattern.compile("^(.+)\\.0\\.properties$"), true);
}
@TestMetadata("propertyFileUsages.0.properties")
public void testPropertyFileUsages() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/findUsages/propertyFiles/propertyFileUsages.0.properties");
doTest(fileName);
}
@TestMetadata("propertyUsages.0.properties")
public void testPropertyUsages() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/findUsages/propertyFiles/propertyUsages.0.properties");
doTest(fileName);
}
}
}