diff --git a/plugins/devkit/devkit-core/resources/inspectionDescriptions/TokenSetInParserDefinition.html b/plugins/devkit/devkit-core/resources/inspectionDescriptions/TokenSetInParserDefinition.html
new file mode 100644
index 000000000000..21f3644804aa
--- /dev/null
+++ b/plugins/devkit/devkit-core/resources/inspectionDescriptions/TokenSetInParserDefinition.html
@@ -0,0 +1,85 @@
+
+
+Reports TokenSet field declarations referencing non-core element types in ParserDefinition classes.
+
+ All languages ParserDefinition are created on the application startup.
+ Declaring a TokenSet referencing non-core language element types may cause creating and registering
+ all the language element types in the holder class of the referenced type, even if a project doesn't contain any files in this language.
+
+
+Example:
+
+// element types holder:
+public interface MyLangTokenTypes {
+ IElementType COMMENT = new MyLangTokenType("COMMENT");
+ IElementType TYPE1 = new MyLangTokenType("TYPE1");
+ IElementType TYPE2 = new MyLangTokenType("TYPE2");
+ // more types...
+}
+
+
+// bad:
+
+public class MyLangParserDefinition implements ParserDefinition {
+ // this field causes initalizing and registering all the types from MyLangTokenTypes:
+ private static final TokenSet COMMENTS = TokenSet.create(MyLangTokenTypes.COMMENT);
+
+ @NotNull
+ @Override
+ public TokenSet getCommentTokens() {
+ return COMMENTS;
+ }
+ ...
+}
+
+
+// good:
+
+public final class MyLangTokenSets {
+ public static final TokenSet COMMENTS = TokenSet.create(MyLangTokenTypes.COMMENT);
+}
+
+public class MyLangParserDefinition implements ParserDefinition {
+ @NotNull
+ @Override
+ public TokenSet getCommentTokens() {
+ // types are referenced and registered only when this method is called:
+ return MyLangTokenSets.COMMENTS;
+ }
+ ...
+}
+
+// good (Kotlin):
+
+// top-level declaration is not loaded until getCommentTokens() method is called:
+private val COMMENTS = TokenSet.create(MyLangTokenTypes.COMMENT);
+
+class MyLangParserDefinition : ParserDefinition {
+ override getCommentTokens(): TokenSet {
+ return COMMENTS;
+ }
+ ...
+}
+
+// good:
+
+public class MyLangParserDefinition implements ParserDefinition {
+ // allowed core TokenSet:
+ private static final TokenSet COMMENTS1 = TokenSet.EMPTY;
+ // allowed core TokenType:
+ private static final TokenSet COMMENTS2 = TokenSet.create(TokenType.WHITE_SPACE);
+
+ @NotNull
+ @Override
+ public TokenSet getCommentTokens() {
+ ...
+ }
+ ...
+}
+
+
+
+
+New in 2023.2
+
+
diff --git a/plugins/devkit/devkit-core/resources/intellij.devkit.core.xml b/plugins/devkit/devkit-core/resources/intellij.devkit.core.xml
index 5215c5137193..769e0d5e97f2 100644
--- a/plugins/devkit/devkit-core/resources/intellij.devkit.core.xml
+++ b/plugins/devkit/devkit-core/resources/intellij.devkit.core.xml
@@ -315,6 +315,11 @@
groupPathKey="inspections.group.path" groupKey="inspections.group.code"
implementationClass="org.jetbrains.idea.devkit.inspections.ThreadingConcurrencyInspection"/>
+
+
diff --git a/plugins/devkit/devkit-core/resources/messages/DevKitBundle.properties b/plugins/devkit/devkit-core/resources/messages/DevKitBundle.properties
index e1f32ca3c70a..cc8e72167125 100644
--- a/plugins/devkit/devkit-core/resources/messages/DevKitBundle.properties
+++ b/plugins/devkit/devkit-core/resources/messages/DevKitBundle.properties
@@ -651,3 +651,6 @@ inspection.threading.concurrency.option.group.inside.requires.edt=Check inside @
inspection.threading.concurrency.option.group.inside.requires.edt.check.requires.read.lock=@RequiresReadLock
inspection.threading.concurrency.option.group.inside.requires.edt.check.requires.write.lock=@RequiresWriteLock
inspection.threading.concurrency.option.check.missing.annotations.methods=Check missing annotations for public methods
+
+inspection.token.set.in.parser.definition.display.name=Non-core TokenSet declared in ParserDefinition
+inspection.token.set.in.parser.definition=TokenSet in ParserDefinition references non-core classes
diff --git a/plugins/devkit/devkit-core/src/inspections/TokenSetInParserDefinitionInspection.kt b/plugins/devkit/devkit-core/src/inspections/TokenSetInParserDefinitionInspection.kt
new file mode 100644
index 000000000000..307a91d6e972
--- /dev/null
+++ b/plugins/devkit/devkit-core/src/inspections/TokenSetInParserDefinitionInspection.kt
@@ -0,0 +1,119 @@
+// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+package org.jetbrains.idea.devkit.inspections
+
+import com.intellij.codeInspection.InspectionManager
+import com.intellij.codeInspection.ProblemDescriptor
+import com.intellij.codeInspection.ProblemsHolder
+import com.intellij.lang.ParserDefinition
+import com.intellij.psi.PsiClassType
+import com.intellij.psi.TokenType
+import com.intellij.psi.tree.TokenSet
+import com.intellij.psi.util.InheritanceUtil
+import org.jetbrains.idea.devkit.DevKitBundle
+import org.jetbrains.uast.*
+import org.jetbrains.uast.visitor.AbstractUastVisitor
+
+internal class TokenSetInParserDefinitionInspection : DevKitUastInspectionBase(UClass::class.java) {
+
+ override fun checkClass(aClass: UClass, manager: InspectionManager, isOnTheFly: Boolean): Array {
+ if (!InheritanceUtil.isInheritor(aClass.javaPsi, ParserDefinition::class.java.name)) return ProblemDescriptor.EMPTY_ARRAY
+
+ val problemsHolder = createProblemsHolder(aClass, manager, isOnTheFly)
+ aClass.fields
+ .filter { it.isTokenSetField() && it.isIllegal(aClass) }
+ .forEach { reportField(it, problemsHolder) }
+
+ return problemsHolder.resultsArray
+ }
+
+ private fun UField.isTokenSetField(): Boolean {
+ val fieldType = (this.type as? PsiClassType)?.resolve() ?: return false
+ return fieldType.qualifiedName == TokenSet::class.java.name
+ }
+
+ private fun UField.isIllegal(aClass: UClass): Boolean {
+ val initializer = this.uastInitializer
+ if (initializer != null) {
+ return initializer.containsIllegalReferences()
+ }
+ else {
+ val constructors = aClass.methods.filter { it.isConstructor }
+ return constructors.any { it.containsFieldAssignmentWithIllegalReferences(this) } ||
+ aClass.initializers.any { it.containsFieldAssignmentWithIllegalReferences(this) } ||
+ companionObjectInitBlockContainsIllegalUsage(aClass)
+ }
+ }
+
+ private fun UExpression.containsIllegalReferences(): Boolean {
+ if (this is UResolvable) {
+ val resolved = this.resolveToUElement() ?: return false
+ when (resolved) {
+ is UField -> {
+ // TokenSet.EMPTY, TokenSet.ANY, etc. are allowed to use
+ return resolved.getContainingUClass()?.qualifiedName != TokenSet::class.java.name
+ }
+ is UMethod -> {
+ // check if assignment contains any non-core class usage
+ val nonCoreApiFinder = NonCoreApiFinder()
+ this.accept(nonCoreApiFinder)
+ return nonCoreApiFinder.nonCoreApiUsed
+ }
+ }
+ }
+ return false
+ }
+
+ private fun reportField(field: UField, problemsHolder: ProblemsHolder) {
+ val anchorPsi = field.getAnchorPsi() ?: return
+ problemsHolder.registerProblem(anchorPsi, DevKitBundle.message("inspection.token.set.in.parser.definition"))
+ }
+
+ private fun UDeclaration.containsFieldAssignmentWithIllegalReferences(field: UField): Boolean {
+ var containsIllegalAssignment = false
+ this.accept(object : AbstractUastVisitor() {
+ private val checkChildrenFlag = false
+ private val skipChildrenFlag = true
+ override fun visitBinaryExpression(node: UBinaryExpression): Boolean {
+ if (containsIllegalAssignment) return skipChildrenFlag
+ val resolvedElement = (node.leftOperand as? UReferenceExpression)?.resolveToUElement() ?: return checkChildrenFlag
+ if (resolvedElement.sourcePsi?.isEquivalentTo(field.sourcePsi) == true && node.rightOperand.containsIllegalReferences()) {
+ containsIllegalAssignment = true
+ return skipChildrenFlag
+ }
+ return checkChildrenFlag
+ }
+ })
+ return containsIllegalAssignment
+ }
+
+ private fun UField.companionObjectInitBlockContainsIllegalUsage(aClass: UClass): Boolean {
+ val companionInitBlock = aClass.innerClasses.firstOrNull { it.javaPsi.name == "Companion" }
+ ?.methods?.firstOrNull { it.javaPsi.name == "Companion" }
+ return companionInitBlock?.containsFieldAssignmentWithIllegalReferences(this) == true
+ }
+
+ private class NonCoreApiFinder : AbstractUastVisitor() {
+ private val checkChildrenFlag = false
+ private val skipChildrenFlag = true
+ var nonCoreApiUsed = false
+
+ override fun visitQualifiedReferenceExpression(node: UQualifiedReferenceExpression): Boolean {
+ return node.checkNonCoreApiUsage()
+ }
+
+ override fun visitSimpleNameReferenceExpression(node: USimpleNameReferenceExpression): Boolean {
+ return node.checkNonCoreApiUsage()
+ }
+
+ private fun UReferenceExpression.checkNonCoreApiUsage(): Boolean {
+ if (nonCoreApiUsed) return skipChildrenFlag
+ val resolvedElementContainingClass = this.resolveToUElement()?.getContainingUClass()?.qualifiedName ?: return checkChildrenFlag
+ if (resolvedElementContainingClass != TokenSet::class.java.name &&
+ resolvedElementContainingClass != TokenType::class.java.name) {
+ nonCoreApiUsed = true
+ return skipChildrenFlag
+ }
+ return checkChildrenFlag
+ }
+ }
+}
diff --git a/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/MyLangTokenTypes.java b/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/MyLangTokenTypes.java
new file mode 100644
index 000000000000..417d12e65906
--- /dev/null
+++ b/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/MyLangTokenTypes.java
@@ -0,0 +1,7 @@
+package com.example;
+
+import com.intellij.psi.tree.IElementType;
+
+public final class MyLangTokenTypes {
+ public static final IElementType COMMENT = null;
+}
diff --git a/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionNonDirectImplementorWithIllegalTokenSet.java b/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionNonDirectImplementorWithIllegalTokenSet.java
new file mode 100644
index 000000000000..9e85a2f63a0e
--- /dev/null
+++ b/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionNonDirectImplementorWithIllegalTokenSet.java
@@ -0,0 +1,16 @@
+import com.intellij.lang.ParserDefinition;
+import com.intellij.psi.tree.TokenSet;
+import com.example.MyLangTokenTypes;
+
+public class ParserDefinitionNonDirectImplementorWithIllegalTokenSet extends CustomParserDefinition {
+ public static final TokenSet COMMENTS = TokenSet.create(MyLangTokenTypes.COMMENT);
+
+ @Override
+ public TokenSet getCommentTokens() {
+ return COMMENTS;
+ }
+}
+
+abstract class CustomParserDefinition implements ParserDefinition {
+
+}
diff --git a/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithIllegalTokenSet.java b/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithIllegalTokenSet.java
new file mode 100644
index 000000000000..8f2a490dd295
--- /dev/null
+++ b/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithIllegalTokenSet.java
@@ -0,0 +1,12 @@
+import com.intellij.lang.ParserDefinition;
+import com.intellij.psi.tree.TokenSet;
+import com.example.MyLangTokenTypes;
+
+public class ParserDefinitionWithIllegalTokenSet implements ParserDefinition {
+ public static final TokenSet COMMENTS = TokenSet.create(MyLangTokenTypes.COMMENT);
+
+ @Override
+ public TokenSet getCommentTokens() {
+ return COMMENTS;
+ }
+}
diff --git a/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithIllegalTokenSetInitializedInConstructor.java b/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithIllegalTokenSetInitializedInConstructor.java
new file mode 100644
index 000000000000..b58e0bfd023c
--- /dev/null
+++ b/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithIllegalTokenSetInitializedInConstructor.java
@@ -0,0 +1,16 @@
+import com.intellij.lang.ParserDefinition;
+import com.intellij.psi.tree.TokenSet;
+import com.example.MyLangTokenTypes;
+
+public class ParserDefinitionWithIllegalTokenSetInitializedInConstructor implements ParserDefinition {
+ public final TokenSet comments;
+
+ public ParserDefinitionWithIllegalTokenSetInitializedInConstructor() {
+ comments = TokenSet.create(MyLangTokenTypes.COMMENT);
+ }
+
+ @Override
+ public TokenSet getCommentTokens() {
+ return comments;
+ }
+}
diff --git a/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithIllegalTokenSetInitializedInStaticBlock.java b/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithIllegalTokenSetInitializedInStaticBlock.java
new file mode 100644
index 000000000000..2a40d86b29ee
--- /dev/null
+++ b/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithIllegalTokenSetInitializedInStaticBlock.java
@@ -0,0 +1,16 @@
+import com.intellij.lang.ParserDefinition;
+import com.intellij.psi.tree.TokenSet;
+import com.example.MyLangTokenTypes;
+
+public class ParserDefinitionWithIllegalTokenSetInitializedInStaticBlock implements ParserDefinition {
+ public static final TokenSet COMMENTS;
+
+ static {
+ COMMENTS = TokenSet.create(MyLangTokenTypes.COMMENT);
+ }
+
+ @Override
+ public TokenSet getCommentTokens() {
+ return COMMENTS;
+ }
+}
diff --git a/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithIllegalTokenSetWhenComplexCreation.java b/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithIllegalTokenSetWhenComplexCreation.java
new file mode 100644
index 000000000000..f7a5eb8ace9a
--- /dev/null
+++ b/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithIllegalTokenSetWhenComplexCreation.java
@@ -0,0 +1,12 @@
+import com.intellij.lang.ParserDefinition;
+import com.intellij.psi.tree.TokenSet;
+import com.example.MyLangTokenTypes;
+
+public class ParserDefinitionWithIllegalTokenSetWhenComplexCreation implements ParserDefinition {
+ public static final TokenSet COMMENTS = TokenSet.orSet(TokenSet.create(MyLangTokenTypes.COMMENT), TokenSet.create(MyLangTokenTypes.COMMENT));
+
+ @Override
+ public TokenSet getCommentTokens() {
+ return COMMENTS;
+ }
+}
diff --git a/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithIllegalTokenSetWhenStaticImportsUsed.java b/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithIllegalTokenSetWhenStaticImportsUsed.java
new file mode 100644
index 000000000000..a4e90780ed9b
--- /dev/null
+++ b/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithIllegalTokenSetWhenStaticImportsUsed.java
@@ -0,0 +1,14 @@
+import com.intellij.lang.ParserDefinition;
+import com.intellij.psi.tree.TokenSet;
+
+import static com.example.MyLangTokenTypes.COMMENT;
+import static com.intellij.psi.tree.TokenSet.create;
+
+public class ParserDefinitionWithIllegalTokenSetWhenStaticImportsUsed implements ParserDefinition {
+ public static final TokenSet COMMENTS = create(COMMENT);
+
+ @Override
+ public TokenSet getCommentTokens() {
+ return COMMENTS;
+ }
+}
diff --git a/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenSet.java b/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenSet.java
new file mode 100644
index 000000000000..c9465e80945e
--- /dev/null
+++ b/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenSet.java
@@ -0,0 +1,10 @@
+import com.intellij.lang.ParserDefinition;
+import com.intellij.psi.tree.TokenSet;
+
+public class ParserDefinitionWithLegalCoreTokenSet implements ParserDefinition {
+ public static final TokenSet COMMENTS = TokenSet.EMPTY;
+ @Override
+ public TokenSet getCommentTokens() {
+ return COMMENTS;
+ }
+}
diff --git a/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenSetInitializedInConstructor.java b/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenSetInitializedInConstructor.java
new file mode 100644
index 000000000000..7b1ea82cb99c
--- /dev/null
+++ b/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenSetInitializedInConstructor.java
@@ -0,0 +1,15 @@
+import com.intellij.lang.ParserDefinition;
+import com.intellij.psi.tree.TokenSet;
+
+public class ParserDefinitionWithLegalCoreTokenSetInitializedInConstructor implements ParserDefinition {
+ public final TokenSet comments;
+
+ public ParserDefinitionWithLegalCoreTokenSetInitializedInConstructor() {
+ comments = TokenSet.EMPTY;
+ }
+
+ @Override
+ public TokenSet getCommentTokens() {
+ return comments;
+ }
+}
diff --git a/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenSetInitializedInStaticBlock.java b/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenSetInitializedInStaticBlock.java
new file mode 100644
index 000000000000..ed9b27ae0e98
--- /dev/null
+++ b/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenSetInitializedInStaticBlock.java
@@ -0,0 +1,15 @@
+import com.intellij.lang.ParserDefinition;
+import com.intellij.psi.tree.TokenSet;
+
+public class ParserDefinitionWithLegalCoreTokenSetInitializedInStaticBlock implements ParserDefinition {
+ public static final TokenSet COMMENTS;
+
+ static {
+ COMMENTS = TokenSet.EMPTY;
+ }
+
+ @Override
+ public TokenSet getCommentTokens() {
+ return COMMENTS;
+ }
+}
diff --git a/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenType.java b/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenType.java
new file mode 100644
index 000000000000..f31332b112d1
--- /dev/null
+++ b/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenType.java
@@ -0,0 +1,11 @@
+import com.intellij.lang.ParserDefinition;
+import com.intellij.psi.TokenType;
+import com.intellij.psi.tree.TokenSet;
+
+public class ParserDefinitionWithLegalCoreTokenType implements ParserDefinition {
+ public static final TokenSet COMMENTS = TokenSet.create(TokenType.WHITE_SPACE);
+ @Override
+ public TokenSet getCommentTokens() {
+ return COMMENTS;
+ }
+}
diff --git a/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenTypeInitializedInConstructor.java b/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenTypeInitializedInConstructor.java
new file mode 100644
index 000000000000..efbad465318b
--- /dev/null
+++ b/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenTypeInitializedInConstructor.java
@@ -0,0 +1,16 @@
+import com.intellij.lang.ParserDefinition;
+import com.intellij.psi.TokenType;
+import com.intellij.psi.tree.TokenSet;
+
+public class ParserDefinitionWithLegalCoreTokenTypeInitializedInConstructor implements ParserDefinition {
+ public final TokenSet comments;
+
+ public ParserDefinitionWithLegalCoreTokenTypeInitializedInConstructor() {
+ comments = TokenSet.create(TokenType.WHITE_SPACE);
+ }
+
+ @Override
+ public TokenSet getCommentTokens() {
+ return comments;
+ }
+}
diff --git a/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenTypeInitializedInStaticBlock.java b/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenTypeInitializedInStaticBlock.java
new file mode 100644
index 000000000000..35c3ca7eb845
--- /dev/null
+++ b/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenTypeInitializedInStaticBlock.java
@@ -0,0 +1,16 @@
+import com.intellij.lang.ParserDefinition;
+import com.intellij.psi.TokenType;
+import com.intellij.psi.tree.TokenSet;
+
+public class ParserDefinitionWithLegalCoreTokenTypeInitializedInStaticBlock implements ParserDefinition {
+ public static final TokenSet COMMENTS;
+
+ static {
+ COMMENTS = TokenSet.create(TokenType.WHITE_SPACE);
+ }
+
+ @Override
+ public TokenSet getCommentTokens() {
+ return COMMENTS;
+ }
+}
diff --git a/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalTokenSetInitializedLazilyInMethod.java b/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalTokenSetInitializedLazilyInMethod.java
new file mode 100644
index 000000000000..185cbedbda8f
--- /dev/null
+++ b/plugins/devkit/devkit-java-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalTokenSetInitializedLazilyInMethod.java
@@ -0,0 +1,14 @@
+import com.intellij.lang.ParserDefinition;
+import com.intellij.psi.tree.TokenSet;
+import com.example.MyLangTokenTypes;
+
+public class ParserDefinitionWithLegalTokenSetInitializedLazilyInMethod implements ParserDefinition {
+ private TokenSet comments;
+ @Override
+ public TokenSet getCommentTokens() {
+ if (comments == null) {
+ comments = TokenSet.create(MyLangTokenTypes.COMMENT);
+ }
+ return comments;
+ }
+}
diff --git a/plugins/devkit/devkit-java-tests/testSrc/org/jetbrains/idea/devkit/inspections/TokenSetInParserDefinitionInspectionTest.kt b/plugins/devkit/devkit-java-tests/testSrc/org/jetbrains/idea/devkit/inspections/TokenSetInParserDefinitionInspectionTest.kt
new file mode 100644
index 000000000000..40d7e5eb8743
--- /dev/null
+++ b/plugins/devkit/devkit-java-tests/testSrc/org/jetbrains/idea/devkit/inspections/TokenSetInParserDefinitionInspectionTest.kt
@@ -0,0 +1,69 @@
+// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+package org.jetbrains.idea.devkit.inspections
+
+import com.intellij.testFramework.TestDataPath
+import org.jetbrains.idea.devkit.DevkitJavaTestsUtil
+
+@TestDataPath("\$CONTENT_ROOT/testData/inspections/tokenSetInParserDefinition")
+class TokenSetInParserDefinitionInspectionTest : TokenSetInParserDefinitionInspectionTestBase() {
+ override fun getBasePath() = DevkitJavaTestsUtil.TESTDATA_PATH + "inspections/tokenSetInParserDefinition"
+ override fun getFileExtension() = "java"
+
+ fun testParserDefinitionWithIllegalTokenSet() {
+ doInspectionTest()
+ }
+
+ fun testParserDefinitionWithIllegalTokenSetWhenComplexCreation() {
+ doInspectionTest()
+ }
+
+ fun testParserDefinitionWithIllegalTokenSetWhenStaticImportsUsed() {
+ doInspectionTest()
+ }
+
+ fun testParserDefinitionNonDirectImplementorWithIllegalTokenSet() {
+ doInspectionTest()
+ }
+
+ fun testParserDefinitionWithIllegalTokenSetInitializedInConstructor() {
+ doInspectionTest()
+ }
+
+ fun testParserDefinitionWithIllegalTokenSetInitializedInStaticBlock() {
+ doInspectionTest()
+ }
+
+ fun testParserDefinitionWithLegalCoreTokenSet() {
+ doInspectionTest()
+ }
+
+ fun testParserDefinitionWithLegalCoreTokenSetInitializedInConstructor() {
+ doInspectionTest()
+ }
+
+ fun testParserDefinitionWithLegalCoreTokenSetInitializedInStaticBlock() {
+ doInspectionTest()
+ }
+
+ fun testParserDefinitionWithLegalCoreTokenType() {
+ doInspectionTest()
+ }
+
+ fun testParserDefinitionWithLegalCoreTokenTypeInitializedInConstructor() {
+ doInspectionTest()
+ }
+
+ fun testParserDefinitionWithLegalCoreTokenTypeInitializedInStaticBlock() {
+ doInspectionTest()
+ }
+
+ fun testParserDefinitionWithLegalTokenSetInitializedLazilyInMethod() {
+ doInspectionTest()
+ }
+
+ private fun doInspectionTest() {
+ myFixture.copyFileToProject("MyLangTokenTypes.java")
+ doTest()
+ }
+
+}
diff --git a/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/MyLangTokenTypes.kt b/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/MyLangTokenTypes.kt
new file mode 100644
index 000000000000..1b2859da0f89
--- /dev/null
+++ b/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/MyLangTokenTypes.kt
@@ -0,0 +1,7 @@
+package com.example
+
+import com.intellij.psi.tree.IElementType
+
+object MyLangTokenTypes {
+ val COMMENT: IElementType? = null
+}
diff --git a/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionNonDirectImplementorWithIllegalTokenSet.kt b/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionNonDirectImplementorWithIllegalTokenSet.kt
new file mode 100644
index 000000000000..ca24f4a81717
--- /dev/null
+++ b/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionNonDirectImplementorWithIllegalTokenSet.kt
@@ -0,0 +1,12 @@
+import com.intellij.lang.ParserDefinition
+import com.intellij.psi.tree.TokenSet
+import com.example.MyLangTokenTypes
+
+class ParserDefinitionNonDirectImplementorWithIllegalTokenSet : CustomParserDefinition() {
+ val COMMENTS = TokenSet.create(MyLangTokenTypes.COMMENT)
+ override fun getCommentTokens(): TokenSet {
+ return COMMENTS
+ }
+}
+
+abstract class CustomParserDefinition : ParserDefinition
diff --git a/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithIllegalTokenSet.kt b/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithIllegalTokenSet.kt
new file mode 100644
index 000000000000..3dd463728a1b
--- /dev/null
+++ b/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithIllegalTokenSet.kt
@@ -0,0 +1,10 @@
+import com.intellij.lang.ParserDefinition
+import com.intellij.psi.tree.TokenSet
+import com.example.MyLangTokenTypes
+
+class ParserDefinitionWithIllegalTokenSet : ParserDefinition {
+ val COMMENTS = TokenSet.create(MyLangTokenTypes.COMMENT)
+ override fun getCommentTokens(): TokenSet {
+ return COMMENTS
+ }
+}
diff --git a/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithIllegalTokenSetInCompanionObject.kt b/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithIllegalTokenSetInCompanionObject.kt
new file mode 100644
index 000000000000..3f8ef3842655
--- /dev/null
+++ b/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithIllegalTokenSetInCompanionObject.kt
@@ -0,0 +1,12 @@
+import com.intellij.lang.ParserDefinition
+import com.intellij.psi.tree.TokenSet
+import com.example.MyLangTokenTypes
+
+class ParserDefinitionWithIllegalTokenSetInCompanionObject : ParserDefinition {
+ override fun getCommentTokens(): TokenSet {
+ return COMMENTS
+ }
+ companion object {
+ val COMMENTS = TokenSet.create(MyLangTokenTypes.COMMENT)
+ }
+}
diff --git a/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithIllegalTokenSetInitializedInCompanionObjectInitBlock.kt b/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithIllegalTokenSetInitializedInCompanionObjectInitBlock.kt
new file mode 100644
index 000000000000..4a5eeb8a388b
--- /dev/null
+++ b/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithIllegalTokenSetInitializedInCompanionObjectInitBlock.kt
@@ -0,0 +1,17 @@
+import com.intellij.lang.ParserDefinition
+import com.intellij.psi.tree.TokenSet
+import com.example.MyLangTokenTypes
+
+class ParserDefinitionWithIllegalTokenSetInitializedInCompanionObjectInitBlock : ParserDefinition {
+ override fun getCommentTokens(): TokenSet {
+ return COMMENTS
+ }
+
+ companion object {
+ val COMMENTS: TokenSet
+
+ init {
+ COMMENTS = TokenSet.create(MyLangTokenTypes.COMMENT)
+ }
+ }
+}
diff --git a/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithIllegalTokenSetInitializedInConstructor.kt b/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithIllegalTokenSetInitializedInConstructor.kt
new file mode 100644
index 000000000000..5dc86c89c17f
--- /dev/null
+++ b/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithIllegalTokenSetInitializedInConstructor.kt
@@ -0,0 +1,14 @@
+import com.intellij.lang.ParserDefinition
+import com.intellij.psi.tree.TokenSet
+import com.example.MyLangTokenTypes
+
+class ParserDefinitionWithIllegalTokenSetInitializedInConstructor : ParserDefinition {
+ val comments: TokenSet
+ constructor() {
+ comments = TokenSet.create(MyLangTokenTypes.COMMENT)
+ }
+
+ override fun getCommentTokens(): TokenSet {
+ return comments
+ }
+}
diff --git a/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithIllegalTokenSetInitializedInInitBlock.kt b/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithIllegalTokenSetInitializedInInitBlock.kt
new file mode 100644
index 000000000000..0de80a994416
--- /dev/null
+++ b/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithIllegalTokenSetInitializedInInitBlock.kt
@@ -0,0 +1,15 @@
+import com.intellij.lang.ParserDefinition
+import com.intellij.psi.tree.TokenSet
+import com.example.MyLangTokenTypes
+
+class ParserDefinitionWithIllegalTokenSetInitializedInInitBlock : ParserDefinition {
+ val comments: TokenSet
+
+ init {
+ comments = TokenSet.create(MyLangTokenTypes.COMMENT)
+ }
+
+ override fun getCommentTokens(): TokenSet {
+ return comments
+ }
+}
diff --git a/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithIllegalTokenSetWhenComplexCreation.kt b/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithIllegalTokenSetWhenComplexCreation.kt
new file mode 100644
index 000000000000..ed12572adb8a
--- /dev/null
+++ b/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithIllegalTokenSetWhenComplexCreation.kt
@@ -0,0 +1,10 @@
+import com.intellij.lang.ParserDefinition
+import com.intellij.psi.tree.TokenSet
+import com.example.MyLangTokenTypes
+
+class ParserDefinitionWithIllegalTokenSetWhenComplexCreation : ParserDefinition {
+ val COMMENTS = TokenSet.orSet(TokenSet.create(MyLangTokenTypes.COMMENT), TokenSet.create(MyLangTokenTypes.COMMENT))
+ override fun getCommentTokens(): TokenSet {
+ return COMMENTS
+ }
+}
diff --git a/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithIllegalTokenSetWhenMembersImported.kt b/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithIllegalTokenSetWhenMembersImported.kt
new file mode 100644
index 000000000000..e2c97f29a5cf
--- /dev/null
+++ b/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithIllegalTokenSetWhenMembersImported.kt
@@ -0,0 +1,11 @@
+import com.intellij.lang.ParserDefinition
+import com.intellij.psi.tree.TokenSet
+import com.intellij.psi.tree.TokenSet.create
+import com.example.MyLangTokenTypes.COMMENT
+
+class ParserDefinitionWithIllegalTokenSetWhenMembersImported : ParserDefinition {
+ val COMMENTS = create(COMMENT)
+ override fun getCommentTokens(): TokenSet {
+ return COMMENTS
+ }
+}
diff --git a/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenSet.kt b/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenSet.kt
new file mode 100644
index 000000000000..59fd312bca0d
--- /dev/null
+++ b/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenSet.kt
@@ -0,0 +1,9 @@
+import com.intellij.lang.ParserDefinition
+import com.intellij.psi.tree.TokenSet
+
+class ParserDefinitionWithLegalCoreTokenSet : ParserDefinition {
+ val comments = TokenSet.EMPTY
+ override fun getCommentTokens(): TokenSet {
+ return comments
+ }
+}
diff --git a/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenSetInCompanionObject.kt b/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenSetInCompanionObject.kt
new file mode 100644
index 000000000000..d75f9b02221c
--- /dev/null
+++ b/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenSetInCompanionObject.kt
@@ -0,0 +1,11 @@
+import com.intellij.lang.ParserDefinition
+import com.intellij.psi.tree.TokenSet
+
+class ParserDefinitionWithLegalCoreTokenSetInCompanionObject : ParserDefinition {
+ override fun getCommentTokens(): TokenSet {
+ return COMMENTS
+ }
+ companion object {
+ val COMMENTS = TokenSet.EMPTY
+ }
+}
diff --git a/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenSetInitializedInCompanionObjectInitBlock.kt b/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenSetInitializedInCompanionObjectInitBlock.kt
new file mode 100644
index 000000000000..ef507d547bf9
--- /dev/null
+++ b/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenSetInitializedInCompanionObjectInitBlock.kt
@@ -0,0 +1,16 @@
+import com.intellij.lang.ParserDefinition
+import com.intellij.psi.tree.TokenSet
+
+class ParserDefinitionWithLegalCoreTokenSetInitializedInCompanionObjectInitBlock : ParserDefinition {
+ override fun getCommentTokens(): TokenSet {
+ return COMMENTS
+ }
+
+ companion object {
+ val COMMENTS: TokenSet
+
+ init {
+ COMMENTS = TokenSet.EMPTY
+ }
+ }
+}
diff --git a/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenSetInitializedInConstructor.kt b/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenSetInitializedInConstructor.kt
new file mode 100644
index 000000000000..af32fe4f1eb8
--- /dev/null
+++ b/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenSetInitializedInConstructor.kt
@@ -0,0 +1,14 @@
+import com.intellij.lang.ParserDefinition
+import com.intellij.psi.tree.TokenSet
+
+class ParserDefinitionWithLegalCoreTokenSetInitializedInConstructor : ParserDefinition {
+ val comments: TokenSet
+
+ init {
+ comments = TokenSet.EMPTY
+ }
+
+ override fun getCommentTokens(): TokenSet {
+ return comments
+ }
+}
diff --git a/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenType.kt b/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenType.kt
new file mode 100644
index 000000000000..d267d8a36113
--- /dev/null
+++ b/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenType.kt
@@ -0,0 +1,13 @@
+import com.intellij.lang.ParserDefinition
+import com.intellij.psi.TokenType
+import com.intellij.psi.tree.TokenSet
+
+class ParserDefinitionWithLegalCoreTokenType : ParserDefinition {
+ override fun getCommentTokens(): TokenSet {
+ return COMMENTS
+ }
+
+ companion object {
+ val COMMENTS = TokenSet.create(TokenType.WHITE_SPACE)
+ }
+}
diff --git a/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenTypeInitializedInConstructor.kt b/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenTypeInitializedInConstructor.kt
new file mode 100644
index 000000000000..ef7b9a7ff115
--- /dev/null
+++ b/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenTypeInitializedInConstructor.kt
@@ -0,0 +1,15 @@
+import com.intellij.lang.ParserDefinition
+import com.intellij.psi.TokenType
+import com.intellij.psi.tree.TokenSet
+
+class ParserDefinitionWithLegalCoreTokenTypeInitializedInConstructor : ParserDefinition {
+ val comments: TokenSet
+
+ init {
+ comments = TokenSet.create(TokenType.WHITE_SPACE)
+ }
+
+ override fun getCommentTokens(): TokenSet {
+ return comments
+ }
+}
diff --git a/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenTypeInitializedInStaticBlock.kt b/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenTypeInitializedInStaticBlock.kt
new file mode 100644
index 000000000000..498b57aa32a1
--- /dev/null
+++ b/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalCoreTokenTypeInitializedInStaticBlock.kt
@@ -0,0 +1,17 @@
+import com.intellij.lang.ParserDefinition
+import com.intellij.psi.TokenType
+import com.intellij.psi.tree.TokenSet
+
+class ParserDefinitionWithLegalCoreTokenTypeInitializedInStaticBlock : ParserDefinition {
+ override fun getCommentTokens(): TokenSet {
+ return COMMENTS
+ }
+
+ companion object {
+ val COMMENTS: TokenSet
+
+ init {
+ COMMENTS = TokenSet.create(TokenType.WHITE_SPACE)
+ }
+ }
+}
diff --git a/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalTokenSetDeclaredOnTopLevel.kt b/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalTokenSetDeclaredOnTopLevel.kt
new file mode 100644
index 000000000000..48c0550df6c5
--- /dev/null
+++ b/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalTokenSetDeclaredOnTopLevel.kt
@@ -0,0 +1,11 @@
+import com.intellij.lang.ParserDefinition
+import com.intellij.psi.tree.TokenSet
+import com.example.MyLangTokenTypes
+
+val comments: TokenSet = TokenSet.create(MyLangTokenTypes.COMMENT)
+
+class ParserDefinitionWithLegalTokenSetDeclaredOnTopLevel : ParserDefinition {
+ override fun getCommentTokens(): TokenSet {
+ return comments
+ }
+}
diff --git a/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalTokenSetInitializedLazilyInMethod.kt b/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalTokenSetInitializedLazilyInMethod.kt
new file mode 100644
index 000000000000..f161f0b53e44
--- /dev/null
+++ b/plugins/devkit/devkit-kotlin-tests/testData/inspections/tokenSetInParserDefinition/ParserDefinitionWithLegalTokenSetInitializedLazilyInMethod.kt
@@ -0,0 +1,13 @@
+import com.intellij.lang.ParserDefinition
+import com.intellij.psi.tree.TokenSet
+import com.example.MyLangTokenTypes
+
+class ParserDefinitionWithLegalTokenSetInitializedLazilyInMethod : ParserDefinition {
+ private var comments: TokenSet? = null
+ override fun getCommentTokens(): TokenSet {
+ if (comments == null) {
+ comments = TokenSet.create(MyLangTokenTypes.COMMENT)
+ }
+ return comments!!
+ }
+}
diff --git a/plugins/devkit/devkit-kotlin-tests/testSrc/org/jetbrains/idea/devkit/kotlin/inspections/KtTokenSetInParserDefinitionInspectionTest.kt b/plugins/devkit/devkit-kotlin-tests/testSrc/org/jetbrains/idea/devkit/kotlin/inspections/KtTokenSetInParserDefinitionInspectionTest.kt
new file mode 100644
index 000000000000..262cb2ebf3a7
--- /dev/null
+++ b/plugins/devkit/devkit-kotlin-tests/testSrc/org/jetbrains/idea/devkit/kotlin/inspections/KtTokenSetInParserDefinitionInspectionTest.kt
@@ -0,0 +1,86 @@
+// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+package org.jetbrains.idea.devkit.kotlin.inspections
+
+import com.intellij.testFramework.TestDataPath
+import org.jetbrains.idea.devkit.inspections.TokenSetInParserDefinitionInspectionTestBase
+import org.jetbrains.idea.devkit.kotlin.DevkitKtTestsUtil
+
+@TestDataPath("/inspections/tokenSetInParserDefinition")
+class KtTokenSetInParserDefinitionInspectionTest : TokenSetInParserDefinitionInspectionTestBase() {
+ override fun getBasePath() = DevkitKtTestsUtil.TESTDATA_PATH + "inspections/tokenSetInParserDefinition"
+ override fun getFileExtension() = "kt"
+
+ fun testParserDefinitionWithIllegalTokenSet() {
+ doInspectionTest()
+ }
+
+ fun testParserDefinitionWithIllegalTokenSetWhenComplexCreation() {
+ doInspectionTest()
+ }
+
+ fun testParserDefinitionNonDirectImplementorWithIllegalTokenSet() {
+ doInspectionTest()
+ }
+
+ fun testParserDefinitionWithIllegalTokenSetInCompanionObject() {
+ doInspectionTest()
+ }
+
+ fun testParserDefinitionWithIllegalTokenSetInitializedInCompanionObjectInitBlock() {
+ doInspectionTest()
+ }
+
+ fun testParserDefinitionWithIllegalTokenSetInitializedInConstructor() {
+ doInspectionTest()
+ }
+
+ fun testParserDefinitionWithIllegalTokenSetInitializedInInitBlock() {
+ doInspectionTest()
+ }
+
+ fun testParserDefinitionWithIllegalTokenSetWhenMembersImported() {
+ doInspectionTest()
+ }
+
+ fun testParserDefinitionWithLegalCoreTokenSet() {
+ doInspectionTest()
+ }
+
+ fun testParserDefinitionWithLegalCoreTokenSetInCompanionObject() {
+ doInspectionTest()
+ }
+
+ fun testParserDefinitionWithLegalCoreTokenSetInitializedInCompanionObjectInitBlock() {
+ doInspectionTest()
+ }
+
+ fun testParserDefinitionWithLegalCoreTokenSetInitializedInConstructor() {
+ doInspectionTest()
+ }
+
+ fun testParserDefinitionWithLegalCoreTokenType() {
+ doInspectionTest()
+ }
+
+ fun testParserDefinitionWithLegalCoreTokenTypeInitializedInConstructor() {
+ doInspectionTest()
+ }
+
+ fun testParserDefinitionWithLegalCoreTokenTypeInitializedInStaticBlock() {
+ doInspectionTest()
+ }
+
+ fun testParserDefinitionWithLegalTokenSetDeclaredOnTopLevel() {
+ doInspectionTest()
+ }
+
+ fun testParserDefinitionWithLegalTokenSetInitializedLazilyInMethod() {
+ doInspectionTest()
+ }
+
+
+ private fun doInspectionTest() {
+ myFixture.copyFileToProject("MyLangTokenTypes.kt")
+ doTest()
+ }
+}
diff --git a/plugins/devkit/devkit-tests/testSrc/org/jetbrains/idea/devkit/inspections/TokenSetInParserDefinitionInspectionTestBase.kt b/plugins/devkit/devkit-tests/testSrc/org/jetbrains/idea/devkit/inspections/TokenSetInParserDefinitionInspectionTestBase.kt
new file mode 100644
index 000000000000..3a46f9386346
--- /dev/null
+++ b/plugins/devkit/devkit-tests/testSrc/org/jetbrains/idea/devkit/inspections/TokenSetInParserDefinitionInspectionTestBase.kt
@@ -0,0 +1,71 @@
+// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+package org.jetbrains.idea.devkit.inspections
+
+import org.jetbrains.idea.devkit.inspections.quickfix.LightDevKitInspectionFixTestBase
+
+abstract class TokenSetInParserDefinitionInspectionTestBase : LightDevKitInspectionFixTestBase() {
+
+ override fun setUp() {
+ super.setUp()
+
+ myFixture.addClass("""
+ package com.intellij.lang;
+ public abstract class Language {}
+ """.trimIndent())
+
+ myFixture.addClass("""
+ package com.intellij.psi.tree;
+
+ import com.intellij.lang.Language;
+
+ public class IElementType {
+ public IElementType(String debugName, Language language) {
+ // any
+ }
+ }
+ """.trimIndent())
+
+ myFixture.addClass("""
+ package com.intellij.psi;
+
+ import com.intellij.psi.tree.IElementType;
+
+ public interface TokenType {
+ IElementType WHITE_SPACE = null;
+ }
+ """.trimIndent())
+
+ myFixture.addClass("""
+ package com.intellij.psi.tree;
+
+ public final class TokenSet {
+ public static final TokenSet EMPTY = null;
+ public static final TokenSet ANY = null;
+ public static final TokenSet WHITE_SPACE = null;
+
+ public static TokenSet create(IElementType... types) {
+ return null;
+ }
+
+ public static TokenSet orSet(TokenSet... sets) {
+ return null;
+ }
+
+ }
+ """.trimIndent())
+
+ myFixture.addClass("""
+ package com.intellij.lang;
+
+ import com.intellij.psi.tree.TokenSet;
+
+ public interface ParserDefinition {
+ // only a single TokenSet-related method for simplicity
+ TokenSet getCommentTokens();
+ }
+ """.trimIndent())
+
+ myFixture.enableInspections(TokenSetInParserDefinitionInspection())
+ }
+
+}