Search in sources :

Example 1 with PackageNameReference

use of org.ballerinalang.plugins.idea.psi.references.PackageNameReference in project ballerina by ballerina-lang.

the class IdentifierPSINode method getReference.

/**
 * Create and return a PsiReference object associated with this ID
 * node. The reference object will be asked to resolve this ref
 * by using the text of this node to identify the appropriate definition
 * site. The definition site is typically a subtree for a function
 * or variable definition whereas this reference is just to this ID
 * leaf node.
 * <p>
 * As the AST factory has no context and cannot create different kinds
 * of PsiNamedElement nodes according to context, every ID node
 * in the tree will be of this type. So, we distinguish references
 * from definitions or other uses by looking at context in this method
 * as we have parent (context) information.
 */
@Override
public PsiReference getReference() {
    PsiElement parent = getParent();
    IElementType elType = parent.getNode().getElementType();
    PsiElement prevVisibleLeaf;
    // do not return a reference for the ID nodes in a definition
    if (elType instanceof RuleIElementType) {
        XmlAttribNode xmlAttribNode = PsiTreeUtil.getParentOfType(parent, XmlAttribNode.class);
        switch(((RuleIElementType) elType).getRuleIndex()) {
            case RULE_packageName:
                if (xmlAttribNode != null) {
                    return new NameSpaceReference(this);
                }
                AliasNode aliasNode = PsiTreeUtil.getParentOfType(parent, AliasNode.class);
                if (aliasNode != null) {
                    return null;
                }
                return new PackageNameReference(this);
            case RULE_nameReference:
                // If we are currently resolving a var variable, we don't need to resolve it since it is the
                // definition.
                PsiElement element = getPsi();
                if (element instanceof IdentifierPSINode) {
                    AssignmentStatementNode assignmentStatementNode = PsiTreeUtil.getParentOfType(element, AssignmentStatementNode.class);
                    if (assignmentStatementNode != null && BallerinaPsiImplUtil.isVarAssignmentStatement(assignmentStatementNode)) {
                        IdentifierPSINode identifier = (IdentifierPSINode) element;
                        if (BallerinaPsiImplUtil.isRedeclaredVar(identifier)) {
                            return new NameReference(this);
                        }
                        if (BallerinaPsiImplUtil.isValidVarVariable(assignmentStatementNode, identifier)) {
                            return null;
                        }
                    }
                }
                if (xmlAttribNode != null) {
                    return new NameSpaceReference(this);
                }
                RecordKeyNode recordKeyNode = PsiTreeUtil.getParentOfType(parent, RecordKeyNode.class);
                if (recordKeyNode != null) {
                    return new RecordKeyReference(this);
                }
                RecordValueNode recordValueNode = PsiTreeUtil.getParentOfType(parent, RecordValueNode.class);
                if (recordValueNode != null) {
                    return new RecordValueReference(this);
                }
                prevVisibleLeaf = PsiTreeUtil.prevVisibleLeaf(parent);
                if (prevVisibleLeaf != null) {
                    if (".".equals(prevVisibleLeaf.getText())) {
                        // Todo - update logic
                        PsiReference reference = checkAndSuggestReferenceAfterDot();
                        if (reference != null) {
                            return reference;
                        }
                        return new FieldReference(this);
                    }
                    // Todo - remove ","
                    if ((prevVisibleLeaf instanceof IdentifierPSINode) && prevVisibleLeaf.getParent() instanceof AnnotationDefinitionNode) {
                        return null;
                    } else if (("attach".equals(prevVisibleLeaf.getText()) || ",".equals(prevVisibleLeaf.getText())) && prevVisibleLeaf.getParent() instanceof AnnotationDefinitionNode) {
                        return new AttachmentPointReference(this);
                    }
                }
                return new NameReference(this);
            case RULE_field:
                prevVisibleLeaf = PsiTreeUtil.prevVisibleLeaf(parent);
                PsiReference variableReference = null;
                if (prevVisibleLeaf != null && ".".equals(prevVisibleLeaf.getText())) {
                    PsiElement connectorVariable = PsiTreeUtil.prevVisibleLeaf(prevVisibleLeaf);
                    if (connectorVariable != null) {
                        variableReference = connectorVariable.findReferenceAt(connectorVariable.getTextLength());
                    }
                } else {
                    PsiElement prevSibling = parent.getPrevSibling();
                    if (prevSibling != null) {
                        PsiReference reference = checkAndSuggestReferenceAfterDot();
                        if (reference != null) {
                            return reference;
                        }
                        return new FieldReference(this);
                    }
                }
                if (variableReference == null) {
                    return null;
                }
                PsiElement variableDefinition = variableReference.resolve();
                if (variableDefinition == null) {
                    return new FieldReference(this);
                }
                ConnectorDefinitionNode connectorDefinitionNode = BallerinaPsiImplUtil.resolveConnectorFromVariableDefinitionNode(variableDefinition.getParent());
                if (connectorDefinitionNode != null) {
                    return new ActionInvocationReference(this);
                }
                return new FieldReference(this);
            case RULE_functionReference:
                return new FunctionReference(this);
            case RULE_workerReference:
                return new WorkerReference(this);
            case RULE_attachmentPoint:
                return new AttachmentPointReference(this);
            case RULE_statement:
                // Todo - update logic
                PsiReference reference = checkAndSuggestReferenceAfterDot();
                if (reference != null) {
                    return reference;
                }
                prevVisibleLeaf = PsiTreeUtil.prevVisibleLeaf(getParent());
                if (prevVisibleLeaf != null) {
                    if (".".equals(prevVisibleLeaf.getText())) {
                        PsiElement psiElement = PsiTreeUtil.prevVisibleLeaf(prevVisibleLeaf);
                        if (psiElement == null) {
                            return new FieldReference(this);
                        }
                        reference = psiElement.findReferenceAt(psiElement.getTextLength());
                        if (reference == null) {
                            return new FieldReference(this);
                        }
                        PsiElement resolvedElement = reference.resolve();
                        if (resolvedElement == null) {
                            return new FieldReference(this);
                        }
                        PsiElement resolvedElementParent = resolvedElement.getParent();
                        if (resolvedElementParent instanceof ConnectorDefinitionNode) {
                            return new ActionInvocationReference(this);
                        }
                        if (resolvedElementParent instanceof VariableDefinitionNode) {
                            connectorDefinitionNode = BallerinaPsiImplUtil.resolveConnectorFromVariableDefinitionNode((resolvedElementParent));
                            if (connectorDefinitionNode != null) {
                                return new ActionInvocationReference(this);
                            }
                        }
                        return new FieldReference(this);
                    } else if (prevVisibleLeaf.getText().matches("[,]")) {
                        return new NameReference(this);
                    } else if (prevVisibleLeaf.getText().matches("[{]")) {
                        return new RecordKeyReference(this);
                    }
                }
                PsiElement nextVisibleLeaf = PsiTreeUtil.nextVisibleLeaf(getPsi());
                if (nextVisibleLeaf != null && ":".equals(nextVisibleLeaf.getText())) {
                    return new PackageNameReference(this);
                }
                return new StatementReference(this);
            case RULE_invocation:
                return suggestReferenceTypeForInvocation();
            case RULE_structReference:
                return new StructReference(this);
            case RULE_transformerReference:
                return new TransformerReference(this);
            case RULE_recordKey:
                return new RecordKeyReference(this);
            case RULE_anyIdentifierName:
                return suggestReferenceTypeForInvocation();
            // return new DocVariableReference(this);
            default:
                return null;
        }
    }
    if (parent instanceof PsiErrorElement) {
        return suggestReferenceType(parent);
    }
    return null;
}
Also used : TransformerReference(org.ballerinalang.plugins.idea.psi.references.TransformerReference) PackageNameReference(org.ballerinalang.plugins.idea.psi.references.PackageNameReference) NameReference(org.ballerinalang.plugins.idea.psi.references.NameReference) PackageNameReference(org.ballerinalang.plugins.idea.psi.references.PackageNameReference) StatementReference(org.ballerinalang.plugins.idea.psi.references.StatementReference) NameSpaceReference(org.ballerinalang.plugins.idea.psi.references.NameSpaceReference) FunctionReference(org.ballerinalang.plugins.idea.psi.references.FunctionReference) RecordValueReference(org.ballerinalang.plugins.idea.psi.references.RecordValueReference) WorkerReference(org.ballerinalang.plugins.idea.psi.references.WorkerReference) PsiElement(com.intellij.psi.PsiElement) FieldReference(org.ballerinalang.plugins.idea.psi.references.FieldReference) EnumFieldReference(org.ballerinalang.plugins.idea.psi.references.EnumFieldReference) StructReference(org.ballerinalang.plugins.idea.psi.references.StructReference) ActionInvocationReference(org.ballerinalang.plugins.idea.psi.references.ActionInvocationReference) RuleIElementType(org.antlr.jetbrains.adaptor.lexer.RuleIElementType) PsiReference(com.intellij.psi.PsiReference) IElementType(com.intellij.psi.tree.IElementType) RuleIElementType(org.antlr.jetbrains.adaptor.lexer.RuleIElementType) PsiErrorElement(com.intellij.psi.PsiErrorElement) AttachmentPointReference(org.ballerinalang.plugins.idea.psi.references.AttachmentPointReference) RecordKeyReference(org.ballerinalang.plugins.idea.psi.references.RecordKeyReference)

