User: joe Date: 23 Oct 25 00:35 Revision: 3b13b6633804b9109e472d7a56b180d42c6e3916 Summary: Rename accessWideners to classTweakers, and support classTweaker v1 TeamCity URL: http://ci.mcdev.io:80/viewModification.html?tab=vcsModificationFiles&modId=10190&personal=false Index: build.gradle.kts =================================================================== --- build.gradle.kts (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) +++ build.gradle.kts (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -263,8 +263,8 @@ val generateAtLexer by lexer("AtLexer", "com/demonwav/mcdev/platform/mcp/at/gen") val generateAtParser by parser("AtParser", "com/demonwav/mcdev/platform/mcp/at/gen") -val generateAwLexer by lexer("AwLexer", "com/demonwav/mcdev/platform/mcp/aw/gen") -val generateAwParser by parser("AwParser", "com/demonwav/mcdev/platform/mcp/aw/gen") +val generateCtLexer by lexer("CtLexer", "com/demonwav/mcdev/platform/mcp/ct/gen") +val generateCtParser by parser("CtParser", "com/demonwav/mcdev/platform/mcp/ct/gen") val generateNbttLexer by lexer("NbttLexer", "com/demonwav/mcdev/nbt/lang/gen") val generateNbttParser by parser("NbttParser", "com/demonwav/mcdev/nbt/lang/gen") @@ -287,8 +287,8 @@ dependsOn( generateAtLexer, generateAtParser, - generateAwLexer, - generateAwParser, + generateCtLexer, + generateCtParser, generateNbttLexer, generateNbttParser, generateLangLexer, Index: src/main/grammars/AwLexer.flex =================================================================== --- src/main/grammars/AwLexer.flex (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) +++ src/main/grammars/AwLexer.flex (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) @@ -1,98 +0,0 @@ -/* - * Minecraft Development for IntelliJ - * - * https://mcdev.io/ - * - * Copyright (C) 2025 minecraft-dev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, version 3.0 only. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.demonwav.mcdev.platform.mcp.aw.gen; - -import com.intellij.lexer.*; -import com.intellij.psi.tree.IElementType; -import static com.demonwav.mcdev.platform.mcp.aw.gen.psi.AwTypes.*; -import static com.intellij.psi.TokenType.*; - -%% - -%{ - public AwLexer() { - this((java.io.Reader)null); - } -%} - -%public -%class AwLexer -%implements FlexLexer -%function advance -%type IElementType - -%s HEADER -%s CLASS_NAME -%s MEMBER_NAME -%s TYPES - -%unicode - -HEADER_NAME=accessWidener -HEADER_VERSION_ELEMENT=v\d+ -HEADER_NAMESPACE_ELEMENT=named|intermediary -PRIMITIVE=[ZBCSIFDJV] -CLASS_VALUE=(\[+[ZBCSIFDJ]|(\[*L[^;\n]+;)) -ACCESS_ELEMENT=accessible|transitive-accessible|extendable|transitive-extendable|mutable|transitive-mutable -CLASS_ELEMENT=class -METHOD_ELEMENT=method -FIELD_ELEMENT=field -NAME_ELEMENT=\w+| -CLASS_NAME_ELEMENT=(\w+\/)*\w+(\$\w+)* -COMMENT=#.* -CRLF=\n|\r|\r\n -WHITE_SPACE=\s - -%% - - { - {HEADER_NAME} { yybegin(HEADER); return HEADER_NAME; } - {ACCESS_ELEMENT} { return ACCESS_ELEMENT; } - {CLASS_ELEMENT} { yybegin(CLASS_NAME); return CLASS_ELEMENT; } - {METHOD_ELEMENT} { yybegin(CLASS_NAME); return METHOD_ELEMENT; } - {FIELD_ELEMENT} { yybegin(CLASS_NAME); return FIELD_ELEMENT; } -} - -
{ - {HEADER_VERSION_ELEMENT} { return HEADER_VERSION_ELEMENT; } - {HEADER_NAMESPACE_ELEMENT} { return HEADER_NAMESPACE_ELEMENT; } -} - - { - {CLASS_NAME_ELEMENT} { yybegin(MEMBER_NAME); return CLASS_NAME_ELEMENT; } -} - - { - {NAME_ELEMENT} { yybegin(TYPES); return NAME_ELEMENT; } -} - - { - "(" { return OPEN_PAREN; } - ")" { return CLOSE_PAREN; } - {CLASS_VALUE} { return CLASS_VALUE; } - {PRIMITIVE} ({PRIMITIVE}|{CLASS_VALUE})* { zzMarkedPos = zzStartRead + 1; return PRIMITIVE; } -} - -{CRLF} { yybegin(YYINITIAL); return CRLF; } -{WHITE_SPACE} { return WHITE_SPACE; } - -{COMMENT} { return COMMENT; } -[^] { return BAD_CHARACTER; } Index: src/main/grammars/AwParser.bnf =================================================================== --- src/main/grammars/AwParser.bnf (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) +++ src/main/grammars/AwParser.bnf (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) @@ -1,112 +0,0 @@ -/* - * Minecraft Development for IntelliJ - * - * https://mcdev.io/ - * - * Copyright (C) 2025 minecraft-dev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, version 3.0 only. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -{ - parserClass="com.demonwav.mcdev.platform.mcp.aw.gen.parser.AwParser" - - extends="com.intellij.extapi.psi.ASTWrapperPsiElement" - - psiClassPrefix="Aw" - psiImplClassSuffix="Impl" - psiPackage="com.demonwav.mcdev.platform.mcp.aw.gen.psi" - psiImplPackage="com.demonwav.mcdev.platform.mcp.aw.gen.psi.impl" - - elementTypeHolderClass="com.demonwav.mcdev.platform.mcp.aw.gen.psi.AwTypes" - elementTypeClass="com.demonwav.mcdev.platform.mcp.aw.psi.AwElementType" - tokenTypeClass="com.demonwav.mcdev.platform.mcp.aw.psi.AwTokenType" - - consumeTokenMethod="consumeTokenFast" -} - -aw_file ::= header_line line* - -private header_line ::= !<> header COMMENT? end_line - -private line ::= !<> entry? COMMENT? end_line -private end_line ::= crlf | <> - -header ::= HEADER_NAME HEADER_VERSION_ELEMENT HEADER_NAMESPACE_ELEMENT { - mixin="com.demonwav.mcdev.platform.mcp.aw.psi.mixins.impl.AwHeaderImplMixin" - implements="com.demonwav.mcdev.platform.mcp.aw.psi.mixins.AwHeaderMixin" -} - -private entry ::= class_entry | method_entry | field_entry { - mixin="com.demonwav.mcdev.platform.mcp.aw.psi.mixins.impl.AwEntryImplMixin" - implements="com.demonwav.mcdev.platform.mcp.aw.psi.mixins.AwEntryMixin" - recoverWhile = line_recover -} - -class_entry ::= access class_literal class_name { - mixin="com.demonwav.mcdev.platform.mcp.aw.psi.mixins.impl.AwClassEntryImplMixin" - implements="com.demonwav.mcdev.platform.mcp.aw.psi.mixins.AwClassEntryMixin" -} - -method_entry ::= access method_literal class_name member_name method_desc{ - mixin="com.demonwav.mcdev.platform.mcp.aw.psi.mixins.impl.AwMethodEntryImplMixin" - implements="com.demonwav.mcdev.platform.mcp.aw.psi.mixins.AwMethodEntryMixin" -} - -field_entry ::= access field_literal class_name member_name field_desc{ - mixin="com.demonwav.mcdev.platform.mcp.aw.psi.mixins.impl.AwFieldEntryImplMixin" - implements="com.demonwav.mcdev.platform.mcp.aw.psi.mixins.AwFieldEntryMixin" -} - -private line_recover ::= !(end_line | COMMENT) - -access ::= ACCESS_ELEMENT { - methods=[ - accessElement="ACCESS_ELEMENT" - ] -} - -class_literal ::= CLASS_ELEMENT - -method_literal ::= METHOD_ELEMENT - -field_literal ::= FIELD_ELEMENT - -class_name ::= CLASS_NAME_ELEMENT { - mixin="com.demonwav.mcdev.platform.mcp.aw.psi.mixins.impl.AwClassNameImplMixin" - implements="com.demonwav.mcdev.platform.mcp.aw.psi.mixins.AwClassNameMixin" - methods=[ - classNameElement="CLASS_NAME_ELEMENT" - ] -} - -member_name ::= NAME_ELEMENT { - mixin= "com.demonwav.mcdev.platform.mcp.aw.psi.mixins.impl.AwMemberNameImplMixin" - implements="com.demonwav.mcdev.platform.mcp.aw.psi.mixins.AwMemberNameMixin" - methods=[ - nameElement="NAME_ELEMENT" - ] -} - -method_desc ::= OPEN_PAREN desc_element* CLOSE_PAREN desc_element - -field_desc ::= desc_element - -desc_element ::= PRIMITIVE | CLASS_VALUE { - mixin= "com.demonwav.mcdev.platform.mcp.aw.psi.mixins.impl.AwDescElementImplMixin" - implements= "com.demonwav.mcdev.platform.mcp.aw.psi.mixins.AwDescElementMixin" - methods=[ - primitive="PRIMITIVE" - classValue="CLASS_VALUE" - ] -} \ No newline at end of file Index: src/main/grammars/CtLexer.flex =================================================================== --- src/main/grammars/CtLexer.flex (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/grammars/CtLexer.flex (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,131 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mcp.ct.gen; + +import com.intellij.lexer.*; +import com.intellij.psi.tree.IElementType; +import static com.demonwav.mcdev.platform.mcp.ct.gen.psi.CtTypes.*; +import static com.intellij.psi.TokenType.*; + +%% + +%{ + public CtLexer() { + this((java.io.Reader)null); + } +%} + +%public +%class CtLexer +%implements FlexLexer +%function advance +%type IElementType + +%s HEADER +%s AW_ENTRY +%s AW_CLASS_NAME +%s AW_MEMBER_NAME +%s AW_TYPES +%s ITF_ENTRY_KEY +%s ITF_ENTRY_VALUE +%s SIGNATURE + +%unicode + +HEADER_NAME=accessWidener|classTweaker +HEADER_VERSION_ELEMENT=v\d+ +HEADER_NAMESPACE_ELEMENT=named|intermediary +PRIMITIVE=[ZBCSIFDJV] +CLASS_VALUE=L[^;\n]+; +SIGNATURE_CLASS_VALUE_START=L[^;<\n]+ +TYPE_VARIABLE=T[^;\n]+; +ACCESS_ELEMENT=accessible|transitive-accessible|extendable|transitive-extendable|mutable|transitive-mutable +INJECT_INTERFACE_ELEMENT=inject-interface|transitive-inject-interface +CLASS_ELEMENT=class +METHOD_ELEMENT=method +FIELD_ELEMENT=field +NAME_ELEMENT=\w+| +CLASS_NAME_ELEMENT=(\w+\/)*\w+(\$\w+)* +COMMENT=#.* +CRLF=\n|\r|\r\n +WHITE_SPACE=\s + +%% + + { + {HEADER_NAME} { yybegin(HEADER); return HEADER_NAME; } + {ACCESS_ELEMENT} { yybegin(AW_ENTRY); return ACCESS_ELEMENT; } + {INJECT_INTERFACE_ELEMENT} { yybegin(ITF_ENTRY_KEY); return INJECT_INTERFACE_ELEMENT; } +} + +
{ + {HEADER_VERSION_ELEMENT} { return HEADER_VERSION_ELEMENT; } + {HEADER_NAMESPACE_ELEMENT} { return HEADER_NAMESPACE_ELEMENT; } +} + + { + {CLASS_ELEMENT} { yybegin(AW_CLASS_NAME); return CLASS_ELEMENT; } + {METHOD_ELEMENT} { yybegin(AW_CLASS_NAME); return METHOD_ELEMENT; } + {FIELD_ELEMENT} { yybegin(AW_CLASS_NAME); return FIELD_ELEMENT; } +} + + { + {CLASS_NAME_ELEMENT} { yybegin(AW_MEMBER_NAME); return CLASS_NAME_ELEMENT; } +} + + { + {NAME_ELEMENT} { yybegin(AW_TYPES); return NAME_ELEMENT; } +} + + { + "(" { return OPEN_PAREN; } + ")" { return CLOSE_PAREN; } + "[" { return OPEN_BRACKET; } + {CLASS_VALUE} { return CLASS_VALUE; } + {PRIMITIVE} { return PRIMITIVE; } +} + + { + {CLASS_NAME_ELEMENT} { yybegin(ITF_ENTRY_VALUE); return CLASS_NAME_ELEMENT; } +} + + { + {CLASS_NAME_ELEMENT} { yybegin(SIGNATURE); return CLASS_NAME_ELEMENT; } +} + + { + "<" { return LESS_THAN; } + ">" { return GREATER_THAN; } + "[" { return OPEN_BRACKET; } + "+" { return PLUS; } + "-" { return MINUS; } + "*" { return ASTERISK; } + {SIGNATURE_CLASS_VALUE_START} { return SIGNATURE_CLASS_VALUE_START; } + ";" { return SIGNATURE_CLASS_VALUE_END; } + {PRIMITIVE} { return PRIMITIVE; } + {TYPE_VARIABLE} { return TYPE_VARIABLE; } +} + +{CRLF} { yybegin(YYINITIAL); return CRLF; } +{WHITE_SPACE} { return WHITE_SPACE; } + +{COMMENT} { return COMMENT; } +[^] { return BAD_CHARACTER; } Index: src/main/grammars/CtParser.bnf =================================================================== --- src/main/grammars/CtParser.bnf (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/grammars/CtParser.bnf (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,129 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +{ + parserClass="com.demonwav.mcdev.platform.mcp.ct.gen.parser.CtParser" + + extends="com.intellij.extapi.psi.ASTWrapperPsiElement" + + psiClassPrefix="Ct" + psiImplClassSuffix="Impl" + psiPackage="com.demonwav.mcdev.platform.mcp.ct.gen.psi" + psiImplPackage="com.demonwav.mcdev.platform.mcp.ct.gen.psi.impl" + + elementTypeHolderClass="com.demonwav.mcdev.platform.mcp.ct.gen.psi.CtTypes" + elementTypeClass="com.demonwav.mcdev.platform.mcp.ct.psi.CtElementType" + tokenTypeClass="com.demonwav.mcdev.platform.mcp.ct.psi.CtTokenType" +} + +aw_file ::= header_line line* + +private header_line ::= !<> header COMMENT? end_line + +private line ::= !<> entry? COMMENT? end_line +private end_line ::= crlf | <> + +header ::= HEADER_NAME HEADER_VERSION_ELEMENT HEADER_NAMESPACE_ELEMENT { + mixin="com.demonwav.mcdev.platform.mcp.ct.psi.mixins.impl.CtHeaderImplMixin" + implements="com.demonwav.mcdev.platform.mcp.ct.psi.mixins.CtHeaderMixin" + pin = 1 +} + +private entry ::= aw_entry | itf_entry { + mixin="com.demonwav.mcdev.platform.mcp.ct.psi.mixins.impl.CtEntryImplMixin" + implements="com.demonwav.mcdev.platform.mcp.ct.psi.mixins.impl.CtEntryMixin" + recoverWhile = line_recover +} + +private aw_entry ::= aw_class_entry | aw_method_entry | aw_field_entry { + mixin="com.demonwav.mcdev.platform.mcp.ct.psi.mixins.impl.CtAwEntryImplMixin" + implements="com.demonwav.mcdev.platform.mcp.ct.psi.mixins.CtAwEntryMixin" +} + +aw_class_entry ::= access class_literal class_name { + mixin="com.demonwav.mcdev.platform.mcp.ct.psi.mixins.impl.CtAwClassEntryImplMixin" + implements="com.demonwav.mcdev.platform.mcp.ct.psi.mixins.CtAwClassEntryMixin" + pin = 2 +} + +aw_method_entry ::= access method_literal class_name member_name method_desc { + mixin="com.demonwav.mcdev.platform.mcp.ct.psi.mixins.impl.CtAwMethodEntryImplMixin" + implements="com.demonwav.mcdev.platform.mcp.ct.psi.mixins.CtAwMethodEntryMixin" + pin = 2 +} + +aw_field_entry ::= access field_literal class_name member_name field_desc { + mixin="com.demonwav.mcdev.platform.mcp.ct.psi.mixins.impl.CtAwFieldEntryImplMixin" + implements="com.demonwav.mcdev.platform.mcp.ct.psi.mixins.CtAwFieldEntryMixin" + pin = 2 +} + +itf_entry ::= INJECT_INTERFACE_ELEMENT class_name signature { + mixin="com.demonwav.mcdev.platform.mcp.ct.psi.mixins.impl.CtItfEntryImplMixin" + implements="com.demonwav.mcdev.platform.mcp.ct.psi.mixins.CtItfEntryMixin" + pin = 1 +} + +private line_recover ::= !(end_line | COMMENT) + +access ::= ACCESS_ELEMENT { + methods=[ + accessElement="ACCESS_ELEMENT" + ] +} + +class_literal ::= CLASS_ELEMENT + +method_literal ::= METHOD_ELEMENT + +field_literal ::= FIELD_ELEMENT + +class_name ::= CLASS_NAME_ELEMENT { + mixin="com.demonwav.mcdev.platform.mcp.ct.psi.mixins.impl.CtAwClassNameImplMixin" + implements="com.demonwav.mcdev.platform.mcp.ct.psi.mixins.CtAwClassNameMixin" + methods=[ + classNameElement="CLASS_NAME_ELEMENT" + ] +} + +member_name ::= NAME_ELEMENT { + mixin= "com.demonwav.mcdev.platform.mcp.ct.psi.mixins.impl.CtAwMemberNameImplMixin" + implements="com.demonwav.mcdev.platform.mcp.ct.psi.mixins.CtAwMemberNameMixin" + methods=[ + nameElement="NAME_ELEMENT" + ] +} + +method_desc ::= OPEN_PAREN desc_element* CLOSE_PAREN desc_element + +field_desc ::= desc_element + +desc_element ::= OPEN_BRACKET* (PRIMITIVE | CLASS_VALUE) { + mixin= "com.demonwav.mcdev.platform.mcp.ct.psi.mixins.impl.CtAwDescElementImplMixin" + implements= "com.demonwav.mcdev.platform.mcp.ct.psi.mixins.CtAwDescElementMixin" + methods=[ + primitive="PRIMITIVE" + classValue="CLASS_VALUE" + ] +} + +signature ::= CLASS_NAME_ELEMENT (LESS_THAN signature_element+ GREATER_THAN)? +signature_element ::= OPEN_BRACKET* (PRIMITIVE | TYPE_VARIABLE | signature_class_element) +signature_class_element ::= ASTERISK | ( (PLUS | MINUS)? SIGNATURE_CLASS_VALUE_START (LESS_THAN signature_element GREATER_THAN)? SIGNATURE_CLASS_VALUE_END ) Index: src/main/kotlin/platform/fabric/reference/FabricReferenceContributor.kt =================================================================== --- src/main/kotlin/platform/fabric/reference/FabricReferenceContributor.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) +++ src/main/kotlin/platform/fabric/reference/FabricReferenceContributor.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -58,7 +58,7 @@ registrar.registerReferenceProvider( stringInModJson.isPropertyValue("accessWidener"), - ResourceFileReference("access widener '%s'", Regex("(.+)\\.(accesswidener|aw)")), + ResourceFileReference("class tweaker '%s'", Regex("(.+)\\.(accesswidener|aw|classtweaker|ct)")), ) registrar.registerReferenceProvider( Index: src/main/kotlin/platform/mcp/aw/AwAnnotator.kt =================================================================== --- src/main/kotlin/platform/mcp/aw/AwAnnotator.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) +++ src/main/kotlin/platform/mcp/aw/AwAnnotator.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) @@ -1,77 +0,0 @@ -/* - * Minecraft Development for IntelliJ - * - * https://mcdev.io/ - * - * Copyright (C) 2025 minecraft-dev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, version 3.0 only. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.demonwav.mcdev.platform.mcp.aw - -import com.demonwav.mcdev.platform.mcp.aw.gen.psi.AwAccess -import com.demonwav.mcdev.platform.mcp.aw.gen.psi.AwClassLiteral -import com.demonwav.mcdev.platform.mcp.aw.gen.psi.AwFieldLiteral -import com.demonwav.mcdev.platform.mcp.aw.gen.psi.AwHeader -import com.demonwav.mcdev.platform.mcp.aw.gen.psi.AwMethodLiteral -import com.demonwav.mcdev.util.childOfType -import com.google.common.collect.HashMultimap -import com.google.common.collect.Multimaps -import com.intellij.lang.annotation.AnnotationHolder -import com.intellij.lang.annotation.Annotator -import com.intellij.lang.annotation.HighlightSeverity -import com.intellij.psi.PsiElement -import com.intellij.psi.PsiWhiteSpace -import com.intellij.psi.util.PsiTreeUtil - -class AwAnnotator : Annotator { - - override fun annotate(element: PsiElement, holder: AnnotationHolder) { - if (element is AwAccess) { - val access = element.text - val target = PsiTreeUtil.skipSiblingsForward(element, PsiWhiteSpace::class.java)?.text - if (!compatibleByAccessMap.get(access).contains(target)) { - holder.newAnnotation(HighlightSeverity.ERROR, "Access '$access' cannot be used on '$target'").create() - } - - if (element.accessElement.text.startsWith("transitive-") && - element.containingFile?.childOfType()?.versionString == "v1" - ) { - holder.newAnnotation(HighlightSeverity.ERROR, "Transitive accesses were introduced in v2").create() - } - } else if (element is AwFieldLiteral || element is AwMethodLiteral || element is AwClassLiteral) { - val target = element.text - val access = PsiTreeUtil.skipSiblingsBackward(element, PsiWhiteSpace::class.java)?.text - if (!compatibleByTargetMap.get(target).contains(access)) { - holder.newAnnotation(HighlightSeverity.ERROR, "'$target' cannot be used with '$access'").create() - } - } - } - - companion object { - - val compatibleByAccessMap = HashMultimap.create() - val compatibleByTargetMap = HashMultimap.create() - - init { - compatibleByAccessMap.putAll("accessible", setOf("class", "method", "field")) - compatibleByAccessMap.putAll("transitive-accessible", setOf("class", "method", "field")) - compatibleByAccessMap.putAll("extendable", setOf("class", "method")) - compatibleByAccessMap.putAll("transitive-extendable", setOf("class", "method")) - compatibleByAccessMap.putAll("mutable", setOf("field")) - compatibleByAccessMap.putAll("transitive-mutable", setOf("field")) - Multimaps.invertFrom(compatibleByAccessMap, compatibleByTargetMap) - } - } -} Index: src/main/kotlin/platform/mcp/aw/AwColorSettingsPage.kt =================================================================== --- src/main/kotlin/platform/mcp/aw/AwColorSettingsPage.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) +++ src/main/kotlin/platform/mcp/aw/AwColorSettingsPage.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) @@ -1,68 +0,0 @@ -/* - * Minecraft Development for IntelliJ - * - * https://mcdev.io/ - * - * Copyright (C) 2025 minecraft-dev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, version 3.0 only. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.demonwav.mcdev.platform.mcp.aw - -import com.demonwav.mcdev.asset.PlatformAssets -import com.intellij.openapi.editor.colors.TextAttributesKey -import com.intellij.openapi.options.colors.AttributesDescriptor -import com.intellij.openapi.options.colors.ColorDescriptor -import com.intellij.openapi.options.colors.ColorSettingsPage - -class AwColorSettingsPage : ColorSettingsPage { - - override fun getIcon() = PlatformAssets.MCP_ICON - override fun getHighlighter() = AwSyntaxHighlighter() - override fun getDemoText() = - """ - accessWidener v1 named - - # https://www.fabricmc.net/wiki/tutorial:accesswideners - - extendable class net/minecraft/world/item/crafting/Ingredient - transitive-extendable class net/minecraft/world/item/crafting/Ingredient - accessible class net/minecraft/world/entity/monster/Phantom${'$'}AttackPhase - transitive-accessible class net/minecraft/world/entity/monster/Phantom${'$'}AttackPhase - extendable method net/minecraft/server/players/IpBanList getIpFromAddress (Ljava/net/SocketAddress;)Ljava/lang/String; - extendable method net/minecraft/world/item/crafting/Ingredient (Ljava/util/stream/Stream;)V - accessible field net/minecraft/world/item/crafting/Ingredient values [Lnet/minecraft/world/item/crafting/Ingredient${'$'}Value; - """.trimIndent() - - override fun getAdditionalHighlightingTagToDescriptorMap(): Map? = null - override fun getAttributeDescriptors() = DESCRIPTORS - override fun getColorDescriptors(): Array = ColorDescriptor.EMPTY_ARRAY - override fun getDisplayName() = "Access Wideners" - - companion object { - private val DESCRIPTORS = arrayOf( - AttributesDescriptor("Header Name", AwSyntaxHighlighter.HEADER_NAME), - AttributesDescriptor("Header Namespace", AwSyntaxHighlighter.HEADER_NAMESPACE), - AttributesDescriptor("Access", AwSyntaxHighlighter.ACCESS), - AttributesDescriptor("Class Element", AwSyntaxHighlighter.CLASS_ELEMENT), - AttributesDescriptor("Method Element", AwSyntaxHighlighter.METHOD_ELEMENT), - AttributesDescriptor("Field Element", AwSyntaxHighlighter.FIELD_ELEMENT), - AttributesDescriptor("Class Name", AwSyntaxHighlighter.CLASS_NAME), - AttributesDescriptor("Member Name", AwSyntaxHighlighter.MEMBER_NAME), - AttributesDescriptor("Class Value", AwSyntaxHighlighter.CLASS_VALUE), - AttributesDescriptor("Primitive", AwSyntaxHighlighter.PRIMITIVE), - AttributesDescriptor("Comment", AwSyntaxHighlighter.COMMENT), - ) - } -} Index: src/main/kotlin/platform/mcp/aw/AwCommenter.kt =================================================================== --- src/main/kotlin/platform/mcp/aw/AwCommenter.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) +++ src/main/kotlin/platform/mcp/aw/AwCommenter.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) @@ -1,36 +0,0 @@ -/* - * Minecraft Development for IntelliJ - * - * https://mcdev.io/ - * - * Copyright (C) 2025 minecraft-dev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, version 3.0 only. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.demonwav.mcdev.platform.mcp.aw - -import com.intellij.lang.Commenter - -class AwCommenter : Commenter { - - override fun getLineCommentPrefix() = "#" - - override fun getBlockCommentPrefix(): String? = null - - override fun getBlockCommentSuffix(): String? = null - - override fun getCommentedBlockCommentPrefix(): String? = null - - override fun getCommentedBlockCommentSuffix(): String? = null -} Index: src/main/kotlin/platform/mcp/aw/AwCompletionContributor.kt =================================================================== --- src/main/kotlin/platform/mcp/aw/AwCompletionContributor.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) +++ src/main/kotlin/platform/mcp/aw/AwCompletionContributor.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) @@ -1,123 +0,0 @@ -/* - * Minecraft Development for IntelliJ - * - * https://mcdev.io/ - * - * Copyright (C) 2025 minecraft-dev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, version 3.0 only. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.demonwav.mcdev.platform.mcp.aw - -import com.demonwav.mcdev.platform.mcp.aw.gen.psi.AwTypes -import com.intellij.codeInsight.completion.CodeCompletionHandlerBase -import com.intellij.codeInsight.completion.CompletionContributor -import com.intellij.codeInsight.completion.CompletionParameters -import com.intellij.codeInsight.completion.CompletionProvider -import com.intellij.codeInsight.completion.CompletionResultSet -import com.intellij.codeInsight.completion.CompletionType -import com.intellij.codeInsight.completion.InsertionContext -import com.intellij.codeInsight.lookup.LookupElementBuilder -import com.intellij.openapi.application.runReadAction -import com.intellij.patterns.PlatformPatterns -import com.intellij.psi.PsiDocumentManager -import com.intellij.psi.TokenType -import com.intellij.psi.util.elementType -import com.intellij.psi.util.prevLeaf -import com.intellij.util.ProcessingContext - -class AwCompletionContributor : CompletionContributor() { - init { - extend(null, PlatformPatterns.psiElement(), AwHeaderCompletionProvider) - val whitespace = PlatformPatterns.psiElement(TokenType.WHITE_SPACE) - val namespacePattern = PlatformPatterns.psiElement() - .afterLeafSkipping(whitespace, PlatformPatterns.psiElement(AwTypes.HEADER_VERSION_ELEMENT)) - extend(null, namespacePattern, AwNamespaceCompletionProvider) - val accessPattern = PlatformPatterns.psiElement().afterLeaf(PlatformPatterns.psiElement(AwTypes.CRLF)) - extend(null, accessPattern, AwAccessCompletionProvider) - val targetPattern = PlatformPatterns.psiElement() - .afterLeafSkipping(whitespace, PlatformPatterns.psiElement(AwTypes.ACCESS_ELEMENT)) - extend(null, targetPattern, AwTargetCompletionProvider) - } -} - -private fun insertWhitespace(context: InsertionContext) { - PsiDocumentManager.getInstance(context.project) - .doPostponedOperationsAndUnblockDocument(context.document) - context.document.insertString(context.editor.caretModel.offset, " ") - context.editor.caretModel.moveCaretRelatively(1, 0, false, false, false) - context.setLaterRunnable { - runReadAction { - CodeCompletionHandlerBase.createHandler(CompletionType.BASIC) - .invokeCompletion(context.project, context.editor) - } - } -} - -object AwHeaderCompletionProvider : CompletionProvider() { - - override fun addCompletions( - parameters: CompletionParameters, - context: ProcessingContext, - result: CompletionResultSet, - ) { - if (parameters.position.prevLeaf(true) == null) { - result.addElement(LookupElementBuilder.create("accessWidener v1 named")) - result.addElement(LookupElementBuilder.create("accessWidener v2 named")) - } - } -} - -object AwNamespaceCompletionProvider : CompletionProvider() { - - override fun addCompletions( - parameters: CompletionParameters, - context: ProcessingContext, - result: CompletionResultSet, - ) = result.addAllElements(listOf("named", "intermediary").map(LookupElementBuilder::create)) -} - -object AwAccessCompletionProvider : CompletionProvider() { - - override fun addCompletions( - parameters: CompletionParameters, - context: ProcessingContext, - result: CompletionResultSet, - ) { - val elements = listOf( - "accessible", - "transitive-accessible", - "extendable", - "transitive-extendable", - "mutable", - "transitive-mutable", - ).map { LookupElementBuilder.create(it).withInsertHandler { ctx, _ -> insertWhitespace(ctx) } } - result.addAllElements(elements) - } -} - -object AwTargetCompletionProvider : CompletionProvider() { - - override fun addCompletions( - parameters: CompletionParameters, - context: ProcessingContext, - result: CompletionResultSet, - ) { - val text = parameters.position - .prevLeaf { it.elementType == AwTypes.ACCESS_ELEMENT || it.elementType == AwTypes.CRLF }?.text - val elements = AwAnnotator.compatibleByAccessMap.get(text) - .map { LookupElementBuilder.create(it).withInsertHandler { ctx, _ -> insertWhitespace(ctx) } } - result.addAllElements(elements) - } -} Index: src/main/kotlin/platform/mcp/aw/AwFile.kt =================================================================== --- src/main/kotlin/platform/mcp/aw/AwFile.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) +++ src/main/kotlin/platform/mcp/aw/AwFile.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) @@ -1,41 +0,0 @@ -/* - * Minecraft Development for IntelliJ - * - * https://mcdev.io/ - * - * Copyright (C) 2025 minecraft-dev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, version 3.0 only. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.demonwav.mcdev.platform.mcp.aw - -import com.demonwav.mcdev.asset.PlatformAssets -import com.demonwav.mcdev.platform.mcp.aw.gen.psi.AwHeader -import com.demonwav.mcdev.platform.mcp.aw.psi.mixins.AwEntryMixin -import com.demonwav.mcdev.util.childrenOfType -import com.intellij.extapi.psi.PsiFileBase -import com.intellij.psi.FileViewProvider - -class AwFile(viewProvider: FileViewProvider) : PsiFileBase(viewProvider, AwLanguage) { - - val header: AwHeader? - get() = children.first { it is AwHeader } as? AwHeader - - val entries: Collection - get() = childrenOfType() - - override fun getFileType() = AwFileType - override fun toString() = "Access Widener File" - override fun getIcon(flags: Int) = PlatformAssets.MCP_ICON -} Index: src/main/kotlin/platform/mcp/aw/AwFileType.kt =================================================================== --- src/main/kotlin/platform/mcp/aw/AwFileType.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) +++ src/main/kotlin/platform/mcp/aw/AwFileType.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) @@ -1,35 +0,0 @@ -/* - * Minecraft Development for IntelliJ - * - * https://mcdev.io/ - * - * Copyright (C) 2025 minecraft-dev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, version 3.0 only. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.demonwav.mcdev.platform.mcp.aw - -import com.demonwav.mcdev.asset.PlatformAssets -import com.intellij.openapi.fileTypes.LanguageFileType - -object AwFileType : LanguageFileType(AwLanguage) { - - override fun getName() = "Access Widener" - - override fun getDescription() = "Access widener" - - override fun getDefaultExtension() = "accesswidener" - - override fun getIcon() = PlatformAssets.MCP_ICON -} Index: src/main/kotlin/platform/mcp/aw/AwLanguage.kt =================================================================== --- src/main/kotlin/platform/mcp/aw/AwLanguage.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) +++ src/main/kotlin/platform/mcp/aw/AwLanguage.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) @@ -1,25 +0,0 @@ -/* - * Minecraft Development for IntelliJ - * - * https://mcdev.io/ - * - * Copyright (C) 2025 minecraft-dev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, version 3.0 only. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.demonwav.mcdev.platform.mcp.aw - -import com.intellij.lang.Language - -object AwLanguage : Language("Access Widener") Index: src/main/kotlin/platform/mcp/aw/AwLexerAdapter.kt =================================================================== --- src/main/kotlin/platform/mcp/aw/AwLexerAdapter.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) +++ src/main/kotlin/platform/mcp/aw/AwLexerAdapter.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) @@ -1,26 +0,0 @@ -/* - * Minecraft Development for IntelliJ - * - * https://mcdev.io/ - * - * Copyright (C) 2025 minecraft-dev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, version 3.0 only. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.demonwav.mcdev.platform.mcp.aw - -import com.demonwav.mcdev.platform.mcp.aw.gen.AwLexer -import com.intellij.lexer.FlexAdapter - -class AwLexerAdapter : FlexAdapter(AwLexer()) Index: src/main/kotlin/platform/mcp/aw/AwParserDefinition.kt =================================================================== --- src/main/kotlin/platform/mcp/aw/AwParserDefinition.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) +++ src/main/kotlin/platform/mcp/aw/AwParserDefinition.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) @@ -1,60 +0,0 @@ -/* - * Minecraft Development for IntelliJ - * - * https://mcdev.io/ - * - * Copyright (C) 2025 minecraft-dev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, version 3.0 only. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.demonwav.mcdev.platform.mcp.aw - -import com.demonwav.mcdev.platform.mcp.aw.gen.parser.AwParser -import com.demonwav.mcdev.platform.mcp.aw.gen.psi.AwTypes -import com.intellij.lang.ASTNode -import com.intellij.lang.Language -import com.intellij.lang.LanguageUtil -import com.intellij.lang.ParserDefinition -import com.intellij.lang.PsiParser -import com.intellij.lexer.Lexer -import com.intellij.openapi.project.Project -import com.intellij.psi.FileViewProvider -import com.intellij.psi.PsiElement -import com.intellij.psi.PsiFile -import com.intellij.psi.TokenType -import com.intellij.psi.tree.IFileElementType -import com.intellij.psi.tree.TokenSet - -class AwParserDefinition : ParserDefinition { - - override fun createLexer(project: Project): Lexer = AwLexerAdapter() - override fun createParser(project: Project): PsiParser = AwParser() - override fun getFileNodeType(): IFileElementType = FILE - override fun getWhitespaceTokens(): TokenSet = WHITE_SPACES - override fun getCommentTokens(): TokenSet = COMMENTS - override fun getStringLiteralElements(): TokenSet = TokenSet.EMPTY - override fun createElement(node: ASTNode): PsiElement = AwTypes.Factory.createElement(node) - override fun createFile(viewProvider: FileViewProvider): PsiFile = AwFile(viewProvider) - - override fun spaceExistenceTypeBetweenTokens(left: ASTNode, right: ASTNode): ParserDefinition.SpaceRequirements { - return LanguageUtil.canStickTokensTogetherByLexer(left, right, AwLexerAdapter()) - } - - companion object { - private val WHITE_SPACES = TokenSet.create(TokenType.WHITE_SPACE) - private val COMMENTS = TokenSet.create(AwTypes.COMMENT) - - private val FILE = IFileElementType(Language.findInstance(AwLanguage::class.java)) - } -} Index: src/main/kotlin/platform/mcp/aw/AwSyntaxHighlighter.kt =================================================================== --- src/main/kotlin/platform/mcp/aw/AwSyntaxHighlighter.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) +++ src/main/kotlin/platform/mcp/aw/AwSyntaxHighlighter.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) @@ -1,92 +0,0 @@ -/* - * Minecraft Development for IntelliJ - * - * https://mcdev.io/ - * - * Copyright (C) 2025 minecraft-dev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, version 3.0 only. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.demonwav.mcdev.platform.mcp.aw - -import com.demonwav.mcdev.platform.mcp.aw.gen.psi.AwTypes -import com.intellij.openapi.editor.DefaultLanguageHighlighterColors -import com.intellij.openapi.editor.HighlighterColors -import com.intellij.openapi.editor.colors.TextAttributesKey -import com.intellij.openapi.fileTypes.SyntaxHighlighterBase -import com.intellij.psi.TokenType -import com.intellij.psi.tree.IElementType - -class AwSyntaxHighlighter : SyntaxHighlighterBase() { - - override fun getHighlightingLexer() = AwLexerAdapter() - - override fun getTokenHighlights(tokenType: IElementType) = - when (tokenType) { - AwTypes.HEADER_NAME -> HEADER_NAME_KEYS - AwTypes.HEADER_NAMESPACE_ELEMENT -> HEADER_NAMESPACE_KEYS - AwTypes.ACCESS_ELEMENT -> ACCESS_KEYS - AwTypes.CLASS_ELEMENT -> CLASS_ELEMENT_KEYS - AwTypes.METHOD_ELEMENT -> METHOD_ELEMENT_KEYS - AwTypes.FIELD_ELEMENT -> FIELD_ELEMENT_KEYS - AwTypes.CLASS_NAME_ELEMENT -> CLASS_NAME_KEYS - AwTypes.NAME_ELEMENT -> MEMBER_NAME_KEYS - AwTypes.CLASS_VALUE -> CLASS_VALUE_KEYS - AwTypes.PRIMITIVE -> PRIMITIVE_KEYS - AwTypes.COMMENT -> COMMENT_KEYS - TokenType.BAD_CHARACTER -> BAD_CHARACTER_KEYS - else -> EMPTY_KEYS - } - - companion object { - val HEADER_NAME = - TextAttributesKey.createTextAttributesKey("AW_HEADER_NAME", DefaultLanguageHighlighterColors.KEYWORD) - val HEADER_NAMESPACE = - TextAttributesKey.createTextAttributesKey("AW_HEADER_NAMESPACE", DefaultLanguageHighlighterColors.KEYWORD) - val ACCESS = - TextAttributesKey.createTextAttributesKey("AW_ACCESS", DefaultLanguageHighlighterColors.KEYWORD) - val CLASS_ELEMENT = - TextAttributesKey.createTextAttributesKey("AW_CLASS_ELEMENT", DefaultLanguageHighlighterColors.KEYWORD) - val METHOD_ELEMENT = - TextAttributesKey.createTextAttributesKey("AW_METHOD_ELEMENT", DefaultLanguageHighlighterColors.KEYWORD) - val FIELD_ELEMENT = - TextAttributesKey.createTextAttributesKey("AW_FIELD_ELEMENT", DefaultLanguageHighlighterColors.KEYWORD) - val CLASS_NAME = - TextAttributesKey.createTextAttributesKey("AW_CLASS_NAME", DefaultLanguageHighlighterColors.STRING) - val MEMBER_NAME = - TextAttributesKey.createTextAttributesKey("AW_MEMBER_NAME", DefaultLanguageHighlighterColors.STATIC_FIELD) - val CLASS_VALUE = - TextAttributesKey.createTextAttributesKey("AW_CLASS_VALUE", DefaultLanguageHighlighterColors.STATIC_METHOD) - val PRIMITIVE = - TextAttributesKey.createTextAttributesKey("AW_PRIMITIVE", DefaultLanguageHighlighterColors.NUMBER) - val COMMENT = - TextAttributesKey.createTextAttributesKey("AW_COMMENT", DefaultLanguageHighlighterColors.LINE_COMMENT) - val BAD_CHARACTER = - TextAttributesKey.createTextAttributesKey("AW_BAD_CHARACTER", HighlighterColors.BAD_CHARACTER) - - private val HEADER_NAME_KEYS = arrayOf(HEADER_NAME) - private val HEADER_NAMESPACE_KEYS = arrayOf(HEADER_NAMESPACE) - private val ACCESS_KEYS = arrayOf(ACCESS) - private val CLASS_ELEMENT_KEYS = arrayOf(CLASS_ELEMENT) - private val METHOD_ELEMENT_KEYS = arrayOf(METHOD_ELEMENT) - private val FIELD_ELEMENT_KEYS = arrayOf(FIELD_ELEMENT) - private val CLASS_NAME_KEYS = arrayOf(CLASS_NAME) - private val MEMBER_NAME_KEYS = arrayOf(MEMBER_NAME) - private val CLASS_VALUE_KEYS = arrayOf(CLASS_VALUE) - private val PRIMITIVE_KEYS = arrayOf(PRIMITIVE) - private val COMMENT_KEYS = arrayOf(COMMENT) - private val BAD_CHARACTER_KEYS = arrayOf(BAD_CHARACTER) - private val EMPTY_KEYS = emptyArray() - } -} Index: src/main/kotlin/platform/mcp/aw/AwSyntaxHighlighterFactory.kt =================================================================== --- src/main/kotlin/platform/mcp/aw/AwSyntaxHighlighterFactory.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) +++ src/main/kotlin/platform/mcp/aw/AwSyntaxHighlighterFactory.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) @@ -1,29 +0,0 @@ -/* - * Minecraft Development for IntelliJ - * - * https://mcdev.io/ - * - * Copyright (C) 2025 minecraft-dev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, version 3.0 only. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.demonwav.mcdev.platform.mcp.aw - -import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory -import com.intellij.openapi.project.Project -import com.intellij.openapi.vfs.VirtualFile - -class AwSyntaxHighlighterFactory : SyntaxHighlighterFactory() { - override fun getSyntaxHighlighter(project: Project?, virtualFile: VirtualFile?) = AwSyntaxHighlighter() -} Index: src/main/kotlin/platform/mcp/aw/fixes/CopyAwAccessibleEntryFix.kt =================================================================== --- src/main/kotlin/platform/mcp/aw/fixes/CopyAwAccessibleEntryFix.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) +++ src/main/kotlin/platform/mcp/aw/fixes/CopyAwAccessibleEntryFix.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) @@ -1,69 +0,0 @@ -/* - * Minecraft Development for IntelliJ - * - * https://mcdev.io/ - * - * Copyright (C) 2025 minecraft-dev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, version 3.0 only. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.demonwav.mcdev.platform.mcp.aw.fixes - -import com.demonwav.mcdev.facet.MinecraftFacet -import com.demonwav.mcdev.platform.fabric.FabricModuleType -import com.demonwav.mcdev.platform.mcp.actions.CopyAwAction -import com.demonwav.mcdev.platform.sponge.SpongeModuleType -import com.demonwav.mcdev.util.findModule -import com.intellij.codeInsight.daemon.QuickFixActionRegistrar -import com.intellij.codeInsight.intention.IntentionAction -import com.intellij.codeInsight.quickfix.UnresolvedReferenceQuickFixProvider -import com.intellij.openapi.editor.Editor -import com.intellij.openapi.project.Project -import com.intellij.psi.PsiElement -import com.intellij.psi.PsiFile -import com.intellij.psi.PsiJavaCodeReferenceElement - -class CopyAwAccessibleEntryFix(val target: PsiElement, val element: PsiElement) : IntentionAction { - - class Provider : UnresolvedReferenceQuickFixProvider() { - - override fun registerFixes(ref: PsiJavaCodeReferenceElement, registrar: QuickFixActionRegistrar) { - val module = ref.findModule() ?: return - val isApplicable = MinecraftFacet.getInstance(module, FabricModuleType, SpongeModuleType) != null - if (!isApplicable) { - return - } - - val resolve = ref.advancedResolve(true) - val target = resolve.element - if (target != null && !resolve.isAccessible) { - registrar.register(CopyAwAccessibleEntryFix(target, ref)) - } - } - - override fun getReferenceClass(): Class = PsiJavaCodeReferenceElement::class.java - } - - override fun startInWriteAction(): Boolean = false - - override fun getText(): String = "Copy AW entry" - - override fun getFamilyName(): String = "Copy AW entry for inaccessible element" - - override fun isAvailable(project: Project, editor: Editor?, file: PsiFile?): Boolean = true - - override fun invoke(project: Project, editor: Editor?, file: PsiFile?) { - CopyAwAction.doCopy(target, element, editor, null) - } -} Index: src/main/kotlin/platform/mcp/aw/inspections/DuplicateAwEntryInspection.kt =================================================================== --- src/main/kotlin/platform/mcp/aw/inspections/DuplicateAwEntryInspection.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) +++ src/main/kotlin/platform/mcp/aw/inspections/DuplicateAwEntryInspection.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) @@ -1,81 +0,0 @@ -/* - * Minecraft Development for IntelliJ - * - * https://mcdev.io/ - * - * Copyright (C) 2025 minecraft-dev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, version 3.0 only. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.demonwav.mcdev.platform.mcp.aw.inspections - -import com.demonwav.mcdev.platform.mcp.aw.AwFile -import com.demonwav.mcdev.platform.mcp.aw.psi.mixins.AwEntryMixin -import com.demonwav.mcdev.platform.mcp.aw.psi.mixins.AwMemberNameMixin -import com.demonwav.mcdev.util.childOfType -import com.intellij.codeInspection.InspectionManager -import com.intellij.codeInspection.LocalInspectionTool -import com.intellij.codeInspection.ProblemDescriptor -import com.intellij.codeInspection.ProblemHighlightType -import com.intellij.psi.PsiElement -import com.intellij.psi.PsiFile -import com.intellij.psi.PsiNamedElement -import com.jetbrains.rd.util.getOrCreate -import org.jetbrains.plugins.groovy.codeInspection.fixes.RemoveElementQuickFix - -class DuplicateAwEntryInspection : LocalInspectionTool() { - - override fun checkFile(file: PsiFile, manager: InspectionManager, isOnTheFly: Boolean): Array? { - if (file !is AwFile) { - return null - } - val collected = HashMap, MutableList>() - file.entries.forEach { - val target = it.childOfType()?.resolve() - val accessKind = it.accessKind - if (target != null && accessKind != null) { - (collected.getOrCreate(Pair(target, accessKind)) { ArrayList() }) += it - } - } - val problems = ArrayList() - collected.forEach { (sort, matches) -> - if (sort.first is PsiNamedElement) { - if (matches.size > 1) { - for (match in matches) - problems += manager.createProblemDescriptor( - match, - "Duplicate entry for \"${sort.second} ${(sort.first as PsiNamedElement).name}\"", - RemoveElementQuickFix("Remove duplicate"), - ProblemHighlightType.WARNING, - isOnTheFly, - ) - } - } - } - return problems.toTypedArray() - } - - override fun runForWholeFile(): Boolean { - return true - } - - override fun getDisplayName(): String { - return "Duplicate AW entry" - } - - override fun getStaticDescription(): String { - return "Warns when the same element has its accessibility, mutability, " + - "or extensibility changed multiple times in one file." - } -} Index: src/main/kotlin/platform/mcp/aw/psi/AwElement.kt =================================================================== --- src/main/kotlin/platform/mcp/aw/psi/AwElement.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) +++ src/main/kotlin/platform/mcp/aw/psi/AwElement.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) @@ -1,25 +0,0 @@ -/* - * Minecraft Development for IntelliJ - * - * https://mcdev.io/ - * - * Copyright (C) 2025 minecraft-dev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, version 3.0 only. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.demonwav.mcdev.platform.mcp.aw.psi - -import com.intellij.psi.PsiElement - -interface AwElement : PsiElement Index: src/main/kotlin/platform/mcp/aw/psi/AwElementType.kt =================================================================== --- src/main/kotlin/platform/mcp/aw/psi/AwElementType.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) +++ src/main/kotlin/platform/mcp/aw/psi/AwElementType.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) @@ -1,27 +0,0 @@ -/* - * Minecraft Development for IntelliJ - * - * https://mcdev.io/ - * - * Copyright (C) 2025 minecraft-dev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, version 3.0 only. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.demonwav.mcdev.platform.mcp.aw.psi - -import com.demonwav.mcdev.platform.mcp.aw.AwLanguage -import com.intellij.psi.tree.IElementType -import org.jetbrains.annotations.NonNls - -class AwElementType(@NonNls debugName: String) : IElementType(debugName, AwLanguage) Index: src/main/kotlin/platform/mcp/aw/psi/AwTokenType.kt =================================================================== --- src/main/kotlin/platform/mcp/aw/psi/AwTokenType.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) +++ src/main/kotlin/platform/mcp/aw/psi/AwTokenType.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) @@ -1,27 +0,0 @@ -/* - * Minecraft Development for IntelliJ - * - * https://mcdev.io/ - * - * Copyright (C) 2025 minecraft-dev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, version 3.0 only. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.demonwav.mcdev.platform.mcp.aw.psi - -import com.demonwav.mcdev.platform.mcp.aw.AwLanguage -import com.intellij.psi.tree.IElementType -import org.jetbrains.annotations.NonNls - -class AwTokenType(@NonNls debugName: String) : IElementType(debugName, AwLanguage) Index: src/main/kotlin/platform/mcp/aw/psi/mixins/AwClassEntryMixin.kt =================================================================== --- src/main/kotlin/platform/mcp/aw/psi/mixins/AwClassEntryMixin.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) +++ src/main/kotlin/platform/mcp/aw/psi/mixins/AwClassEntryMixin.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) @@ -1,23 +0,0 @@ -/* - * Minecraft Development for IntelliJ - * - * https://mcdev.io/ - * - * Copyright (C) 2025 minecraft-dev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, version 3.0 only. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.demonwav.mcdev.platform.mcp.aw.psi.mixins - -interface AwClassEntryMixin : AwEntryMixin Index: src/main/kotlin/platform/mcp/aw/psi/mixins/AwClassNameMixin.kt =================================================================== --- src/main/kotlin/platform/mcp/aw/psi/mixins/AwClassNameMixin.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) +++ src/main/kotlin/platform/mcp/aw/psi/mixins/AwClassNameMixin.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) @@ -1,26 +0,0 @@ -/* - * Minecraft Development for IntelliJ - * - * https://mcdev.io/ - * - * Copyright (C) 2025 minecraft-dev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, version 3.0 only. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.demonwav.mcdev.platform.mcp.aw.psi.mixins - -import com.demonwav.mcdev.platform.mcp.aw.psi.AwElement -import com.intellij.psi.PsiReference - -interface AwClassNameMixin : AwElement, PsiReference Index: src/main/kotlin/platform/mcp/aw/psi/mixins/AwDescElementMixin.kt =================================================================== --- src/main/kotlin/platform/mcp/aw/psi/mixins/AwDescElementMixin.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) +++ src/main/kotlin/platform/mcp/aw/psi/mixins/AwDescElementMixin.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) @@ -1,26 +0,0 @@ -/* - * Minecraft Development for IntelliJ - * - * https://mcdev.io/ - * - * Copyright (C) 2025 minecraft-dev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, version 3.0 only. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.demonwav.mcdev.platform.mcp.aw.psi.mixins - -import com.demonwav.mcdev.platform.mcp.aw.psi.AwElement -import com.intellij.psi.PsiReference - -interface AwDescElementMixin : AwElement, PsiReference Index: src/main/kotlin/platform/mcp/aw/psi/mixins/AwEntryMixin.kt =================================================================== --- src/main/kotlin/platform/mcp/aw/psi/mixins/AwEntryMixin.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) +++ src/main/kotlin/platform/mcp/aw/psi/mixins/AwEntryMixin.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) @@ -1,29 +0,0 @@ -/* - * Minecraft Development for IntelliJ - * - * https://mcdev.io/ - * - * Copyright (C) 2025 minecraft-dev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, version 3.0 only. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.demonwav.mcdev.platform.mcp.aw.psi.mixins - -import com.demonwav.mcdev.platform.mcp.aw.psi.AwElement - -interface AwEntryMixin : AwElement { - - val accessKind: String? - val targetClassName: String? -} Index: src/main/kotlin/platform/mcp/aw/psi/mixins/AwFieldEntryMixin.kt =================================================================== --- src/main/kotlin/platform/mcp/aw/psi/mixins/AwFieldEntryMixin.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) +++ src/main/kotlin/platform/mcp/aw/psi/mixins/AwFieldEntryMixin.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) @@ -1,27 +0,0 @@ -/* - * Minecraft Development for IntelliJ - * - * https://mcdev.io/ - * - * Copyright (C) 2025 minecraft-dev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, version 3.0 only. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.demonwav.mcdev.platform.mcp.aw.psi.mixins - -interface AwFieldEntryMixin : AwEntryMixin { - - val fieldName: String? - val fieldDescriptor: String? -} Index: src/main/kotlin/platform/mcp/aw/psi/mixins/AwHeaderMixin.kt =================================================================== --- src/main/kotlin/platform/mcp/aw/psi/mixins/AwHeaderMixin.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) +++ src/main/kotlin/platform/mcp/aw/psi/mixins/AwHeaderMixin.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) @@ -1,29 +0,0 @@ -/* - * Minecraft Development for IntelliJ - * - * https://mcdev.io/ - * - * Copyright (C) 2025 minecraft-dev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, version 3.0 only. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.demonwav.mcdev.platform.mcp.aw.psi.mixins - -import com.demonwav.mcdev.platform.mcp.aw.psi.AwElement - -interface AwHeaderMixin : AwElement { - - val versionString: String? - val namespaceString: String? -} Index: src/main/kotlin/platform/mcp/aw/psi/mixins/AwMemberNameMixin.kt =================================================================== --- src/main/kotlin/platform/mcp/aw/psi/mixins/AwMemberNameMixin.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) +++ src/main/kotlin/platform/mcp/aw/psi/mixins/AwMemberNameMixin.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) @@ -1,26 +0,0 @@ -/* - * Minecraft Development for IntelliJ - * - * https://mcdev.io/ - * - * Copyright (C) 2025 minecraft-dev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, version 3.0 only. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.demonwav.mcdev.platform.mcp.aw.psi.mixins - -import com.demonwav.mcdev.platform.mcp.aw.psi.AwElement -import com.intellij.psi.PsiReference - -interface AwMemberNameMixin : AwElement, PsiReference Index: src/main/kotlin/platform/mcp/aw/psi/mixins/AwMethodEntryMixin.kt =================================================================== --- src/main/kotlin/platform/mcp/aw/psi/mixins/AwMethodEntryMixin.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) +++ src/main/kotlin/platform/mcp/aw/psi/mixins/AwMethodEntryMixin.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) @@ -1,27 +0,0 @@ -/* - * Minecraft Development for IntelliJ - * - * https://mcdev.io/ - * - * Copyright (C) 2025 minecraft-dev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, version 3.0 only. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.demonwav.mcdev.platform.mcp.aw.psi.mixins - -interface AwMethodEntryMixin : AwEntryMixin { - - val methodName: String? - val methodDescriptor: String? -} Index: src/main/kotlin/platform/mcp/aw/psi/mixins/impl/AwClassEntryImplMixin.kt =================================================================== --- src/main/kotlin/platform/mcp/aw/psi/mixins/impl/AwClassEntryImplMixin.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) +++ src/main/kotlin/platform/mcp/aw/psi/mixins/impl/AwClassEntryImplMixin.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) @@ -1,26 +0,0 @@ -/* - * Minecraft Development for IntelliJ - * - * https://mcdev.io/ - * - * Copyright (C) 2025 minecraft-dev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, version 3.0 only. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.demonwav.mcdev.platform.mcp.aw.psi.mixins.impl - -import com.demonwav.mcdev.platform.mcp.aw.psi.mixins.AwClassEntryMixin -import com.intellij.lang.ASTNode - -abstract class AwClassEntryImplMixin(node: ASTNode) : AwEntryImplMixin(node), AwClassEntryMixin Index: src/main/kotlin/platform/mcp/aw/psi/mixins/impl/AwClassNameImplMixin.kt =================================================================== --- src/main/kotlin/platform/mcp/aw/psi/mixins/impl/AwClassNameImplMixin.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) +++ src/main/kotlin/platform/mcp/aw/psi/mixins/impl/AwClassNameImplMixin.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) @@ -1,62 +0,0 @@ -/* - * Minecraft Development for IntelliJ - * - * https://mcdev.io/ - * - * Copyright (C) 2025 minecraft-dev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, version 3.0 only. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.demonwav.mcdev.platform.mcp.aw.psi.mixins.impl - -import com.demonwav.mcdev.platform.mcp.aw.psi.mixins.AwClassNameMixin -import com.demonwav.mcdev.util.cached -import com.demonwav.mcdev.util.findQualifiedClass -import com.intellij.extapi.psi.ASTWrapperPsiElement -import com.intellij.lang.ASTNode -import com.intellij.openapi.util.TextRange -import com.intellij.psi.PsiClass -import com.intellij.psi.PsiElement -import com.intellij.psi.PsiReference -import com.intellij.psi.util.PsiModificationTracker -import com.intellij.util.IncorrectOperationException - -abstract class AwClassNameImplMixin(node: ASTNode) : ASTWrapperPsiElement(node), AwClassNameMixin { - - override fun getElement(): PsiElement = this - - override fun getReference(): PsiReference? = this - - override fun resolve(): PsiElement? { - return cached(PsiModificationTracker.MODIFICATION_COUNT) { findQualifiedClass(text.replace('/', '.'), this) } - } - - override fun getRangeInElement(): TextRange = TextRange(0, text.length) - - override fun getCanonicalText(): String = text - - override fun handleElementRename(newElementName: String): PsiElement { - throw IncorrectOperationException() - } - - override fun bindToElement(element: PsiElement): PsiElement { - throw IncorrectOperationException() - } - - override fun isReferenceTo(element: PsiElement): Boolean { - return element is PsiClass && element.qualifiedName == text.replace('/', '.') - } - - override fun isSoft(): Boolean = false -} Index: src/main/kotlin/platform/mcp/aw/psi/mixins/impl/AwDescElementImplMixin.kt =================================================================== --- src/main/kotlin/platform/mcp/aw/psi/mixins/impl/AwDescElementImplMixin.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) +++ src/main/kotlin/platform/mcp/aw/psi/mixins/impl/AwDescElementImplMixin.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) @@ -1,70 +0,0 @@ -/* - * Minecraft Development for IntelliJ - * - * https://mcdev.io/ - * - * Copyright (C) 2025 minecraft-dev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, version 3.0 only. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.demonwav.mcdev.platform.mcp.aw.psi.mixins.impl - -import com.demonwav.mcdev.platform.mcp.aw.psi.mixins.AwDescElementMixin -import com.demonwav.mcdev.util.cached -import com.demonwav.mcdev.util.findQualifiedClass -import com.intellij.extapi.psi.ASTWrapperPsiElement -import com.intellij.lang.ASTNode -import com.intellij.openapi.util.TextRange -import com.intellij.psi.PsiClass -import com.intellij.psi.PsiElement -import com.intellij.psi.PsiReference -import com.intellij.psi.util.PsiModificationTracker -import com.intellij.util.IncorrectOperationException - -abstract class AwDescElementImplMixin(node: ASTNode) : ASTWrapperPsiElement(node), AwDescElementMixin { - - override fun getElement(): PsiElement = this - - override fun getReference(): PsiReference? = this - - override fun resolve(): PsiElement? = cached(PsiModificationTracker.MODIFICATION_COUNT) { - val name = asQualifiedName() ?: return@cached null - return@cached findQualifiedClass(name, this) - } - - override fun getRangeInElement(): TextRange = TextRange(0, text.length) - - override fun getCanonicalText(): String = text - - override fun handleElementRename(newElementName: String): PsiElement { - throw IncorrectOperationException() - } - - override fun bindToElement(element: PsiElement): PsiElement { - throw IncorrectOperationException() - } - - override fun isReferenceTo(element: PsiElement): Boolean { - return element is PsiClass && element.qualifiedName == asQualifiedName() - } - - private fun asQualifiedName(): String? = - if (text.length > 1) { - text.substring(1, text.length - 1).replace('/', '.') - } else { - null - } - - override fun isSoft(): Boolean = false -} Index: src/main/kotlin/platform/mcp/aw/psi/mixins/impl/AwEntryImplMixin.kt =================================================================== --- src/main/kotlin/platform/mcp/aw/psi/mixins/impl/AwEntryImplMixin.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) +++ src/main/kotlin/platform/mcp/aw/psi/mixins/impl/AwEntryImplMixin.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) @@ -1,36 +0,0 @@ -/* - * Minecraft Development for IntelliJ - * - * https://mcdev.io/ - * - * Copyright (C) 2025 minecraft-dev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, version 3.0 only. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.demonwav.mcdev.platform.mcp.aw.psi.mixins.impl - -import com.demonwav.mcdev.platform.mcp.aw.gen.psi.AwTypes -import com.demonwav.mcdev.platform.mcp.aw.psi.mixins.AwEntryMixin -import com.intellij.extapi.psi.ASTWrapperPsiElement -import com.intellij.lang.ASTNode -import com.intellij.psi.PsiElement - -abstract class AwEntryImplMixin(node: ASTNode) : ASTWrapperPsiElement(node), AwEntryMixin { - - override val accessKind: String? - get() = findChildByType(AwTypes.ACCESS)?.text - - override val targetClassName: String? - get() = findChildByType(AwTypes.CLASS_NAME)?.text -} Index: src/main/kotlin/platform/mcp/aw/psi/mixins/impl/AwFieldEntryImplMixin.kt =================================================================== --- src/main/kotlin/platform/mcp/aw/psi/mixins/impl/AwFieldEntryImplMixin.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) +++ src/main/kotlin/platform/mcp/aw/psi/mixins/impl/AwFieldEntryImplMixin.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) @@ -1,34 +0,0 @@ -/* - * Minecraft Development for IntelliJ - * - * https://mcdev.io/ - * - * Copyright (C) 2025 minecraft-dev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, version 3.0 only. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.demonwav.mcdev.platform.mcp.aw.psi.mixins.impl - -import com.demonwav.mcdev.platform.mcp.aw.gen.psi.AwTypes -import com.demonwav.mcdev.platform.mcp.aw.psi.mixins.AwFieldEntryMixin -import com.intellij.lang.ASTNode -import com.intellij.psi.PsiElement - -abstract class AwFieldEntryImplMixin(node: ASTNode) : AwEntryImplMixin(node), AwFieldEntryMixin { - override val fieldName: String? - get() = findChildByType(AwTypes.MEMBER_NAME)?.text - - override val fieldDescriptor: String? - get() = findChildByType(AwTypes.FIELD_DESC)?.text -} Index: src/main/kotlin/platform/mcp/aw/psi/mixins/impl/AwHeaderImplMixin.kt =================================================================== --- src/main/kotlin/platform/mcp/aw/psi/mixins/impl/AwHeaderImplMixin.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) +++ src/main/kotlin/platform/mcp/aw/psi/mixins/impl/AwHeaderImplMixin.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) @@ -1,36 +0,0 @@ -/* - * Minecraft Development for IntelliJ - * - * https://mcdev.io/ - * - * Copyright (C) 2025 minecraft-dev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, version 3.0 only. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.demonwav.mcdev.platform.mcp.aw.psi.mixins.impl - -import com.demonwav.mcdev.platform.mcp.aw.gen.psi.AwTypes -import com.demonwav.mcdev.platform.mcp.aw.psi.mixins.AwHeaderMixin -import com.intellij.extapi.psi.ASTWrapperPsiElement -import com.intellij.lang.ASTNode -import com.intellij.psi.PsiElement - -abstract class AwHeaderImplMixin(node: ASTNode) : ASTWrapperPsiElement(node), AwHeaderMixin { - - override val versionString: String? - get() = findChildByType(AwTypes.HEADER_VERSION_ELEMENT)?.text - - override val namespaceString: String? - get() = findChildByType(AwTypes.HEADER_NAMESPACE_ELEMENT)?.text -} Index: src/main/kotlin/platform/mcp/aw/psi/mixins/impl/AwMemberNameImplMixin.kt =================================================================== --- src/main/kotlin/platform/mcp/aw/psi/mixins/impl/AwMemberNameImplMixin.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) +++ src/main/kotlin/platform/mcp/aw/psi/mixins/impl/AwMemberNameImplMixin.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) @@ -1,105 +0,0 @@ -/* - * Minecraft Development for IntelliJ - * - * https://mcdev.io/ - * - * Copyright (C) 2025 minecraft-dev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, version 3.0 only. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.demonwav.mcdev.platform.mcp.aw.psi.mixins.impl - -import com.demonwav.mcdev.platform.mcp.aw.gen.psi.AwFieldEntry -import com.demonwav.mcdev.platform.mcp.aw.gen.psi.AwMethodEntry -import com.demonwav.mcdev.platform.mcp.aw.psi.mixins.AwEntryMixin -import com.demonwav.mcdev.platform.mcp.aw.psi.mixins.AwMemberNameMixin -import com.demonwav.mcdev.util.MemberReference -import com.demonwav.mcdev.util.cached -import com.intellij.codeInsight.completion.JavaLookupElementBuilder -import com.intellij.extapi.psi.ASTWrapperPsiElement -import com.intellij.lang.ASTNode -import com.intellij.openapi.util.TextRange -import com.intellij.psi.JavaPsiFacade -import com.intellij.psi.PsiClass -import com.intellij.psi.PsiElement -import com.intellij.psi.PsiMethod -import com.intellij.psi.PsiReference -import com.intellij.psi.PsiSubstitutor -import com.intellij.psi.util.PsiModificationTracker -import com.intellij.psi.util.parentOfType -import com.intellij.util.ArrayUtil -import com.intellij.util.IncorrectOperationException -import com.intellij.util.containers.map2Array - -abstract class AwMemberNameImplMixin(node: ASTNode) : ASTWrapperPsiElement(node), AwMemberNameMixin { - - override fun getElement(): PsiElement = this - - override fun getReference(): PsiReference? = this - - override fun resolve(): PsiElement? = cached(PsiModificationTracker.MODIFICATION_COUNT) { - val entry = this.parentOfType() ?: return@cached null - val owner = entry.targetClassName?.replace('/', '.') - return@cached when (entry) { - is AwMethodEntry -> { - val name = entry.methodName ?: return@cached null - val desc = entry.methodDescriptor - MemberReference(name, desc, owner).resolveMember(project, resolveScope) - // fallback if descriptor is invalid - ?: MemberReference(name, null, owner).resolveMember(project, resolveScope) - } - is AwFieldEntry -> { - val name = entry.fieldName ?: return@cached null - MemberReference(name, null, owner) - .resolveMember(project, resolveScope) - } - else -> null - } - } - - override fun getVariants(): Array<*> { - val entry = this.parentOfType() ?: return ArrayUtil.EMPTY_OBJECT_ARRAY - val targetClassName = entry.targetClassName?.replace('/', '.')?.replace('$', '.') - ?: return ArrayUtil.EMPTY_OBJECT_ARRAY - val targetClass = JavaPsiFacade.getInstance(project)?.findClass(targetClassName, resolveScope) - ?: return ArrayUtil.EMPTY_OBJECT_ARRAY - - return when (entry) { - is AwMethodEntry -> targetClass.methods.map2Array(::methodLookupElement) - is AwFieldEntry -> targetClass.fields - else -> ArrayUtil.EMPTY_OBJECT_ARRAY - } - } - - private fun methodLookupElement(it: PsiMethod) = - JavaLookupElementBuilder.forMethod(it, if (it.isConstructor) "" else it.name, PsiSubstitutor.EMPTY, null) - - override fun getRangeInElement(): TextRange = TextRange(0, text.length) - - override fun getCanonicalText(): String = text - - override fun handleElementRename(newElementName: String): PsiElement { - throw IncorrectOperationException() - } - - override fun bindToElement(element: PsiElement): PsiElement { - throw IncorrectOperationException() - } - - override fun isReferenceTo(element: PsiElement): Boolean { - return element is PsiClass && element.qualifiedName == text.replace('/', '.') - } - - override fun isSoft(): Boolean = false -} Index: src/main/kotlin/platform/mcp/aw/psi/mixins/impl/AwMethodEntryImplMixin.kt =================================================================== --- src/main/kotlin/platform/mcp/aw/psi/mixins/impl/AwMethodEntryImplMixin.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) +++ src/main/kotlin/platform/mcp/aw/psi/mixins/impl/AwMethodEntryImplMixin.kt (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) @@ -1,34 +0,0 @@ -/* - * Minecraft Development for IntelliJ - * - * https://mcdev.io/ - * - * Copyright (C) 2025 minecraft-dev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, version 3.0 only. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.demonwav.mcdev.platform.mcp.aw.psi.mixins.impl - -import com.demonwav.mcdev.platform.mcp.aw.gen.psi.AwTypes -import com.demonwav.mcdev.platform.mcp.aw.psi.mixins.AwMethodEntryMixin -import com.intellij.lang.ASTNode -import com.intellij.psi.PsiElement - -abstract class AwMethodEntryImplMixin(node: ASTNode) : AwEntryImplMixin(node), AwMethodEntryMixin { - override val methodName: String? - get() = findChildByType(AwTypes.MEMBER_NAME)?.text - - override val methodDescriptor: String? - get() = findChildByType(AwTypes.METHOD_DESC)?.text -} Index: src/main/kotlin/platform/mcp/ct/CtAnnotator.kt =================================================================== --- src/main/kotlin/platform/mcp/ct/CtAnnotator.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/kotlin/platform/mcp/ct/CtAnnotator.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,77 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mcp.ct + +import com.demonwav.mcdev.platform.mcp.ct.gen.psi.CtAccess +import com.demonwav.mcdev.platform.mcp.ct.gen.psi.CtClassLiteral +import com.demonwav.mcdev.platform.mcp.ct.gen.psi.CtFieldLiteral +import com.demonwav.mcdev.platform.mcp.ct.gen.psi.CtHeader +import com.demonwav.mcdev.platform.mcp.ct.gen.psi.CtMethodLiteral +import com.demonwav.mcdev.util.childOfType +import com.google.common.collect.HashMultimap +import com.google.common.collect.Multimaps +import com.intellij.lang.annotation.AnnotationHolder +import com.intellij.lang.annotation.Annotator +import com.intellij.lang.annotation.HighlightSeverity +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiWhiteSpace +import com.intellij.psi.util.PsiTreeUtil + +class CtAnnotator : Annotator { + + override fun annotate(element: PsiElement, holder: AnnotationHolder) { + if (element is CtAccess) { + val access = element.text + val target = PsiTreeUtil.skipSiblingsForward(element, PsiWhiteSpace::class.java)?.text + if (!compatibleByAccessMap.get(access).contains(target)) { + holder.newAnnotation(HighlightSeverity.ERROR, "Access '$access' cannot be used on '$target'").create() + } + + if (element.accessElement.text.startsWith("transitive-") && + element.containingFile?.childOfType()?.versionString == "v1" + ) { + holder.newAnnotation(HighlightSeverity.ERROR, "Transitive accesses were introduced in v2").create() + } + } else if (element is CtFieldLiteral || element is CtMethodLiteral || element is CtClassLiteral) { + val target = element.text + val access = PsiTreeUtil.skipSiblingsBackward(element, PsiWhiteSpace::class.java)?.text + if (!compatibleByTargetMap.get(target).contains(access)) { + holder.newAnnotation(HighlightSeverity.ERROR, "'$target' cannot be used with '$access'").create() + } + } + } + + companion object { + + val compatibleByAccessMap = HashMultimap.create() + val compatibleByTargetMap = HashMultimap.create() + + init { + compatibleByAccessMap.putAll("accessible", setOf("class", "method", "field")) + compatibleByAccessMap.putAll("transitive-accessible", setOf("class", "method", "field")) + compatibleByAccessMap.putAll("extendable", setOf("class", "method")) + compatibleByAccessMap.putAll("transitive-extendable", setOf("class", "method")) + compatibleByAccessMap.putAll("mutable", setOf("field")) + compatibleByAccessMap.putAll("transitive-mutable", setOf("field")) + Multimaps.invertFrom(compatibleByAccessMap, compatibleByTargetMap) + } + } +} Index: src/main/kotlin/platform/mcp/ct/CtColorSettingsPage.kt =================================================================== --- src/main/kotlin/platform/mcp/ct/CtColorSettingsPage.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/kotlin/platform/mcp/ct/CtColorSettingsPage.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,72 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mcp.ct + +import com.demonwav.mcdev.asset.PlatformAssets +import com.intellij.openapi.editor.colors.TextAttributesKey +import com.intellij.openapi.options.colors.AttributesDescriptor +import com.intellij.openapi.options.colors.ColorDescriptor +import com.intellij.openapi.options.colors.ColorSettingsPage + +class CtColorSettingsPage : ColorSettingsPage { + + override fun getIcon() = PlatformAssets.MCP_ICON + override fun getHighlighter() = CtSyntaxHighlighter() + override fun getDemoText() = + """ + classTweaker v1 named + + # https://www.fabricmc.net/wiki/tutorial:accesswideners + + extendable class net/minecraft/world/item/crafting/Ingredient + transitive-extendable class net/minecraft/world/item/crafting/Ingredient + accessible class net/minecraft/world/entity/monster/Phantom${'$'}AttackPhase + transitive-accessible class net/minecraft/world/entity/monster/Phantom${'$'}AttackPhase + extendable method net/minecraft/server/players/IpBanList getIpFromAddress (Ljava/net/SocketAddress;)Ljava/lang/String; + extendable method net/minecraft/world/item/crafting/Ingredient (Ljava/util/stream/Stream;)V + accessible field net/minecraft/world/item/crafting/Ingredient values [Lnet/minecraft/world/item/crafting/Ingredient${'$'}Value; + inject-interface net/minecraft/world/level/block/Block com/example/MyBlockInterface + transitive-inject-interface net/minecraft/world/level/block/Block com/example/MyTransitiveBlockInterface + """.trimIndent() + + override fun getAdditionalHighlightingTagToDescriptorMap(): Map? = null + override fun getAttributeDescriptors() = DESCRIPTORS + override fun getColorDescriptors(): Array = ColorDescriptor.EMPTY_ARRAY + override fun getDisplayName() = "Class Tweakers" + + companion object { + private val DESCRIPTORS = arrayOf( + AttributesDescriptor("Header Name", CtSyntaxHighlighter.HEADER_NAME), + AttributesDescriptor("Header Namespace", CtSyntaxHighlighter.HEADER_NAMESPACE), + AttributesDescriptor("Access", CtSyntaxHighlighter.ACCESS), + AttributesDescriptor("Inject Interface", CtSyntaxHighlighter.INJECT_INTERFACE), + AttributesDescriptor("Class Element", CtSyntaxHighlighter.CLASS_ELEMENT), + AttributesDescriptor("Method Element", CtSyntaxHighlighter.METHOD_ELEMENT), + AttributesDescriptor("Field Element", CtSyntaxHighlighter.FIELD_ELEMENT), + AttributesDescriptor("Class Name", CtSyntaxHighlighter.CLASS_NAME), + AttributesDescriptor("Member Name", CtSyntaxHighlighter.MEMBER_NAME), + AttributesDescriptor("Class Value", CtSyntaxHighlighter.CLASS_VALUE), + AttributesDescriptor("Primitive", CtSyntaxHighlighter.PRIMITIVE), + AttributesDescriptor("Type Variable", CtSyntaxHighlighter.TYPE_VARIABLE), + AttributesDescriptor("Comment", CtSyntaxHighlighter.COMMENT), + ) + } +} Index: src/main/kotlin/platform/mcp/ct/CtCommenter.kt =================================================================== --- src/main/kotlin/platform/mcp/ct/CtCommenter.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/kotlin/platform/mcp/ct/CtCommenter.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,36 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mcp.ct + +import com.intellij.lang.Commenter + +class CtCommenter : Commenter { + + override fun getLineCommentPrefix() = "#" + + override fun getBlockCommentPrefix(): String? = null + + override fun getBlockCommentSuffix(): String? = null + + override fun getCommentedBlockCommentPrefix(): String? = null + + override fun getCommentedBlockCommentSuffix(): String? = null +} Index: src/main/kotlin/platform/mcp/ct/CtCompletionContributor.kt =================================================================== --- src/main/kotlin/platform/mcp/ct/CtCompletionContributor.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/kotlin/platform/mcp/ct/CtCompletionContributor.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,126 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mcp.ct + +import com.demonwav.mcdev.platform.mcp.ct.gen.psi.CtTypes +import com.intellij.codeInsight.completion.CodeCompletionHandlerBase +import com.intellij.codeInsight.completion.CompletionContributor +import com.intellij.codeInsight.completion.CompletionParameters +import com.intellij.codeInsight.completion.CompletionProvider +import com.intellij.codeInsight.completion.CompletionResultSet +import com.intellij.codeInsight.completion.CompletionType +import com.intellij.codeInsight.completion.InsertionContext +import com.intellij.codeInsight.lookup.LookupElementBuilder +import com.intellij.openapi.application.runReadAction +import com.intellij.patterns.PlatformPatterns +import com.intellij.psi.PsiDocumentManager +import com.intellij.psi.TokenType +import com.intellij.psi.util.elementType +import com.intellij.psi.util.prevLeaf +import com.intellij.util.ProcessingContext + +class CtCompletionContributor : CompletionContributor() { + init { + extend(null, PlatformPatterns.psiElement(), CtHeaderCompletionProvider) + val whitespace = PlatformPatterns.psiElement(TokenType.WHITE_SPACE) + val namespacePattern = PlatformPatterns.psiElement() + .afterLeafSkipping(whitespace, PlatformPatterns.psiElement(CtTypes.HEADER_VERSION_ELEMENT)) + extend(null, namespacePattern, CtNamespaceCompletionProvider) + val entryStartPattern = PlatformPatterns.psiElement().afterLeaf(PlatformPatterns.psiElement(CtTypes.CRLF)) + extend(null, entryStartPattern, CtEntryStartCompletionProvider) + val awTargetPattern = PlatformPatterns.psiElement() + .afterLeafSkipping(whitespace, PlatformPatterns.psiElement(CtTypes.ACCESS_ELEMENT)) + extend(null, awTargetPattern, CtAwTargetCompletionProvider) + } +} + +private fun insertWhitespace(context: InsertionContext) { + PsiDocumentManager.getInstance(context.project) + .doPostponedOperationsAndUnblockDocument(context.document) + context.document.insertString(context.editor.caretModel.offset, " ") + context.editor.caretModel.moveCaretRelatively(1, 0, false, false, false) + context.setLaterRunnable { + runReadAction { + CodeCompletionHandlerBase.createHandler(CompletionType.BASIC) + .invokeCompletion(context.project, context.editor) + } + } +} + +object CtHeaderCompletionProvider : CompletionProvider() { + + override fun addCompletions( + parameters: CompletionParameters, + context: ProcessingContext, + result: CompletionResultSet, + ) { + if (parameters.position.prevLeaf(true) == null) { + result.addElement(LookupElementBuilder.create("accessWidener v1 named")) + result.addElement(LookupElementBuilder.create("accessWidener v2 named")) + result.addElement(LookupElementBuilder.create("classTweaker v1 named")) + } + } +} + +object CtNamespaceCompletionProvider : CompletionProvider() { + + override fun addCompletions( + parameters: CompletionParameters, + context: ProcessingContext, + result: CompletionResultSet, + ) = result.addAllElements(listOf("named", "intermediary").map(LookupElementBuilder::create)) +} + +object CtEntryStartCompletionProvider : CompletionProvider() { + + override fun addCompletions( + parameters: CompletionParameters, + context: ProcessingContext, + result: CompletionResultSet, + ) { + val elements = listOf( + "accessible", + "transitive-accessible", + "extendable", + "transitive-extendable", + "mutable", + "transitive-mutable", + "inject-interface", + "transitive-inject-interface" + ).map { LookupElementBuilder.create(it).withInsertHandler { ctx, _ -> insertWhitespace(ctx) } } + result.addAllElements(elements) + } +} + +object CtAwTargetCompletionProvider : CompletionProvider() { + + override fun addCompletions( + parameters: CompletionParameters, + context: ProcessingContext, + result: CompletionResultSet, + ) { + val text = parameters.position + .prevLeaf { it.elementType == CtTypes.ACCESS_ELEMENT || it.elementType == CtTypes.CRLF }?.text + val elements = CtAnnotator.compatibleByAccessMap.get(text) + .map { LookupElementBuilder.create(it).withInsertHandler { ctx, _ -> insertWhitespace(ctx) } } + result.addAllElements(elements) + } +} Index: src/main/kotlin/platform/mcp/ct/CtFile.kt =================================================================== --- src/main/kotlin/platform/mcp/ct/CtFile.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/kotlin/platform/mcp/ct/CtFile.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,41 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mcp.ct + +import com.demonwav.mcdev.asset.PlatformAssets +import com.demonwav.mcdev.platform.mcp.ct.gen.psi.CtHeader +import com.demonwav.mcdev.platform.mcp.ct.psi.mixins.CtEntryMixin +import com.demonwav.mcdev.util.childrenOfType +import com.intellij.extapi.psi.PsiFileBase +import com.intellij.psi.FileViewProvider + +class CtFile(viewProvider: FileViewProvider) : PsiFileBase(viewProvider, CtLanguage) { + + val header: CtHeader? + get() = children.first { it is CtHeader } as? CtHeader + + val entries: Collection + get() = childrenOfType() + + override fun getFileType() = CtFileType + override fun toString() = "Class Tweaker File" + override fun getIcon(flags: Int) = PlatformAssets.MCP_ICON +} Index: src/main/kotlin/platform/mcp/ct/CtFileType.kt =================================================================== --- src/main/kotlin/platform/mcp/ct/CtFileType.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/kotlin/platform/mcp/ct/CtFileType.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,35 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mcp.ct + +import com.demonwav.mcdev.asset.PlatformAssets +import com.intellij.openapi.fileTypes.LanguageFileType + +object CtFileType : LanguageFileType(CtLanguage) { + + override fun getName() = "Class Tweaker" + + override fun getDescription() = "Class Tweaker" + + override fun getDefaultExtension() = "classtweaker" + + override fun getIcon() = PlatformAssets.MCP_ICON +} Index: src/main/kotlin/platform/mcp/ct/CtLanguage.kt =================================================================== --- src/main/kotlin/platform/mcp/ct/CtLanguage.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/kotlin/platform/mcp/ct/CtLanguage.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,25 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mcp.ct + +import com.intellij.lang.Language + +object CtLanguage : Language("Class Tweaker") Index: src/main/kotlin/platform/mcp/ct/CtLexerAdapter.kt =================================================================== --- src/main/kotlin/platform/mcp/ct/CtLexerAdapter.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/kotlin/platform/mcp/ct/CtLexerAdapter.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,26 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mcp.ct + +import com.demonwav.mcdev.platform.mcp.ct.gen.CtLexer +import com.intellij.lexer.FlexAdapter + +class CtLexerAdapter : FlexAdapter(CtLexer()) Index: src/main/kotlin/platform/mcp/ct/CtParserDefinition.kt =================================================================== --- src/main/kotlin/platform/mcp/ct/CtParserDefinition.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/kotlin/platform/mcp/ct/CtParserDefinition.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,60 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mcp.ct + +import com.demonwav.mcdev.platform.mcp.ct.gen.parser.CtParser +import com.demonwav.mcdev.platform.mcp.ct.gen.psi.CtTypes +import com.intellij.lang.ASTNode +import com.intellij.lang.Language +import com.intellij.lang.LanguageUtil +import com.intellij.lang.ParserDefinition +import com.intellij.lang.PsiParser +import com.intellij.lexer.Lexer +import com.intellij.openapi.project.Project +import com.intellij.psi.FileViewProvider +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiFile +import com.intellij.psi.TokenType +import com.intellij.psi.tree.IFileElementType +import com.intellij.psi.tree.TokenSet + +class CtParserDefinition : ParserDefinition { + + override fun createLexer(project: Project): Lexer = CtLexerAdapter() + override fun createParser(project: Project): PsiParser = CtParser() + override fun getFileNodeType(): IFileElementType = FILE + override fun getWhitespaceTokens(): TokenSet = WHITE_SPACES + override fun getCommentTokens(): TokenSet = COMMENTS + override fun getStringLiteralElements(): TokenSet = TokenSet.EMPTY + override fun createElement(node: ASTNode): PsiElement = CtTypes.Factory.createElement(node) + override fun createFile(viewProvider: FileViewProvider): PsiFile = CtFile(viewProvider) + + override fun spaceExistenceTypeBetweenTokens(left: ASTNode, right: ASTNode): ParserDefinition.SpaceRequirements { + return LanguageUtil.canStickTokensTogetherByLexer(left, right, CtLexerAdapter()) + } + + companion object { + private val WHITE_SPACES = TokenSet.create(TokenType.WHITE_SPACE) + private val COMMENTS = TokenSet.create(CtTypes.COMMENT) + + private val FILE = IFileElementType(Language.findInstance(CtLanguage::class.java)) + } +} Index: src/main/kotlin/platform/mcp/ct/CtSyntaxHighlighter.kt =================================================================== --- src/main/kotlin/platform/mcp/ct/CtSyntaxHighlighter.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/kotlin/platform/mcp/ct/CtSyntaxHighlighter.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,100 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mcp.ct + +import com.demonwav.mcdev.platform.mcp.ct.gen.psi.CtTypes +import com.intellij.openapi.editor.DefaultLanguageHighlighterColors +import com.intellij.openapi.editor.HighlighterColors +import com.intellij.openapi.editor.colors.TextAttributesKey +import com.intellij.openapi.fileTypes.SyntaxHighlighterBase +import com.intellij.psi.TokenType +import com.intellij.psi.tree.IElementType + +class CtSyntaxHighlighter : SyntaxHighlighterBase() { + + override fun getHighlightingLexer() = CtLexerAdapter() + + override fun getTokenHighlights(tokenType: IElementType) = + when (tokenType) { + CtTypes.HEADER_NAME -> HEADER_NAME_KEYS + CtTypes.HEADER_NAMESPACE_ELEMENT -> HEADER_NAMESPACE_KEYS + CtTypes.ACCESS_ELEMENT -> ACCESS_KEYS + CtTypes.INJECT_INTERFACE_ELEMENT -> INJECT_INTERFACE_KEYS + CtTypes.CLASS_ELEMENT -> CLASS_ELEMENT_KEYS + CtTypes.METHOD_ELEMENT -> METHOD_ELEMENT_KEYS + CtTypes.FIELD_ELEMENT -> FIELD_ELEMENT_KEYS + CtTypes.CLASS_NAME_ELEMENT -> CLASS_NAME_KEYS + CtTypes.NAME_ELEMENT -> MEMBER_NAME_KEYS + CtTypes.CLASS_VALUE, CtTypes.SIGNATURE_CLASS_VALUE_START, CtTypes.SIGNATURE_CLASS_VALUE_END -> CLASS_VALUE_KEYS + CtTypes.PRIMITIVE -> PRIMITIVE_KEYS + CtTypes.TYPE_VARIABLE -> TYPE_VARIABLE_KEYS + CtTypes.COMMENT -> COMMENT_KEYS + TokenType.BAD_CHARACTER -> BAD_CHARACTER_KEYS + else -> EMPTY_KEYS + } + + companion object { + val HEADER_NAME = + TextAttributesKey.createTextAttributesKey("CT_HEADER_NAME", DefaultLanguageHighlighterColors.KEYWORD) + val HEADER_NAMESPACE = + TextAttributesKey.createTextAttributesKey("CT_HEADER_NAMESPACE", DefaultLanguageHighlighterColors.KEYWORD) + val ACCESS = + TextAttributesKey.createTextAttributesKey("CT_ACCESS", DefaultLanguageHighlighterColors.KEYWORD) + val INJECT_INTERFACE = + TextAttributesKey.createTextAttributesKey("CT_INJECT_INTERFACE", DefaultLanguageHighlighterColors.KEYWORD) + val CLASS_ELEMENT = + TextAttributesKey.createTextAttributesKey("CT_CLASS_ELEMENT", DefaultLanguageHighlighterColors.KEYWORD) + val METHOD_ELEMENT = + TextAttributesKey.createTextAttributesKey("CT_METHOD_ELEMENT", DefaultLanguageHighlighterColors.KEYWORD) + val FIELD_ELEMENT = + TextAttributesKey.createTextAttributesKey("CT_FIELD_ELEMENT", DefaultLanguageHighlighterColors.KEYWORD) + val CLASS_NAME = + TextAttributesKey.createTextAttributesKey("CT_CLASS_NAME", DefaultLanguageHighlighterColors.STRING) + val MEMBER_NAME = + TextAttributesKey.createTextAttributesKey("CT_MEMBER_NAME", DefaultLanguageHighlighterColors.STATIC_FIELD) + val CLASS_VALUE = + TextAttributesKey.createTextAttributesKey("CT_CLASS_VALUE", DefaultLanguageHighlighterColors.STATIC_METHOD) + val PRIMITIVE = + TextAttributesKey.createTextAttributesKey("CT_PRIMITIVE", DefaultLanguageHighlighterColors.NUMBER) + val TYPE_VARIABLE = + TextAttributesKey.createTextAttributesKey("CT_TYPE_VARIABLE", DefaultLanguageHighlighterColors.STATIC_METHOD) + val COMMENT = + TextAttributesKey.createTextAttributesKey("CT_COMMENT", DefaultLanguageHighlighterColors.LINE_COMMENT) + val BAD_CHARACTER = + TextAttributesKey.createTextAttributesKey("CT_BAD_CHARACTER", HighlighterColors.BAD_CHARACTER) + + private val HEADER_NAME_KEYS = arrayOf(HEADER_NAME) + private val HEADER_NAMESPACE_KEYS = arrayOf(HEADER_NAMESPACE) + private val ACCESS_KEYS = arrayOf(ACCESS) + private val INJECT_INTERFACE_KEYS = arrayOf(INJECT_INTERFACE) + private val CLASS_ELEMENT_KEYS = arrayOf(CLASS_ELEMENT) + private val METHOD_ELEMENT_KEYS = arrayOf(METHOD_ELEMENT) + private val FIELD_ELEMENT_KEYS = arrayOf(FIELD_ELEMENT) + private val CLASS_NAME_KEYS = arrayOf(CLASS_NAME) + private val MEMBER_NAME_KEYS = arrayOf(MEMBER_NAME) + private val CLASS_VALUE_KEYS = arrayOf(CLASS_VALUE) + private val PRIMITIVE_KEYS = arrayOf(PRIMITIVE) + private val TYPE_VARIABLE_KEYS = arrayOf(TYPE_VARIABLE) + private val COMMENT_KEYS = arrayOf(COMMENT) + private val BAD_CHARACTER_KEYS = arrayOf(BAD_CHARACTER) + private val EMPTY_KEYS = emptyArray() + } +} Index: src/main/kotlin/platform/mcp/ct/CtSyntaxHighlighterFactory.kt =================================================================== --- src/main/kotlin/platform/mcp/ct/CtSyntaxHighlighterFactory.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/kotlin/platform/mcp/ct/CtSyntaxHighlighterFactory.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,29 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mcp.ct + +import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory +import com.intellij.openapi.project.Project +import com.intellij.openapi.vfs.VirtualFile + +class CtSyntaxHighlighterFactory : SyntaxHighlighterFactory() { + override fun getSyntaxHighlighter(project: Project?, virtualFile: VirtualFile?) = CtSyntaxHighlighter() +} Index: src/main/kotlin/platform/mcp/ct/fixes/CopyAwAccessibleEntryFix.kt =================================================================== --- src/main/kotlin/platform/mcp/ct/fixes/CopyAwAccessibleEntryFix.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/kotlin/platform/mcp/ct/fixes/CopyAwAccessibleEntryFix.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,69 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mcp.ct.fixes + +import com.demonwav.mcdev.facet.MinecraftFacet +import com.demonwav.mcdev.platform.fabric.FabricModuleType +import com.demonwav.mcdev.platform.mcp.actions.CopyAwAction +import com.demonwav.mcdev.platform.sponge.SpongeModuleType +import com.demonwav.mcdev.util.findModule +import com.intellij.codeInsight.daemon.QuickFixActionRegistrar +import com.intellij.codeInsight.intention.IntentionAction +import com.intellij.codeInsight.quickfix.UnresolvedReferenceQuickFixProvider +import com.intellij.openapi.editor.Editor +import com.intellij.openapi.project.Project +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiFile +import com.intellij.psi.PsiJavaCodeReferenceElement + +class CopyAwAccessibleEntryFix(val target: PsiElement, val element: PsiElement) : IntentionAction { + + class Provider : UnresolvedReferenceQuickFixProvider() { + + override fun registerFixes(ref: PsiJavaCodeReferenceElement, registrar: QuickFixActionRegistrar) { + val module = ref.findModule() ?: return + val isApplicable = MinecraftFacet.getInstance(module, FabricModuleType, SpongeModuleType) != null + if (!isApplicable) { + return + } + + val resolve = ref.advancedResolve(true) + val target = resolve.element + if (target != null && !resolve.isAccessible) { + registrar.register(CopyAwAccessibleEntryFix(target, ref)) + } + } + + override fun getReferenceClass(): Class = PsiJavaCodeReferenceElement::class.java + } + + override fun startInWriteAction(): Boolean = false + + override fun getText(): String = "Copy AW entry" + + override fun getFamilyName(): String = "Copy AW entry for inaccessible element" + + override fun isAvailable(project: Project, editor: Editor?, file: PsiFile?): Boolean = true + + override fun invoke(project: Project, editor: Editor?, file: PsiFile?) { + CopyAwAction.doCopy(target, element, editor, null) + } +} Index: src/main/kotlin/platform/mcp/ct/inspections/DuplicateAwEntryInspection.kt =================================================================== --- src/main/kotlin/platform/mcp/ct/inspections/DuplicateAwEntryInspection.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/kotlin/platform/mcp/ct/inspections/DuplicateAwEntryInspection.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,81 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mcp.ct.inspections + +import com.demonwav.mcdev.platform.mcp.ct.CtFile +import com.demonwav.mcdev.platform.mcp.ct.psi.mixins.CtAwEntryMixin +import com.demonwav.mcdev.platform.mcp.ct.psi.mixins.CtAwMemberNameMixin +import com.demonwav.mcdev.util.childOfType +import com.intellij.codeInspection.InspectionManager +import com.intellij.codeInspection.LocalInspectionTool +import com.intellij.codeInspection.ProblemDescriptor +import com.intellij.codeInspection.ProblemHighlightType +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiFile +import com.intellij.psi.PsiNamedElement +import com.jetbrains.rd.util.getOrCreate +import org.jetbrains.plugins.groovy.codeInspection.fixes.RemoveElementQuickFix + +class DuplicateAwEntryInspection : LocalInspectionTool() { + + override fun checkFile(file: PsiFile, manager: InspectionManager, isOnTheFly: Boolean): Array? { + if (file !is CtFile) { + return null + } + val collected = HashMap, MutableList>() + file.entries.filterIsInstance().forEach { + val target = it.childOfType()?.resolve() + val accessKind = it.accessKind + if (target != null && accessKind != null) { + (collected.getOrCreate(Pair(target, accessKind)) { ArrayList() }) += it + } + } + val problems = ArrayList() + collected.forEach { (sort, matches) -> + if (sort.first is PsiNamedElement) { + if (matches.size > 1) { + for (match in matches) + problems += manager.createProblemDescriptor( + match, + "Duplicate entry for \"${sort.second} ${(sort.first as PsiNamedElement).name}\"", + RemoveElementQuickFix("Remove duplicate"), + ProblemHighlightType.WARNING, + isOnTheFly, + ) + } + } + } + return problems.toTypedArray() + } + + override fun runForWholeFile(): Boolean { + return true + } + + override fun getDisplayName(): String { + return "Duplicate AW entry" + } + + override fun getStaticDescription(): String { + return "Warns when the same element has its accessibility, mutability, " + + "or extensibility changed multiple times in one file." + } +} Index: src/main/kotlin/platform/mcp/ct/psi/CtElement.kt =================================================================== --- src/main/kotlin/platform/mcp/ct/psi/CtElement.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/kotlin/platform/mcp/ct/psi/CtElement.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,25 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mcp.ct.psi + +import com.intellij.psi.PsiElement + +interface CtElement : PsiElement Index: src/main/kotlin/platform/mcp/ct/psi/CtElementType.kt =================================================================== --- src/main/kotlin/platform/mcp/ct/psi/CtElementType.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/kotlin/platform/mcp/ct/psi/CtElementType.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,27 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mcp.ct.psi + +import com.demonwav.mcdev.platform.mcp.ct.CtLanguage +import com.intellij.psi.tree.IElementType +import org.jetbrains.annotations.NonNls + +class CtElementType(@NonNls debugName: String) : IElementType(debugName, CtLanguage) Index: src/main/kotlin/platform/mcp/ct/psi/CtTokenType.kt =================================================================== --- src/main/kotlin/platform/mcp/ct/psi/CtTokenType.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/kotlin/platform/mcp/ct/psi/CtTokenType.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,27 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mcp.ct.psi + +import com.demonwav.mcdev.platform.mcp.ct.CtLanguage +import com.intellij.psi.tree.IElementType +import org.jetbrains.annotations.NonNls + +class CtTokenType(@NonNls debugName: String) : IElementType(debugName, CtLanguage) Index: src/main/kotlin/platform/mcp/ct/psi/mixins/CtAwClassEntryMixin.kt =================================================================== --- src/main/kotlin/platform/mcp/ct/psi/mixins/CtAwClassEntryMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/kotlin/platform/mcp/ct/psi/mixins/CtAwClassEntryMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,23 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mcp.ct.psi.mixins + +interface CtAwClassEntryMixin : CtAwEntryMixin Index: src/main/kotlin/platform/mcp/ct/psi/mixins/CtAwClassNameMixin.kt =================================================================== --- src/main/kotlin/platform/mcp/ct/psi/mixins/CtAwClassNameMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/kotlin/platform/mcp/ct/psi/mixins/CtAwClassNameMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,26 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mcp.ct.psi.mixins + +import com.demonwav.mcdev.platform.mcp.ct.psi.CtElement +import com.intellij.psi.PsiReference + +interface CtAwClassNameMixin : CtElement, PsiReference Index: src/main/kotlin/platform/mcp/ct/psi/mixins/CtAwDescElementMixin.kt =================================================================== --- src/main/kotlin/platform/mcp/ct/psi/mixins/CtAwDescElementMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/kotlin/platform/mcp/ct/psi/mixins/CtAwDescElementMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,26 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mcp.ct.psi.mixins + +import com.demonwav.mcdev.platform.mcp.ct.psi.CtElement +import com.intellij.psi.PsiReference + +interface CtAwDescElementMixin : CtElement, PsiReference Index: src/main/kotlin/platform/mcp/ct/psi/mixins/CtAwEntryMixin.kt =================================================================== --- src/main/kotlin/platform/mcp/ct/psi/mixins/CtAwEntryMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/kotlin/platform/mcp/ct/psi/mixins/CtAwEntryMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,27 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mcp.ct.psi.mixins + +interface CtAwEntryMixin : CtEntryMixin { + + val accessKind: String? + val targetClassName: String? +} Index: src/main/kotlin/platform/mcp/ct/psi/mixins/CtAwFieldEntryMixin.kt =================================================================== --- src/main/kotlin/platform/mcp/ct/psi/mixins/CtAwFieldEntryMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/kotlin/platform/mcp/ct/psi/mixins/CtAwFieldEntryMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,27 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mcp.ct.psi.mixins + +interface CtAwFieldEntryMixin : CtAwEntryMixin { + + val fieldName: String? + val fieldDescriptor: String? +} Index: src/main/kotlin/platform/mcp/ct/psi/mixins/CtAwMemberNameMixin.kt =================================================================== --- src/main/kotlin/platform/mcp/ct/psi/mixins/CtAwMemberNameMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/kotlin/platform/mcp/ct/psi/mixins/CtAwMemberNameMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,26 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mcp.ct.psi.mixins + +import com.demonwav.mcdev.platform.mcp.ct.psi.CtElement +import com.intellij.psi.PsiReference + +interface CtAwMemberNameMixin : CtElement, PsiReference Index: src/main/kotlin/platform/mcp/ct/psi/mixins/CtAwMethodEntryMixin.kt =================================================================== --- src/main/kotlin/platform/mcp/ct/psi/mixins/CtAwMethodEntryMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/kotlin/platform/mcp/ct/psi/mixins/CtAwMethodEntryMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,27 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mcp.ct.psi.mixins + +interface CtAwMethodEntryMixin : CtAwEntryMixin { + + val methodName: String? + val methodDescriptor: String? +} Index: src/main/kotlin/platform/mcp/ct/psi/mixins/CtEntryMixin.kt =================================================================== --- src/main/kotlin/platform/mcp/ct/psi/mixins/CtEntryMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/kotlin/platform/mcp/ct/psi/mixins/CtEntryMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,26 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mcp.ct.psi.mixins + +import com.demonwav.mcdev.platform.mcp.ct.psi.CtElement + +interface CtEntryMixin : CtElement { +} Index: src/main/kotlin/platform/mcp/ct/psi/mixins/CtHeaderMixin.kt =================================================================== --- src/main/kotlin/platform/mcp/ct/psi/mixins/CtHeaderMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/kotlin/platform/mcp/ct/psi/mixins/CtHeaderMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,29 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mcp.ct.psi.mixins + +import com.demonwav.mcdev.platform.mcp.ct.psi.CtElement + +interface CtHeaderMixin : CtElement { + + val versionString: String? + val namespaceString: String? +} Index: src/main/kotlin/platform/mcp/ct/psi/mixins/CtItfEntryMixin.kt =================================================================== --- src/main/kotlin/platform/mcp/ct/psi/mixins/CtItfEntryMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/kotlin/platform/mcp/ct/psi/mixins/CtItfEntryMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,24 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mcp.ct.psi.mixins + +interface CtItfEntryMixin : CtEntryMixin { +} Index: src/main/kotlin/platform/mcp/ct/psi/mixins/impl/CtAwClassEntryImplMixin.kt =================================================================== --- src/main/kotlin/platform/mcp/ct/psi/mixins/impl/CtAwClassEntryImplMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/kotlin/platform/mcp/ct/psi/mixins/impl/CtAwClassEntryImplMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,26 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mcp.ct.psi.mixins.impl + +import com.demonwav.mcdev.platform.mcp.ct.psi.mixins.CtAwClassEntryMixin +import com.intellij.lang.ASTNode + +abstract class CtAwClassEntryImplMixin(node: ASTNode) : CtAwEntryImplMixin(node), CtAwClassEntryMixin Index: src/main/kotlin/platform/mcp/ct/psi/mixins/impl/CtAwClassNameImplMixin.kt =================================================================== --- src/main/kotlin/platform/mcp/ct/psi/mixins/impl/CtAwClassNameImplMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/kotlin/platform/mcp/ct/psi/mixins/impl/CtAwClassNameImplMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,62 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mcp.ct.psi.mixins.impl + +import com.demonwav.mcdev.platform.mcp.ct.psi.mixins.CtAwClassNameMixin +import com.demonwav.mcdev.util.cached +import com.demonwav.mcdev.util.findQualifiedClass +import com.intellij.extapi.psi.ASTWrapperPsiElement +import com.intellij.lang.ASTNode +import com.intellij.openapi.util.TextRange +import com.intellij.psi.PsiClass +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiReference +import com.intellij.psi.util.PsiModificationTracker +import com.intellij.util.IncorrectOperationException + +abstract class CtAwClassNameImplMixin(node: ASTNode) : ASTWrapperPsiElement(node), CtAwClassNameMixin { + + override fun getElement(): PsiElement = this + + override fun getReference(): PsiReference? = this + + override fun resolve(): PsiElement? { + return cached(PsiModificationTracker.MODIFICATION_COUNT) { findQualifiedClass(text.replace('/', '.'), this) } + } + + override fun getRangeInElement(): TextRange = TextRange(0, text.length) + + override fun getCanonicalText(): String = text + + override fun handleElementRename(newElementName: String): PsiElement { + throw IncorrectOperationException() + } + + override fun bindToElement(element: PsiElement): PsiElement { + throw IncorrectOperationException() + } + + override fun isReferenceTo(element: PsiElement): Boolean { + return element is PsiClass && element.qualifiedName == text.replace('/', '.') + } + + override fun isSoft(): Boolean = false +} Index: src/main/kotlin/platform/mcp/ct/psi/mixins/impl/CtAwDescElementImplMixin.kt =================================================================== --- src/main/kotlin/platform/mcp/ct/psi/mixins/impl/CtAwDescElementImplMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/kotlin/platform/mcp/ct/psi/mixins/impl/CtAwDescElementImplMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,70 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mcp.ct.psi.mixins.impl + +import com.demonwav.mcdev.platform.mcp.ct.psi.mixins.CtAwDescElementMixin +import com.demonwav.mcdev.util.cached +import com.demonwav.mcdev.util.findQualifiedClass +import com.intellij.extapi.psi.ASTWrapperPsiElement +import com.intellij.lang.ASTNode +import com.intellij.openapi.util.TextRange +import com.intellij.psi.PsiClass +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiReference +import com.intellij.psi.util.PsiModificationTracker +import com.intellij.util.IncorrectOperationException + +abstract class CtAwDescElementImplMixin(node: ASTNode) : ASTWrapperPsiElement(node), CtAwDescElementMixin { + + override fun getElement(): PsiElement = this + + override fun getReference(): PsiReference? = this + + override fun resolve(): PsiElement? = cached(PsiModificationTracker.MODIFICATION_COUNT) { + val name = asQualifiedName() ?: return@cached null + return@cached findQualifiedClass(name, this) + } + + override fun getRangeInElement(): TextRange = TextRange(0, text.length) + + override fun getCanonicalText(): String = text + + override fun handleElementRename(newElementName: String): PsiElement { + throw IncorrectOperationException() + } + + override fun bindToElement(element: PsiElement): PsiElement { + throw IncorrectOperationException() + } + + override fun isReferenceTo(element: PsiElement): Boolean { + return element is PsiClass && element.qualifiedName == asQualifiedName() + } + + private fun asQualifiedName(): String? = + if (text.length > 1) { + text.substring(1, text.length - 1).replace('/', '.') + } else { + null + } + + override fun isSoft(): Boolean = false +} Index: src/main/kotlin/platform/mcp/ct/psi/mixins/impl/CtAwEntryImplMixin.kt =================================================================== --- src/main/kotlin/platform/mcp/ct/psi/mixins/impl/CtAwEntryImplMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/kotlin/platform/mcp/ct/psi/mixins/impl/CtAwEntryImplMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,35 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mcp.ct.psi.mixins.impl + +import com.demonwav.mcdev.platform.mcp.ct.gen.psi.CtTypes +import com.demonwav.mcdev.platform.mcp.ct.psi.mixins.CtAwEntryMixin +import com.intellij.lang.ASTNode +import com.intellij.psi.PsiElement + +abstract class CtAwEntryImplMixin(node: ASTNode) : CtEntryImplMixin(node), CtAwEntryMixin { + + override val accessKind: String? + get() = findChildByType(CtTypes.ACCESS)?.text + + override val targetClassName: String? + get() = findChildByType(CtTypes.CLASS_NAME)?.text +} Index: src/main/kotlin/platform/mcp/ct/psi/mixins/impl/CtAwFieldEntryImplMixin.kt =================================================================== --- src/main/kotlin/platform/mcp/ct/psi/mixins/impl/CtAwFieldEntryImplMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/kotlin/platform/mcp/ct/psi/mixins/impl/CtAwFieldEntryImplMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,34 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mcp.ct.psi.mixins.impl + +import com.demonwav.mcdev.platform.mcp.ct.gen.psi.CtTypes +import com.demonwav.mcdev.platform.mcp.ct.psi.mixins.CtAwFieldEntryMixin +import com.intellij.lang.ASTNode +import com.intellij.psi.PsiElement + +abstract class CtAwFieldEntryImplMixin(node: ASTNode) : CtAwEntryImplMixin(node), CtAwFieldEntryMixin { + override val fieldName: String? + get() = findChildByType(CtTypes.MEMBER_NAME)?.text + + override val fieldDescriptor: String? + get() = findChildByType(CtTypes.FIELD_DESC)?.text +} Index: src/main/kotlin/platform/mcp/ct/psi/mixins/impl/CtAwMemberNameImplMixin.kt =================================================================== --- src/main/kotlin/platform/mcp/ct/psi/mixins/impl/CtAwMemberNameImplMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/kotlin/platform/mcp/ct/psi/mixins/impl/CtAwMemberNameImplMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,105 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mcp.ct.psi.mixins.impl + +import com.demonwav.mcdev.platform.mcp.ct.gen.psi.CtAwFieldEntry +import com.demonwav.mcdev.platform.mcp.ct.gen.psi.CtAwMethodEntry +import com.demonwav.mcdev.platform.mcp.ct.psi.mixins.CtAwEntryMixin +import com.demonwav.mcdev.platform.mcp.ct.psi.mixins.CtAwMemberNameMixin +import com.demonwav.mcdev.util.MemberReference +import com.demonwav.mcdev.util.cached +import com.intellij.codeInsight.completion.JavaLookupElementBuilder +import com.intellij.extapi.psi.ASTWrapperPsiElement +import com.intellij.lang.ASTNode +import com.intellij.openapi.util.TextRange +import com.intellij.psi.JavaPsiFacade +import com.intellij.psi.PsiClass +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiMethod +import com.intellij.psi.PsiReference +import com.intellij.psi.PsiSubstitutor +import com.intellij.psi.util.PsiModificationTracker +import com.intellij.psi.util.parentOfType +import com.intellij.util.ArrayUtil +import com.intellij.util.IncorrectOperationException +import com.intellij.util.containers.map2Array + +abstract class CtAwMemberNameImplMixin(node: ASTNode) : ASTWrapperPsiElement(node), CtAwMemberNameMixin { + + override fun getElement(): PsiElement = this + + override fun getReference(): PsiReference? = this + + override fun resolve(): PsiElement? = cached(PsiModificationTracker.MODIFICATION_COUNT) { + val entry = this.parentOfType() ?: return@cached null + val owner = entry.targetClassName?.replace('/', '.') + return@cached when (entry) { + is CtAwMethodEntry -> { + val name = entry.methodName ?: return@cached null + val desc = entry.methodDescriptor + MemberReference(name, desc, owner).resolveMember(project, resolveScope) + // fallback if descriptor is invalid + ?: MemberReference(name, null, owner).resolveMember(project, resolveScope) + } + is CtAwFieldEntry -> { + val name = entry.fieldName ?: return@cached null + MemberReference(name, null, owner) + .resolveMember(project, resolveScope) + } + else -> null + } + } + + override fun getVariants(): Array<*> { + val entry = this.parentOfType() ?: return ArrayUtil.EMPTY_OBJECT_ARRAY + val targetClassName = entry.targetClassName?.replace('/', '.')?.replace('$', '.') + ?: return ArrayUtil.EMPTY_OBJECT_ARRAY + val targetClass = JavaPsiFacade.getInstance(project)?.findClass(targetClassName, resolveScope) + ?: return ArrayUtil.EMPTY_OBJECT_ARRAY + + return when (entry) { + is CtAwMethodEntry -> targetClass.methods.map2Array(::methodLookupElement) + is CtAwFieldEntry -> targetClass.fields + else -> ArrayUtil.EMPTY_OBJECT_ARRAY + } + } + + private fun methodLookupElement(it: PsiMethod) = + JavaLookupElementBuilder.forMethod(it, if (it.isConstructor) "" else it.name, PsiSubstitutor.EMPTY, null) + + override fun getRangeInElement(): TextRange = TextRange(0, text.length) + + override fun getCanonicalText(): String = text + + override fun handleElementRename(newElementName: String): PsiElement { + throw IncorrectOperationException() + } + + override fun bindToElement(element: PsiElement): PsiElement { + throw IncorrectOperationException() + } + + override fun isReferenceTo(element: PsiElement): Boolean { + return element is PsiClass && element.qualifiedName == text.replace('/', '.') + } + + override fun isSoft(): Boolean = false +} Index: src/main/kotlin/platform/mcp/ct/psi/mixins/impl/CtAwMethodEntryImplMixin.kt =================================================================== --- src/main/kotlin/platform/mcp/ct/psi/mixins/impl/CtAwMethodEntryImplMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/kotlin/platform/mcp/ct/psi/mixins/impl/CtAwMethodEntryImplMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,34 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mcp.ct.psi.mixins.impl + +import com.demonwav.mcdev.platform.mcp.ct.gen.psi.CtTypes +import com.demonwav.mcdev.platform.mcp.ct.psi.mixins.CtAwMethodEntryMixin +import com.intellij.lang.ASTNode +import com.intellij.psi.PsiElement + +abstract class CtAwMethodEntryImplMixin(node: ASTNode) : CtAwEntryImplMixin(node), CtAwMethodEntryMixin { + override val methodName: String? + get() = findChildByType(CtTypes.MEMBER_NAME)?.text + + override val methodDescriptor: String? + get() = findChildByType(CtTypes.METHOD_DESC)?.text +} Index: src/main/kotlin/platform/mcp/ct/psi/mixins/impl/CtEntryImplMixin.kt =================================================================== --- src/main/kotlin/platform/mcp/ct/psi/mixins/impl/CtEntryImplMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/kotlin/platform/mcp/ct/psi/mixins/impl/CtEntryImplMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,28 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mcp.ct.psi.mixins.impl + +import com.demonwav.mcdev.platform.mcp.ct.psi.mixins.CtEntryMixin +import com.intellij.extapi.psi.ASTWrapperPsiElement +import com.intellij.lang.ASTNode + +abstract class CtEntryImplMixin(node: ASTNode) : ASTWrapperPsiElement(node), CtEntryMixin { +} Index: src/main/kotlin/platform/mcp/ct/psi/mixins/impl/CtHeaderImplMixin.kt =================================================================== --- src/main/kotlin/platform/mcp/ct/psi/mixins/impl/CtHeaderImplMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/kotlin/platform/mcp/ct/psi/mixins/impl/CtHeaderImplMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,36 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mcp.ct.psi.mixins.impl + +import com.demonwav.mcdev.platform.mcp.ct.gen.psi.CtTypes +import com.demonwav.mcdev.platform.mcp.ct.psi.mixins.CtHeaderMixin +import com.intellij.extapi.psi.ASTWrapperPsiElement +import com.intellij.lang.ASTNode +import com.intellij.psi.PsiElement + +abstract class CtHeaderImplMixin(node: ASTNode) : ASTWrapperPsiElement(node), CtHeaderMixin { + + override val versionString: String? + get() = findChildByType(CtTypes.HEADER_VERSION_ELEMENT)?.text + + override val namespaceString: String? + get() = findChildByType(CtTypes.HEADER_NAMESPACE_ELEMENT)?.text +} Index: src/main/kotlin/platform/mcp/ct/psi/mixins/impl/CtItfEntryImplMixin.kt =================================================================== --- src/main/kotlin/platform/mcp/ct/psi/mixins/impl/CtItfEntryImplMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) +++ src/main/kotlin/platform/mcp/ct/psi/mixins/impl/CtItfEntryImplMixin.kt (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -0,0 +1,27 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mcp.ct.psi.mixins.impl + +import com.demonwav.mcdev.platform.mcp.ct.psi.mixins.CtItfEntryMixin +import com.intellij.lang.ASTNode + +abstract class CtItfEntryImplMixin(node: ASTNode): CtEntryImplMixin(node), CtItfEntryMixin { +} Index: src/main/resources/META-INF/plugin.xml =================================================================== --- src/main/resources/META-INF/plugin.xml (revision 853854a2c3c85c5269fa671f16b0a7e6ddcfd6e7) +++ src/main/resources/META-INF/plugin.xml (revision 3b13b6633804b9109e472d7a56b180d42c6e3916) @@ -629,21 +629,21 @@ - - - - - - - - + + + + + + + + + implementation="com.demonwav.mcdev.platform.mcp.ct.fixes.CopyAwAccessibleEntryFix$Provider"/> @@ -1017,11 +1017,11 @@ implementationClass="com.demonwav.mcdev.platform.mcp.inspections.StackEmptyInspection"/> + implementationClass="com.demonwav.mcdev.platform.mcp.ct.inspections.DuplicateAwEntryInspection"/>