diff --git a/jvm/jvm-analysis-internal-testFramework/src/com/intellij/jvm/analysis/internal/testFramework/JavaApiUsageGenerator.kt b/jvm/jvm-analysis-internal-testFramework/src/com/intellij/jvm/analysis/internal/testFramework/JavaApiUsageGenerator.kt index f97d1c12ef36..93d8e957e822 100644 --- a/jvm/jvm-analysis-internal-testFramework/src/com/intellij/jvm/analysis/internal/testFramework/JavaApiUsageGenerator.kt +++ b/jvm/jvm-analysis-internal-testFramework/src/com/intellij/jvm/analysis/internal/testFramework/JavaApiUsageGenerator.kt @@ -132,7 +132,7 @@ class JavaApiUsageGenerator : LightJavaCodeInsightFixtureTestCase() { if (signature.contains("(")) { val methods = clazz.findMethodsByName(signature.substringAfter("#").substringBefore("("), true) if (methods.isEmpty()) return null - val paramFqns = signature.substringAfter("(").substringBefore(")").split(";").dropLast(1) + val paramFqns = getParamFqns(signature) val method = methods.firstOrNull { method -> if (method.parameterList.parametersCount != paramFqns.size) return@firstOrNull false method.getSignature(PsiSubstitutor.EMPTY).getParameterTypes().zip(paramFqns).all { (paramType, sigTypeCanonicalText) -> @@ -153,6 +153,10 @@ class JavaApiUsageGenerator : LightJavaCodeInsightFixtureTestCase() { } } + fun getParamFqns(signature: String): List { + return signature.substringAfter("(").substringBefore(")").split(";").dropLast(1) + } + /** * Run to generate API lists. * Setting [LANGUAGE_LEVEL], [SINCE_VERSION] and [JDK_HOME] or [PREVIEW_JDK_HOME] is required. @@ -196,6 +200,10 @@ class JavaApiUsageGenerator : LightJavaCodeInsightFixtureTestCase() { if (JavaPsiFacade.getInstance(project).findClass(className, GlobalSearchScope.allScope(project)) == null) { return // If the class is not in all scope, don't generate } + val paramFqns = getParamFqns(signature).map { name -> name.substringBefore("[").substringBefore("<") } + if (paramFqns.any { name -> !isValidTypeName(element, name) }) { + throw IllegalStateException("Generated parameters $paramFqns must be fully qualified or primitive") + } if (isDocumentedSinceApi(element) && !previews.contains(signature)) { println(signature) } else if (element is PsiMethod && element.docComment == null) { // find inherited doc @@ -222,6 +230,18 @@ class JavaApiUsageGenerator : LightJavaCodeInsightFixtureTestCase() { VfsUtilCore.iterateChildrenRecursively(srcFile, VirtualFileFilter.ALL, contentIterator) } + private fun isValidTypeName(element: PsiMember, name: String): Boolean { + if (name in PsiTypes.primitiveTypes().map(PsiPrimitiveType::getName)) return true + if (isValidTypeArgName(element, name)) return true + return name.contains(".") + } + + private fun isValidTypeArgName(element: PsiMember, name: String): Boolean { + if (element is PsiTypeParameterListOwner && name in element.typeParameters.map { it.name }) return true + val parent = element.parentOfType() ?: return false + return isValidTypeName(parent, name) + } + companion object { private const val TEMP_API_DIR = "REPLACE_ME"