Search in sources :

Example 1 with GoReference

use of com.goide.psi.impl.GoReference in project go-lang-idea-plugin by go-lang-plugin-org.

the class GoUnresolvedReferenceInspection method buildGoVisitor.

@NotNull
@Override
protected GoVisitor buildGoVisitor(@NotNull ProblemsHolder holder, @NotNull LocalInspectionToolSession session) {
    return new GoVisitor() {

        @Override
        public void visitFieldName(@NotNull GoFieldName o) {
            super.visitFieldName(o);
            PsiElement resolve = o.resolve();
            if (resolve == null) {
                PsiElement id = o.getIdentifier();
                holder.registerProblem(id, "Unknown field <code>#ref</code> in struct literal #loc", LIKE_UNKNOWN_SYMBOL);
            }
        }

        @Override
        public void visitReferenceExpression(@NotNull GoReferenceExpression o) {
            super.visitReferenceExpression(o);
            GoReference reference = o.getReference();
            GoReferenceExpression qualifier = o.getQualifier();
            GoReference qualifierRef = qualifier != null ? qualifier.getReference() : null;
            PsiElement qualifierResolve = qualifierRef != null ? qualifierRef.resolve() : null;
            if (qualifier != null && qualifierResolve == null)
                return;
            ResolveResult[] results = reference.multiResolve(false);
            PsiElement id = o.getIdentifier();
            String name = id.getText();
            if (results.length > 1) {
                holder.registerProblem(id, "Ambiguous reference " + "'" + name + "'", GENERIC_ERROR_OR_WARNING);
            } else if (reference.resolve() == null) {
                LocalQuickFix[] fixes = LocalQuickFix.EMPTY_ARRAY;
                if (isProhibited(o, qualifier)) {
                    fixes = createImportPackageFixes(o, reference, holder.isOnTheFly());
                } else if (holder.isOnTheFly()) {
                    boolean canBeLocal = PsiTreeUtil.getParentOfType(o, GoBlock.class) != null;
                    List<LocalQuickFix> fixesList = ContainerUtil.newArrayList(new GoIntroduceGlobalVariableFix(id, name));
                    if (canBeLocal) {
                        fixesList.add(new GoIntroduceLocalVariableFix(id, name));
                    }
                    PsiElement parent = o.getParent();
                    if (o.getReadWriteAccess() == ReadWriteAccessDetector.Access.Read) {
                        fixesList.add(new GoIntroduceGlobalConstantFix(id, name));
                        if (canBeLocal) {
                            fixesList.add(new GoIntroduceLocalConstantFix(id, name));
                        }
                    } else if (canBeLocal) {
                        PsiElement grandParent = parent.getParent();
                        if (grandParent instanceof GoAssignmentStatement) {
                            fixesList.add(new GoReplaceAssignmentWithDeclarationQuickFix(grandParent));
                        } else if (parent instanceof GoRangeClause || parent instanceof GoRecvStatement) {
                            fixesList.add(new GoReplaceAssignmentWithDeclarationQuickFix(parent));
                        }
                    }
                    if (parent instanceof GoCallExpr && PsiTreeUtil.getParentOfType(o, GoConstDeclaration.class) == null) {
                        fixesList.add(new GoIntroduceFunctionFix(parent, name));
                    }
                    fixes = fixesList.toArray(new LocalQuickFix[fixesList.size()]);
                }
                holder.registerProblem(id, "Unresolved reference " + "'" + name + "'", LIKE_UNKNOWN_SYMBOL, fixes);
            }
        }

        @Override
        public void visitImportSpec(@NotNull GoImportSpec o) {
            if (o.isCImport())
                return;
            GoImportString string = o.getImportString();
            if (string.getTextLength() < 2)
                return;
            PsiReference[] references = string.getReferences();
            for (PsiReference reference : references) {
                if (reference instanceof FileReference) {
                    ResolveResult[] resolveResults = ((FileReference) reference).multiResolve(false);
                    if (resolveResults.length == 0) {
                        ProblemHighlightType type = reference.getRangeInElement().isEmpty() ? GENERIC_ERROR_OR_WARNING : LIKE_UNKNOWN_SYMBOL;
                        holder.registerProblem(reference, ProblemsHolder.unresolvedReferenceMessage(reference), type);
                    }
                }
            }
        }

        @Override
        public void visitLabelRef(@NotNull GoLabelRef o) {
            PsiReference reference = o.getReference();
            String name = o.getText();
            if (reference.resolve() == null) {
                holder.registerProblem(o, "Unresolved label " + "'" + name + "'", LIKE_UNKNOWN_SYMBOL);
            }
        }

        @Override
        public void visitTypeReferenceExpression(@NotNull GoTypeReferenceExpression o) {
            super.visitTypeReferenceExpression(o);
            PsiReference reference = o.getReference();
            GoTypeReferenceExpression qualifier = o.getQualifier();
            PsiElement qualifierResolve = qualifier != null ? qualifier.resolve() : null;
            if (qualifier != null && qualifierResolve == null)
                return;
            if (reference.resolve() == null) {
                PsiElement id = o.getIdentifier();
                String name = id.getText();
                boolean isProhibited = isProhibited(o, qualifier);
                LocalQuickFix[] fixes = LocalQuickFix.EMPTY_ARRAY;
                if (isProhibited) {
                    fixes = createImportPackageFixes(o, reference, holder.isOnTheFly());
                } else if (holder.isOnTheFly()) {
                    fixes = new LocalQuickFix[] { new GoIntroduceTypeFix(id, name) };
                }
                holder.registerProblem(id, "Unresolved type " + "'" + name + "'", LIKE_UNKNOWN_SYMBOL, fixes);
            }
        }
    };
}
Also used : LocalQuickFix(com.intellij.codeInspection.LocalQuickFix) NotNull(org.jetbrains.annotations.NotNull) ResolveResult(com.intellij.psi.ResolveResult) PsiElement(com.intellij.psi.PsiElement) PsiReference(com.intellij.psi.PsiReference) GoReference(com.goide.psi.impl.GoReference) FileReference(com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReference) ProblemHighlightType(com.intellij.codeInspection.ProblemHighlightType) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

GoReference (com.goide.psi.impl.GoReference)1 LocalQuickFix (com.intellij.codeInspection.LocalQuickFix)1 ProblemHighlightType (com.intellij.codeInspection.ProblemHighlightType)1 PsiElement (com.intellij.psi.PsiElement)1 PsiReference (com.intellij.psi.PsiReference)1 ResolveResult (com.intellij.psi.ResolveResult)1 FileReference (com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReference)1 NotNull (org.jetbrains.annotations.NotNull)1