From 5ae8b5149295a151ab261a954d40ea5810876aa6 Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Fri, 14 Mar 2014 13:18:45 +0400 Subject: [PATCH] Groovy: use method can be used with a list of classes --- .../groovy/lang/psi/util/GdkMethodUtil.java | 38 ++++++++++++++++--- .../GrCompletionWithLibraryTest.groovy | 4 +- .../completion/MultipleCategories2.groovy | 18 +++++++++ .../completion/MultipleCategories3.groovy | 18 +++++++++ 4 files changed, 72 insertions(+), 6 deletions(-) create mode 100644 plugins/groovy/testdata/groovy/completion/MultipleCategories2.groovy create mode 100644 plugins/groovy/testdata/groovy/completion/MultipleCategories3.groovy diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GdkMethodUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GdkMethodUtil.java index e5977bddf77e..5cda3e748ddb 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GdkMethodUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GdkMethodUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -25,9 +25,8 @@ import com.intellij.psi.*; import com.intellij.psi.scope.DelegatingScopeProcessor; import com.intellij.psi.scope.PsiScopeProcessor; import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.psi.util.CachedValueProvider; -import com.intellij.psi.util.CachedValuesManager; -import com.intellij.psi.util.PsiModificationTracker; +import com.intellij.psi.util.*; +import com.intellij.psi.util.PsiUtil; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -49,6 +48,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMe import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureParameter; import org.jetbrains.plugins.groovy.lang.psi.api.util.GrStatementOwner; import org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType; +import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleType; import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager; import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrReferenceResolveUtil; @@ -98,12 +98,40 @@ public class GdkMethodUtil { if (call == null) return true; final GrClosableBlock[] closures = call.getClosureArguments(); - final GrExpression[] args = call.getExpressionArguments(); + GrExpression[] args = call.getExpressionArguments(); if (!(placeEqualsSingleClosureArg(place, closures) || placeEqualsLastArg(place, args))) return true; if (!(call.resolveMethod() instanceof GrGdkMethod)) return true; state = state.put(ResolverProcessor.RESOLVE_CONTEXT, call); + + if ((args.length == 1 || args.length == 2 && placeEqualsLastArg(place, args))) { + PsiType type = args[0].getType(); + if (type instanceof GrTupleType) { + return processTypesFromTuple((GrTupleType)type, processor, state, place); + } + } + return processTypesFomArgs(args, processor, state, place); + } + + private static boolean processTypesFromTuple(@NotNull GrTupleType type, + @NotNull PsiScopeProcessor processor, + @NotNull ResolveState state, + @NotNull GrClosableBlock place) { + for (PsiType component : type.getComponentTypes()) { + PsiType clazz = PsiUtil.substituteTypeParameter(component, CommonClassNames.JAVA_LANG_CLASS, 0, false); + PsiClass aClass = PsiTypesUtil.getPsiClass(clazz); + if (aClass != null) { + if (!processCategoryMethods(place, processor, state, aClass)) return false; + } + } + return true; + } + + private static boolean processTypesFomArgs(@NotNull GrExpression[] args, + @NotNull PsiScopeProcessor processor, + @NotNull ResolveState state, + @NotNull GrClosableBlock place) { for (GrExpression arg : args) { if (arg instanceof GrReferenceExpression) { final PsiElement resolved = ((GrReferenceExpression)arg).resolve(); diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GrCompletionWithLibraryTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GrCompletionWithLibraryTest.groovy index f0a4f1af958a..32291ad12d47 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GrCompletionWithLibraryTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GrCompletionWithLibraryTest.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -45,6 +45,8 @@ class GrCompletionWithLibraryTest extends GroovyCompletionTestBase { public void testCategoryMethod() {doBasicTest()} public void testCategoryProperty() {doCompletionTest(null, null, '\n', CompletionType.BASIC)} public void testMultipleCategories() {doVariantableTest(null, "", CompletionType.BASIC, CompletionResult.contain, 'getMd5', 'getMd52')} + public void testMultipleCategories2() {doVariantableTest(null, "", CompletionType.BASIC, CompletionResult.contain, 'getMd5', 'getMd52')} + public void testMultipleCategories3() {doVariantableTest(null, "", CompletionType.BASIC, CompletionResult.contain, 'getMd5', 'getMd52')} public void testCategoryForArray() {doCompletionTest(null, null, '\n', CompletionType.BASIC)} public void testArrayLikeAccessForList() throws Throwable {doBasicTest(); } diff --git a/plugins/groovy/testdata/groovy/completion/MultipleCategories2.groovy b/plugins/groovy/testdata/groovy/completion/MultipleCategories2.groovy new file mode 100644 index 000000000000..027abf3bd65e --- /dev/null +++ b/plugins/groovy/testdata/groovy/completion/MultipleCategories2.groovy @@ -0,0 +1,18 @@ +class StringCategory { + static String getMd5(String s) { + return "MD5Value";//suppose to be some code that generate md5 + } +} + +class StringCategory2 { + static String getMd52(String s) { + return "MD5Value"; + } +} + + + +use([StringCategory, StringCategory2]) { + println "hello world".getMd +} + diff --git a/plugins/groovy/testdata/groovy/completion/MultipleCategories3.groovy b/plugins/groovy/testdata/groovy/completion/MultipleCategories3.groovy new file mode 100644 index 000000000000..a9c0c42b7658 --- /dev/null +++ b/plugins/groovy/testdata/groovy/completion/MultipleCategories3.groovy @@ -0,0 +1,18 @@ +class StringCategory { + static String getMd5(String s) { + return "MD5Value";//suppose to be some code that generate md5 + } +} + +class StringCategory2 { + static String getMd52(String s) { + return "MD5Value"; + } +} + + +def categories = [StringCategory, StringCategory2] +use(categories) { + println "hello world".getMd +} +