Search in sources :

Example 11 with PackageNameNode

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

the class BallerinaImportPackageQuickFix method doAutoImportOrShowHint.

private boolean doAutoImportOrShowHint(@NotNull Editor editor, boolean showHint) {
    PsiElement element = getStartElement();
    if (element == null || !element.isValid()) {
        return false;
    }
    if (!(element instanceof PackageNameNode)) {
        return false;
    }
    PsiElement nameIdentifier = ((PackageNameNode) element).getNameIdentifier();
    if (nameIdentifier == null) {
        return false;
    }
    PsiReference reference = nameIdentifier.getReference();
    if (reference != null && reference.resolve() != null) {
        return false;
    }
    List<String> packagesToImport = getImportPathVariantsToImport(element);
    if (packagesToImport.isEmpty()) {
        return false;
    }
    PsiFile file = element.getContainingFile();
    String firstPackageToImport = ContainerUtil.getFirstItem(packagesToImport);
    // autoimport on trying to fix
    if (packagesToImport.size() == 1) {
        if (BallerinaCodeInsightSettings.getInstance().isAddUnambiguousImportsOnTheFly()) {
            if (!LaterInvocator.isInModalContext() && (ApplicationManager.getApplication().isUnitTestMode() || DaemonListeners.canChangeFileSilently(file))) {
                if (reference == null || reference.resolve() == null) {
                    performImport(file, firstPackageToImport);
                }
                return false;
            }
        }
    }
    // show hint on failed autoimport
    if (showHint) {
        if (ApplicationManager.getApplication().isUnitTestMode()) {
            return false;
        }
        if (HintManager.getInstance().hasShownHintsThatWillHideByOtherHint(true)) {
            return false;
        }
        if (!BallerinaCodeInsightSettings.getInstance().isShowImportPopup()) {
            return false;
        }
        TextRange referenceRange = element.getTextRange();
        String message = ShowAutoImportPass.getMessage(packagesToImport.size() > 1, ContainerUtil.getFirstItem(packagesToImport));
        HintManager.getInstance().showQuestionHint(editor, message, referenceRange.getStartOffset(), referenceRange.getEndOffset(), () -> {
            if (file.isValid() && !editor.isDisposed()) {
                performImport(packagesToImport, file, editor);
            }
            return true;
        });
        return true;
    }
    return false;
}
Also used : PackageNameNode(org.ballerinalang.plugins.idea.psi.PackageNameNode) PsiReference(com.intellij.psi.PsiReference) PsiFile(com.intellij.psi.PsiFile) TextRange(com.intellij.openapi.util.TextRange) LocalQuickFixAndIntentionActionOnPsiElement(com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement) PsiElement(com.intellij.psi.PsiElement)

Example 12 with PackageNameNode

use of org.ballerinalang.plugins.idea.psi.PackageNameNode 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)

Example 13 with PackageNameNode

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

the class BallerinaUnresolvedReferenceInspection method getUnresolvedNameReferenceDescriptors.

private List<ProblemDescriptor> getUnresolvedNameReferenceDescriptors(@NotNull InspectionManager manager, boolean isOnTheFly, @NotNull LocalQuickFix[] availableFixes, @NotNull Collection<NameReferenceNode> nodes) {
    List<ProblemDescriptor> problemDescriptors = new LinkedList<>();
    for (NameReferenceNode node : nodes) {
        ProgressManager.checkCanceled();
        if (node == null || "_".equals(node.getText())) {
            continue;
        }
        PackageNameNode packageNameNode = PsiTreeUtil.getChildOfType(node, PackageNameNode.class);
        if (packageNameNode != null) {
            PsiReference reference = packageNameNode.findReferenceAt(0);
            if (reference != null) {
                PsiElement resolvedElement = reference.resolve();
                if (resolvedElement != null && resolvedElement.getParent() instanceof NamespaceDeclarationNode) {
                    continue;
                }
            }
        }
        IdentifierPSINode identifier = PsiTreeUtil.getChildOfType(node, IdentifierPSINode.class);
        if (identifier == null) {
            continue;
        }
        AssignmentStatementNode assignmentStatementNode = PsiTreeUtil.getParentOfType(identifier, AssignmentStatementNode.class);
        if (assignmentStatementNode == null) {
            continue;
        }
        boolean isValidVarVariable = BallerinaPsiImplUtil.isValidVarVariable(assignmentStatementNode, identifier);
        if (isValidVarVariable) {
            continue;
        }
        PsiReference reference = identifier.getReference();
        if (reference == null || reference.resolve() == null) {
            problemDescriptors.add(createProblemDescriptor(manager, identifier, isOnTheFly, availableFixes));
        }
    }
    return problemDescriptors;
}
Also used : PackageNameNode(org.ballerinalang.plugins.idea.psi.PackageNameNode) AssignmentStatementNode(org.ballerinalang.plugins.idea.psi.AssignmentStatementNode) NamespaceDeclarationNode(org.ballerinalang.plugins.idea.psi.NamespaceDeclarationNode) ProblemDescriptor(com.intellij.codeInspection.ProblemDescriptor) IdentifierPSINode(org.ballerinalang.plugins.idea.psi.IdentifierPSINode) PsiReference(com.intellij.psi.PsiReference) LinkedList(java.util.LinkedList) NameReferenceNode(org.ballerinalang.plugins.idea.psi.NameReferenceNode) PsiElement(com.intellij.psi.PsiElement)

