override fun annotate()

in gdscript/src/main/kotlin/gdscript/annotator/GdRefIdAnnotator.kt [32:137]


    override fun annotate(element: PsiElement, holder: AnnotationHolder) {
        val state = GdProjectSettingsState.getInstance(element).state.annotators
        if (element !is GdRefIdRef) return
        val txt = element.text

        if (txt == GdKeywords.SELF || txt == GdKeywords.SUPER) return
        if (GdKeywords.MATH_CONSTANTS.contains(txt)) {
            holder
                .newSilentAnnotation(HighlightSeverity.INFORMATION)
                .range(element.textRange)
                .textAttributes(GdHighlighterColors.KEYWORD)
                .create()
            return
        }

        var attribute = GdHighlighterColors.METHOD_CALL
        val reference = element.references.firstOrNull()
        if (reference?.isSoft == false && reference is GdClassMemberReference) {
            attribute = when (val resolved = reference.resolveDeclaration()) {
                is GdMethodDeclTl -> {
                    if (resolved.containingFile.name.endsWith("GlobalScope.gd")) GdHighlighterColors.GLOBAL_FUNCTION
                    else if (resolved.isStatic) GdHighlighterColors.STATIC_METHOD_CALL
                    else GdHighlighterColors.METHOD_CALL
                }

                is PsiFile, is GdClassDeclTl, is GdClassNaming -> {
                    var psi = resolved
                    if (resolved is GdClassNaming) {
                        psi = psi.parent!!
                    }

                    if (psi.containingFile.isInSdk()) {
                        val nextLeaf = element.nextLeaf(true)
                        if (!objectContinuation.contains(nextLeaf.elementType) && psi.childrenOfType<GdMethodDeclTl>()
                                .any { it.isConstructor }
                        ) {
                            holder
                                .newAnnotationGd(
                                    element.project,
                                    HighlightSeverity.ERROR,
                                    GdScriptBundle.message("annotator.builtin.type.cannot.be.assigned.to.a.variable", txt)
                                )
                                .range(element.textRange)
                                .create()
                            return
                        }
                        GdHighlighterColors.ENGINE_TYPE
                    } else GdHighlighterColors.CLASS_TYPE
                }

                null -> run {
                    if (element.text == "new"
                        || GdClassMemberUtil.calledUpon(element)?.returnType == "Dictionary"
                    ) {
                        return@run GdHighlighterColors.MEMBER
                    }

                    val calledUponExpr = GdClassMemberUtil.calledUpon(element)
                    // For undefined types do not mark it as error
                    if (calledUponExpr != null) {
                        // If qualifier is a node path, skip error
                        if (PsiTreeUtil.findChildOfType(calledUponExpr, GdNodePath::class.java) != null)
                            return@run GdHighlighterColors.MEMBER

                        // If qualifier resolves to a named enum, allow enum member access only for existing enum values
                        run {
                            val decl = GdClassMemberUtil.findDeclaration(calledUponExpr)
                            if (decl is GdEnumDeclTl) {
                                val name = element.text
                                val isMember = decl.enumValueList.any { it.enumValueNmi.name == name }
                                if (isMember) return@run GdHighlighterColors.MEMBER
                                // otherwise, fall through to unresolved reference error
                            }
                        }

                        val callType = calledUponExpr.returnType
                        if (callType in unresolvedTolerantTypes)
                            return@run GdHighlighterColors.MEMBER
                    }

                    if (element.getCallExpr() != null && GdClassMemberUtil.hasMethodCheck(element))
                        return@run GdHighlighterColors.METHOD_CALL

                    holder
                        .newAnnotationGd(element.project, GdProjectState.selectedLevel(state),
                            GdScriptBundle.message("annotator.message.reference.not.found", element.text)
                        )
                        .range(element.textRange)
                        .create()
                    return
                }

                else -> GdHighlighterColors.MEMBER
            }
        }

        if (attribute == GdHighlighterColors.MEMBER && element.getCallExpr() != null) {
            attribute = GdHighlighterColors.METHOD_CALL
        }

        holder
            .newSilentAnnotation(HighlightSeverity.INFORMATION)
            .range(element.textRange)
            .textAttributes(attribute)
            .create()
    }