Skip to content

impr: Better AccessWidener #2483

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/main/grammars/AwParser.bnf
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,12 @@ class_entry ::= access class_literal class_name {
implements="com.demonwav.mcdev.platform.mcp.aw.psi.mixins.AwClassEntryMixin"
}

method_entry ::= access method_literal class_name member_name method_desc{
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{
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"
}
Expand Down
29 changes: 29 additions & 0 deletions src/main/kotlin/platform/mcp/aw/AwAnnotator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,26 @@

package com.demonwav.mcdev.platform.mcp.aw

import com.demonwav.mcdev.asset.MCDevBundle
import com.demonwav.mcdev.platform.mcp.aw.config.IgnoredClassNamesConfig
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.AwClassName
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.platform.mcp.aw.quickfix.IgnoreClassWarningFix
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.openapi.project.DumbService
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiWhiteSpace
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.util.PsiTreeUtil

class AwAnnotator : Annotator {
Expand All @@ -56,6 +63,28 @@ class AwAnnotator : Annotator {
if (!compatibleByTargetMap.get(target).contains(access)) {
holder.newAnnotation(HighlightSeverity.ERROR, "'$target' cannot be used with '$access'").create()
}
} else if (element is AwClassName) {
val project = element.project

if (DumbService.isDumb(project)) {
return
}

val javaPsiFacade = JavaPsiFacade.getInstance(project)
val scope = GlobalSearchScope.allScope(project)

val classFqn = element.text.replace('/', '.')
val psiClass = javaPsiFacade.findClass(classFqn, scope)

val config = IgnoredClassNamesConfig.getInstance(project)
val ignored = config.ignoredClassNames

if (classFqn !in ignored && psiClass == null) {
holder.newAnnotation(HighlightSeverity.WARNING, MCDevBundle("inspection.aw.class_not_found", classFqn))
.range(element.textRange)
.withFix(IgnoreClassWarningFix(classFqn, element))
.create()
}
}
}

Expand Down
32 changes: 32 additions & 0 deletions src/main/kotlin/platform/mcp/aw/config/IgnoredClassNamesConfig.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.demonwav.mcdev.platform.mcp.aw.config

import com.intellij.openapi.components.PersistentStateComponent
import com.intellij.openapi.components.Service
import com.intellij.openapi.components.State
import com.intellij.openapi.components.Storage
import com.intellij.openapi.project.Project

@Service(Service.Level.PROJECT)
@State(name = "IgnoredClassNamesConfig", storages = [Storage("ignoredClassNames.xml")])
class IgnoredClassNamesConfig : PersistentStateComponent<IgnoredClassNamesConfig.State> {

data class State(var ignoredClassNames: MutableSet<String> = mutableSetOf())

private var state = State()

companion object {
fun getInstance(project: Project): IgnoredClassNamesConfig =
project.getService(IgnoredClassNamesConfig::class.java)
}

var ignoredClassNames: MutableSet<String>
get() = state.ignoredClassNames
set(value) {
state.ignoredClassNames = value
}

override fun getState(): State = state
override fun loadState(state: State) {
this.state = state
}
}
38 changes: 38 additions & 0 deletions src/main/kotlin/platform/mcp/aw/quickfix/IgnoreClassWarningFix.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.demonwav.mcdev.platform.mcp.aw.quickfix

import com.demonwav.mcdev.platform.mcp.aw.config.IgnoredClassNamesConfig
import com.demonwav.mcdev.platform.mcp.aw.gen.psi.AwClassName
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer
import com.intellij.codeInsight.intention.IntentionAction
import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.LocalQuickFixOnPsiElement
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.codeInspection.util.IntentionFamilyName
import com.intellij.codeInspection.util.IntentionName
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import org.jetbrains.annotations.Nls

class IgnoreClassWarningFix(private val className: String, private val element: PsiElement) : IntentionAction {

override fun getText() = "Ignore warnings for '$className'"

override fun getFamilyName() = "Ignore warnings"

override fun isAvailable(project: Project, editor: Editor?, file: PsiFile?): Boolean = element.isValid

override fun invoke(project: Project, editor: Editor?, file: PsiFile?) {
val config = IgnoredClassNamesConfig.getInstance(project)
val ignored = config.ignoredClassNames.toMutableSet()
ignored.add(className)
config.ignoredClassNames = ignored

file?.let {
DaemonCodeAnalyzer.getInstance(project).restart(it)
}
}

override fun startInWriteAction(): Boolean = false
}
2 changes: 2 additions & 0 deletions src/main/resources/messages/MinecraftDevelopment.properties
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,8 @@ inspection.entity_data_param.description=Reports when the class passed to an ent
inspection.entity_data_param.message=Entity class does not match this entity class
inspection.entity_data_param.fix=Replace other entity class with this entity class

inspection.aw.class_not_found=Class "{0}" not found in the project or libraries. Please make sure the class name is correct and the relevant module dependencies are set.

nbt.compression.gzip=GZipped
nbt.compression.uncompressed=Uncompressed
nbt.compression.file_type.label=Compression:
Expand Down
Loading