Example 14 with PackageNameNode

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

the class UnusedImportInspection 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];
    }
    // This is used to track all packages used in the file.
    List<String> usedPackages = new LinkedList<>();
    LocalQuickFix[] availableFixes = new LocalQuickFix[0];
    List<ProblemDescriptor> problemDescriptors = new LinkedList<>();
    Collection<PackageNameNode> packageNameNodes = PsiTreeUtil.findChildrenOfType(file, PackageNameNode.class);
    for (PackageNameNode packageNameNode : packageNameNodes) {
        ProgressManager.checkCanceled();
        if (packageNameNode == null) {
            continue;
        }
        PackageDeclarationNode packageDeclarationNode = PsiTreeUtil.getParentOfType(packageNameNode, PackageDeclarationNode.class);
        if (packageDeclarationNode != null) {
            continue;
        }
        ImportDeclarationNode importDeclarationNode = PsiTreeUtil.getParentOfType(packageNameNode, ImportDeclarationNode.class);
        if (importDeclarationNode != null) {
            continue;
        }
        XmlAttribNode xmlAttribNode = PsiTreeUtil.getParentOfType(packageNameNode, XmlAttribNode.class);
        if (xmlAttribNode != null) {
            continue;
        }
        PsiElement nameIdentifier = packageNameNode.getNameIdentifier();
        if (nameIdentifier == null) {
            continue;
        }
        usedPackages.add(nameIdentifier.getText());
    }
    // This is used to keep track of fully qualified imported packages. This will be used to identify redeclared
    // import statements.
    List<String> fullyQualifiedImportedPackages = new LinkedList<>();
    // This is used to keep track of last package in import declaration. This will be used to identify importing
    // multiple packages which ends with same name.
    List<String> importedPackages = new LinkedList<>();
    Collection<ImportDeclarationNode> importDeclarationNodes = PsiTreeUtil.findChildrenOfType(file, ImportDeclarationNode.class);
    for (ImportDeclarationNode importDeclarationNode : importDeclarationNodes) {
        ProgressManager.checkCanceled();
        if (importDeclarationNode == null) {
            continue;
        }
        // Check unused imports. No need to check for fully qualified path since we cant import packages of same
        // name.
        List<PackageNameNode> packageNames = new ArrayList<>(PsiTreeUtil.findChildrenOfType(importDeclarationNode, PackageNameNode.class));
        PackageNameNode lastPackage = ContainerUtil.getLastItem(packageNames);
        if (lastPackage == null) {
            continue;
        }
        String lastPackageName = lastPackage.getText();
        if (!usedPackages.contains(lastPackageName)) {
            problemDescriptors.add(createProblemDescriptor(manager, "Unused import", isOnTheFly, importDeclarationNode, availableFixes, ProblemHighlightType.LIKE_UNUSED_SYMBOL));
        }
        // Check conflicting imports (which ends with same package name).
        if (importedPackages.contains(lastPackageName)) {
            problemDescriptors.add(createProblemDescriptor(manager, "Conflicting import", isOnTheFly, importDeclarationNode, availableFixes, ProblemHighlightType.GENERIC_ERROR));
        }
        importedPackages.add(lastPackageName);
        // Check redeclared imports.
        FullyQualifiedPackageNameNode fullyQualifiedPackageName = PsiTreeUtil.getChildOfType(importDeclarationNode, FullyQualifiedPackageNameNode.class);
        if (fullyQualifiedPackageName == null) {
            continue;
        }
        if (fullyQualifiedImportedPackages.contains(fullyQualifiedPackageName.getText())) {
            problemDescriptors.add(createProblemDescriptor(manager, "Redeclared import", isOnTheFly, importDeclarationNode, availableFixes, ProblemHighlightType.GENERIC_ERROR));
        }
        fullyQualifiedImportedPackages.add(fullyQualifiedPackageName.getText());
    }
    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) ArrayList(java.util.ArrayList) LocalQuickFix(com.intellij.codeInspection.LocalQuickFix) PackageDeclarationNode(org.ballerinalang.plugins.idea.psi.PackageDeclarationNode) LinkedList(java.util.LinkedList) FullyQualifiedPackageNameNode(org.ballerinalang.plugins.idea.psi.FullyQualifiedPackageNameNode) PackageNameNode(org.ballerinalang.plugins.idea.psi.PackageNameNode) FullyQualifiedPackageNameNode(org.ballerinalang.plugins.idea.psi.FullyQualifiedPackageNameNode) XmlAttribNode(org.ballerinalang.plugins.idea.psi.XmlAttribNode) PsiElement(com.intellij.psi.PsiElement) Nullable(org.jetbrains.annotations.Nullable)