Example 2 with PackageNameReference

use of org.ballerinalang.plugins.idea.psi.references.PackageNameReference in project ballerina by ballerina-lang.

the class BallerinaUnresolvedReferenceInspection method checkFile.

@Override
@Nullable
public ProblemDescriptor[] checkFile(@NotNull PsiFile file, @NotNull InspectionManager manager, boolean isOnTheFly) {
    // does not work in tests since CodeInsightTestCase copies file into temporary location
    if (ApplicationManager.getApplication().isUnitTestMode()) {
        return new ProblemDescriptor[0];
    }
    if (!(file instanceof BallerinaFile)) {
        return new ProblemDescriptor[0];
    }
    List<ProblemDescriptor> problemDescriptors = new LinkedList<>();
    Collection<PackageNameNode> packageNameNodes = PsiTreeUtil.findChildrenOfType(file, PackageNameNode.class);
    for (PackageNameNode packageNameNode : packageNameNodes) {
        ProgressManager.checkCanceled();
        if (packageNameNode == null) {
            continue;
        }
        AliasNode aliasNode = PsiTreeUtil.getParentOfType(packageNameNode, AliasNode.class);
        if (aliasNode != null) {
            continue;
        }
        PackageDeclarationNode packageDeclarationNode = PsiTreeUtil.getParentOfType(packageNameNode, PackageDeclarationNode.class);
        if (packageDeclarationNode != null) {
            continue;
        }
        XmlAttribNode xmlAttribNode = PsiTreeUtil.getParentOfType(packageNameNode, XmlAttribNode.class);
        if (xmlAttribNode != null) {
            continue;
        }
        LocalQuickFix[] availableFixes;
        ImportDeclarationNode importDeclarationNode = PsiTreeUtil.getParentOfType(packageNameNode, ImportDeclarationNode.class);
        if (importDeclarationNode != null) {
            availableFixes = new LocalQuickFix[0];
        } else {
            BallerinaImportPackageQuickFix quickFix = new BallerinaImportPackageQuickFix(packageNameNode);
            availableFixes = new LocalQuickFix[] { quickFix };
        }
        PsiElement nameIdentifier = packageNameNode.getNameIdentifier();
        if (nameIdentifier == null) {
            continue;
        }
        PsiReference reference = nameIdentifier.getReference();
        if (reference == null || reference.resolve() == null) {
            if (reference instanceof PackageNameReference) {
                ResolveResult[] resolveResults = ((PackageNameReference) reference).multiResolve(false);
                if (resolveResults.length > 0) {
                    continue;
                }
            }
            problemDescriptors.add(createProblemDescriptor(manager, packageNameNode, isOnTheFly, availableFixes));
        }
    }
    // Todo - Add new quick fixes.
    LocalQuickFix[] availableFixes = new LocalQuickFix[0];
    Collection<NameReferenceNode> nameReferenceNodes = PsiTreeUtil.findChildrenOfType(file, NameReferenceNode.class);
    problemDescriptors.addAll(getUnresolvedNameReferenceDescriptors(manager, isOnTheFly, availableFixes, nameReferenceNodes));
    Collection<AnnotationAttributeNode> annotationAttributeNodes = PsiTreeUtil.findChildrenOfType(file, AnnotationAttributeNode.class);
    problemDescriptors.addAll(getUnresolvedReferenceDescriptors(manager, isOnTheFly, availableFixes, annotationAttributeNodes));
    Collection<ConnectorReferenceNode> connectorReferenceNodes = PsiTreeUtil.findChildrenOfType(file, ConnectorReferenceNode.class);
    problemDescriptors.addAll(getUnresolvedReferenceDescriptors(manager, isOnTheFly, availableFixes, connectorReferenceNodes));
    Collection<ActionInvocationNode> actionInvocationNodes = PsiTreeUtil.findChildrenOfType(file, ActionInvocationNode.class);
    problemDescriptors.addAll(getUnresolvedReferenceDescriptors(manager, isOnTheFly, availableFixes, actionInvocationNodes));
    Collection<FunctionReferenceNode> functionReferenceNodes = PsiTreeUtil.findChildrenOfType(file, FunctionReferenceNode.class);
    problemDescriptors.addAll(getUnresolvedReferenceDescriptors(manager, isOnTheFly, availableFixes, functionReferenceNodes));
    return problemDescriptors.toArray(new ProblemDescriptor[problemDescriptors.size()]);
}
Also used : BallerinaFile(org.ballerinalang.plugins.idea.psi.BallerinaFile) ImportDeclarationNode(org.ballerinalang.plugins.idea.psi.ImportDeclarationNode) ProblemDescriptor(com.intellij.codeInspection.ProblemDescriptor) PackageNameReference(org.ballerinalang.plugins.idea.psi.references.PackageNameReference) AnnotationAttributeNode(org.ballerinalang.plugins.idea.psi.AnnotationAttributeNode) LocalQuickFix(com.intellij.codeInspection.LocalQuickFix) XmlAttribNode(org.ballerinalang.plugins.idea.psi.XmlAttribNode) ConnectorReferenceNode(org.ballerinalang.plugins.idea.psi.ConnectorReferenceNode) ResolveResult(com.intellij.psi.ResolveResult) PsiElement(com.intellij.psi.PsiElement) AliasNode(org.ballerinalang.plugins.idea.psi.AliasNode) ActionInvocationNode(org.ballerinalang.plugins.idea.psi.ActionInvocationNode) PsiReference(com.intellij.psi.PsiReference) PackageDeclarationNode(org.ballerinalang.plugins.idea.psi.PackageDeclarationNode) LinkedList(java.util.LinkedList) PackageNameNode(org.ballerinalang.plugins.idea.psi.PackageNameNode) FunctionReferenceNode(org.ballerinalang.plugins.idea.psi.FunctionReferenceNode) NameReferenceNode(org.ballerinalang.plugins.idea.psi.NameReferenceNode) Nullable(org.jetbrains.annotations.Nullable)

