Added inspection for unresolved symbols, macros and labels.
This commit is contained in:
+48
@@ -0,0 +1,48 @@
|
||||
package de.platon42.intellij.plugins.m68k.inspections
|
||||
|
||||
import com.intellij.codeInspection.LocalInspectionToolSession
|
||||
import com.intellij.codeInspection.ProblemHighlightType
|
||||
import com.intellij.codeInspection.ProblemsHolder
|
||||
import com.intellij.psi.PsiElementVisitor
|
||||
import com.intellij.psi.PsiPolyVariantReference
|
||||
import de.platon42.intellij.plugins.m68k.psi.M68kMacroCall
|
||||
import de.platon42.intellij.plugins.m68k.psi.M68kSymbolReference
|
||||
import de.platon42.intellij.plugins.m68k.psi.M68kVisitor
|
||||
import de.platon42.intellij.plugins.m68k.refs.M68kGlobalLabelSymbolReference
|
||||
|
||||
class M68kUnresolvedReferenceInspection : AbstractBaseM68kLocalInspectionTool() {
|
||||
|
||||
companion object {
|
||||
private const val DISPLAY_NAME = "Unresolved label/symbol/macro reference"
|
||||
}
|
||||
|
||||
override fun getDisplayName() = DISPLAY_NAME
|
||||
|
||||
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor {
|
||||
return object : M68kVisitor() {
|
||||
override fun visitMacroCall(macroCall: M68kMacroCall) {
|
||||
val reference = macroCall.reference as? PsiPolyVariantReference ?: return
|
||||
val resolve = reference.multiResolve(false)
|
||||
if (resolve.isEmpty()) {
|
||||
holder.registerProblem(reference)
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitSymbolReference(symbolReference: M68kSymbolReference) {
|
||||
val references = symbolReference.references ?: return
|
||||
if (references.isEmpty()) return
|
||||
val resolve = references.mapNotNull { it as? PsiPolyVariantReference }
|
||||
.firstNotNullOfOrNull { it.multiResolve(false).ifEmpty { null } }
|
||||
if (resolve == null) {
|
||||
// TODO currently, because macro invocations are not evaluated, mark missing symbols only as weak warning
|
||||
val makeWeak = references.any { it is M68kGlobalLabelSymbolReference }
|
||||
if (makeWeak) {
|
||||
holder.registerProblem(references.first(), ProblemHighlightType.WEAK_WARNING)
|
||||
} else {
|
||||
holder.registerProblem(references.first())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,10 @@ import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry
|
||||
|
||||
abstract class M68kMacroCallMixin(node: ASTNode) : ASTWrapperPsiElement(node), M68kMacroCall {
|
||||
|
||||
override fun getReference(): PsiReference? {
|
||||
return references.firstOrNull()
|
||||
}
|
||||
|
||||
override fun getReferences(): Array<PsiReference> {
|
||||
return ReferenceProvidersRegistry.getReferencesFromProviders(this)
|
||||
}
|
||||
|
||||
@@ -7,6 +7,10 @@ import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry
|
||||
|
||||
abstract class M68kPreprocessorDirectiveMixin(node: ASTNode) : ASTWrapperPsiElement(node), M68kPreprocessorDirective {
|
||||
|
||||
override fun getReference(): PsiReference? {
|
||||
return references.firstOrNull()
|
||||
}
|
||||
|
||||
override fun getReferences(): Array<PsiReference> {
|
||||
return ReferenceProvidersRegistry.getReferencesFromProviders(this)
|
||||
}
|
||||
|
||||
@@ -7,6 +7,10 @@ import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry
|
||||
|
||||
abstract class M68kSymbolReferenceMixin(node: ASTNode) : ASTWrapperPsiElement(node), M68kSymbolReference {
|
||||
|
||||
override fun getReference(): PsiReference? {
|
||||
return references.firstOrNull()
|
||||
}
|
||||
|
||||
override fun getReferences(): Array<PsiReference> {
|
||||
return ReferenceProvidersRegistry.getReferencesFromProviders(this)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package de.platon42.intellij.plugins.m68k.refs
|
||||
|
||||
import com.intellij.codeInsight.daemon.EmptyResolveMessageProvider
|
||||
import com.intellij.codeInsight.lookup.LookupElementBuilder
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.PsiElement
|
||||
@@ -14,11 +15,15 @@ import de.platon42.intellij.plugins.m68k.psi.M68kLocalLabel
|
||||
import de.platon42.intellij.plugins.m68k.psi.M68kStatement
|
||||
import de.platon42.intellij.plugins.m68k.psi.M68kSymbolReference
|
||||
|
||||
class M68kLocalLabelReference(element: M68kSymbolReference) : PsiPolyVariantReferenceBase<M68kSymbolReference>(element, TextRange(0, element.textLength)) {
|
||||
class M68kLocalLabelReference(element: M68kSymbolReference) :
|
||||
PsiPolyVariantReferenceBase<M68kSymbolReference>(element, TextRange(0, element.textLength)),
|
||||
EmptyResolveMessageProvider {
|
||||
|
||||
companion object {
|
||||
val INSTANCE = Resolver()
|
||||
|
||||
private const val UNRESOLVED_MESSAGE_PATTERN = "Cannot resolve local label ''{0}''"
|
||||
|
||||
fun findLocalLabels(element: M68kSymbolReference, predicate: (M68kLocalLabel) -> Boolean): List<M68kLocalLabel> {
|
||||
val statement = PsiTreeUtil.getStubOrPsiParentOfType(element, M68kStatement::class.java)!!
|
||||
val results = SmartList<M68kLocalLabel>()
|
||||
@@ -42,6 +47,8 @@ class M68kLocalLabelReference(element: M68kSymbolReference) : PsiPolyVariantRefe
|
||||
}
|
||||
}
|
||||
|
||||
override fun getUnresolvedMessagePattern() = UNRESOLVED_MESSAGE_PATTERN
|
||||
|
||||
class Resolver : ResolveCache.PolyVariantResolver<M68kLocalLabelReference> {
|
||||
override fun resolve(ref: M68kLocalLabelReference, incompleteCode: Boolean): Array<ResolveResult> {
|
||||
val refName = ref.element.symbolName
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package de.platon42.intellij.plugins.m68k.refs
|
||||
|
||||
import com.intellij.codeInsight.daemon.EmptyResolveMessageProvider
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiElementResolveResult
|
||||
@@ -14,12 +15,16 @@ import de.platon42.intellij.plugins.m68k.psi.M68kMacroDefinition
|
||||
import de.platon42.intellij.plugins.m68k.stubs.M68kMacroDefinitionStubIndex
|
||||
|
||||
class M68kMacroReference(element: M68kMacroCall) :
|
||||
PsiPolyVariantReferenceBase<M68kMacroCall>(element, TextRange(0, element.macroName.length)) {
|
||||
PsiPolyVariantReferenceBase<M68kMacroCall>(element, TextRange(0, element.macroName.length)), EmptyResolveMessageProvider {
|
||||
|
||||
companion object {
|
||||
val INSTANCE = Resolver()
|
||||
|
||||
private const val UNRESOLVED_MESSAGE_PATTERN = "Cannot resolve macro ''{0}''"
|
||||
}
|
||||
|
||||
override fun getUnresolvedMessagePattern() = UNRESOLVED_MESSAGE_PATTERN
|
||||
|
||||
class Resolver : ResolveCache.PolyVariantResolver<M68kMacroReference> {
|
||||
override fun resolve(ref: M68kMacroReference, incompleteCode: Boolean): Array<ResolveResult> {
|
||||
val macroName = ref.element.macroName
|
||||
|
||||
@@ -61,6 +61,9 @@
|
||||
<localInspection implementationClass="de.platon42.intellij.plugins.m68k.inspections.M68kUnexpectedConditionalInstructionInspection"
|
||||
displayName="Unaffected condition codes before conditional instruction" groupName="M68k"
|
||||
enabledByDefault="true" level="WARNING"/>
|
||||
<localInspection implementationClass="de.platon42.intellij.plugins.m68k.inspections.M68kUnresolvedReferenceInspection"
|
||||
displayName="Unresolved label/symbol/macro reference" groupName="M68k"
|
||||
enabledByDefault="true" level="WARNING"/>
|
||||
</extensions>
|
||||
|
||||
<actions>
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<html>
|
||||
<body>
|
||||
Checks if references to symbols, macros, global and local labels are resolvable.
|
||||
<!-- tooltip end -->
|
||||
<p>Currently, issues a weak warning for global labels or symbols as those
|
||||
can be defined via macros, which are not evaluated right now</p>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user