Example 15 with PackageNameNode

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

the class BallerinaCompletionContributor method fillCompletionVariants.

@Override
public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
    // The file will be loaded to memory and and will be edited. parameters.getOriginalFile()
    // contains the original file. parameters.getPosition().getContainingFile() will return null
    // because it only exists in the memory. So use parameters.getOriginalFile().getContainingFile()
    // if you want to get the details like containing directory, etc.
    PsiElement element = parameters.getPosition();
    PsiElement parent = element.getParent();
    if (parent instanceof PackageNameNode) {
        handlePackageNameNode(parameters, result);
    } else if (parent instanceof ImportDeclarationNode) {
        handleImportDeclarationNode(parameters, result);
    }
    // Otherwise we only suggest attachable annotations only.
    if (parameters.isExtendedCompletion()) {
        PsiReference reference = element.findReferenceAt(0);
        if (reference instanceof AnnotationReference) {
            List<LookupElement> variants = ((AnnotationReference) reference).getVariants(true);
            result.addAllElements(variants);
            result.addLookupAdvertisement("Showing all annotations in the package");
        }
    }
}
Also used : PackageNameNode(org.ballerinalang.plugins.idea.psi.PackageNameNode) ImportDeclarationNode(org.ballerinalang.plugins.idea.psi.ImportDeclarationNode) PsiReference(com.intellij.psi.PsiReference) AnnotationReference(org.ballerinalang.plugins.idea.psi.references.AnnotationReference) LookupElement(com.intellij.codeInsight.lookup.LookupElement) PsiElement(com.intellij.psi.PsiElement)

Aggregations

PackageNameNode (org.ballerinalang.plugins.idea.psi.PackageNameNode)35 PsiElement (com.intellij.psi.PsiElement)30 IdentifierPSINode (org.ballerinalang.plugins.idea.psi.IdentifierPSINode)20 LinkedList (java.util.LinkedList)17 NotNull (org.jetbrains.annotations.NotNull)14 LookupElement (com.intellij.codeInsight.lookup.LookupElement)11 Nullable (org.jetbrains.annotations.Nullable)11 PsiReference (com.intellij.psi.PsiReference)9 FullyQualifiedPackageNameNode (org.ballerinalang.plugins.idea.psi.FullyQualifiedPackageNameNode)9 PsiDirectory (com.intellij.psi.PsiDirectory)8 ArrayList (java.util.ArrayList)7 ImportDeclarationNode (org.ballerinalang.plugins.idea.psi.ImportDeclarationNode)7 AliasNode (org.ballerinalang.plugins.idea.psi.AliasNode)5 PackageDeclarationNode (org.ballerinalang.plugins.idea.psi.PackageDeclarationNode)5 ProblemDescriptor (com.intellij.codeInspection.ProblemDescriptor)4 Module (com.intellij.openapi.module.Module)4 PsiFile (com.intellij.psi.PsiFile)4 LeafPsiElement (com.intellij.psi.impl.source.tree.LeafPsiElement)4 BallerinaFile (org.ballerinalang.plugins.idea.psi.BallerinaFile)4 XmlAttribNode (org.ballerinalang.plugins.idea.psi.XmlAttribNode)4