Aggregations

PsiElement (com.intellij.psi.PsiElement)2 PsiReference (com.intellij.psi.PsiReference)2 PackageNameReference (org.ballerinalang.plugins.idea.psi.references.PackageNameReference)2 LocalQuickFix (com.intellij.codeInspection.LocalQuickFix)1 ProblemDescriptor (com.intellij.codeInspection.ProblemDescriptor)1 PsiErrorElement (com.intellij.psi.PsiErrorElement)1 ResolveResult (com.intellij.psi.ResolveResult)1 IElementType (com.intellij.psi.tree.IElementType)1 LinkedList (java.util.LinkedList)1 RuleIElementType (org.antlr.jetbrains.adaptor.lexer.RuleIElementType)1 ActionInvocationNode (org.ballerinalang.plugins.idea.psi.ActionInvocationNode)1 AliasNode (org.ballerinalang.plugins.idea.psi.AliasNode)1 AnnotationAttributeNode (org.ballerinalang.plugins.idea.psi.AnnotationAttributeNode)1 BallerinaFile (org.ballerinalang.plugins.idea.psi.BallerinaFile)1 ConnectorReferenceNode (org.ballerinalang.plugins.idea.psi.ConnectorReferenceNode)1 FunctionReferenceNode (org.ballerinalang.plugins.idea.psi.FunctionReferenceNode)1 ImportDeclarationNode (org.ballerinalang.plugins.idea.psi.ImportDeclarationNode)1 NameReferenceNode (org.ballerinalang.plugins.idea.psi.NameReferenceNode)1 PackageDeclarationNode (org.ballerinalang.plugins.idea.psi.PackageDeclarationNode)1 PackageNameNode (org.ballerinalang.plugins.idea.psi.PackageNameNode)1