Search in sources :

Example 6 with BallerinaFile

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

the class BallerinaCreateFileActionTest method doTemplateTest.

private static void doTemplateTest(@NotNull PsiDirectory dir, @NotNull String expectedPackage, @NotNull CustomFileTemplate template) {
    PsiFile fileFromTemplate = CreateFileFromTemplateAction.createFileFromTemplate("test", template, dir, null, true);
    BallerinaFile file = (BallerinaFile) fileFromTemplate;
    assertNotNull(file);
    PackageDeclarationNode packageDeclarationNode = PsiTreeUtil.findChildOfType(fileFromTemplate, PackageDeclarationNode.class);
    // declaration available. Otherwise there will be a package declaration node.
    if (!expectedPackage.isEmpty()) {
        assertNotNull(packageDeclarationNode);
        FullyQualifiedPackageNameNode fullyQualifiedPackageNameNode = PsiTreeUtil.getChildOfType(packageDeclarationNode, FullyQualifiedPackageNameNode.class);
        assertNotNull(fullyQualifiedPackageNameNode);
        assertEquals(expectedPackage, fullyQualifiedPackageNameNode.getText());
    } else {
        assertNull(packageDeclarationNode);
    }
    WriteCommandAction.runWriteCommandAction(dir.getProject(), file::delete);
}
Also used : FullyQualifiedPackageNameNode(org.ballerinalang.plugins.idea.psi.FullyQualifiedPackageNameNode) BallerinaFile(org.ballerinalang.plugins.idea.psi.BallerinaFile) PsiFile(com.intellij.psi.PsiFile) PackageDeclarationNode(org.ballerinalang.plugins.idea.psi.PackageDeclarationNode)

Example 7 with BallerinaFile

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

the class BallerinaCreateFileAction method postProcess.

@Override
protected void postProcess(PsiFile createdElement, String templateName, Map<String, String> customProperties) {
    if (createdElement instanceof BallerinaFile) {
        // Moving the caret to the end of the file.
        Project project = createdElement.getProject();
        Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor();
        if (editor == null) {
            return;
        }
        VirtualFile virtualFile = createdElement.getContainingFile().getVirtualFile();
        if (virtualFile == null) {
            return;
        }
        PsiElement lastChild = createdElement.getLastChild();
        if (FileDocumentManager.getInstance().getDocument(virtualFile) == editor.getDocument()) {
            editor.getCaretModel().moveToOffset(lastChild.getTextRange().getEndOffset());
        }
    }
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) Project(com.intellij.openapi.project.Project) BallerinaFile(org.ballerinalang.plugins.idea.psi.BallerinaFile) Editor(com.intellij.openapi.editor.Editor) PsiElement(com.intellij.psi.PsiElement)

Example 8 with BallerinaFile

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

the class BallerinaImportPackageQuickFix method isAvailable.

@Override
public boolean isAvailable(@NotNull Project project, @NotNull PsiFile file, @NotNull PsiElement startElement, @NotNull PsiElement endElement) {
    // We only perform this action on Ballerina modules since this might cause issues in other modules.
    Module module = ModuleUtil.findModuleForFile(file.getVirtualFile(), file.getProject());
    boolean isBallerinaModule = BallerinaSdkService.getInstance(project).isBallerinaModule(module);
    if (!isBallerinaModule) {
        return false;
    }
    // If the file contain error elements, do not perform auto import. Since this might affect badly to the user
    // experience.
    Collection<PsiErrorElement> errorElements = PsiTreeUtil.findChildrenOfType(file, PsiErrorElement.class);
    if (!errorElements.isEmpty()) {
        return false;
    }
    if (!(startElement instanceof PackageNameNode)) {
        return false;
    }
    PsiElement nameIdentifier = ((PackageNameNode) startElement).getNameIdentifier();
    if (nameIdentifier == null) {
        return false;
    }
    PsiReference reference = nameIdentifier.getReference();
    return file instanceof BallerinaFile && file.getManager().isInProject(file) && (reference == null || reference.resolve() == null);
}
Also used : PsiErrorElement(com.intellij.psi.PsiErrorElement) BallerinaFile(org.ballerinalang.plugins.idea.psi.BallerinaFile) PackageNameNode(org.ballerinalang.plugins.idea.psi.PackageNameNode) PsiReference(com.intellij.psi.PsiReference) Module(com.intellij.openapi.module.Module) LocalQuickFixAndIntentionActionOnPsiElement(com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement) PsiElement(com.intellij.psi.PsiElement)

Example 9 with BallerinaFile

use of org.ballerinalang.plugins.idea.psi.BallerinaFile 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 10 with BallerinaFile

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

Aggregations

BallerinaFile (org.ballerinalang.plugins.idea.psi.BallerinaFile)16 PsiElement (com.intellij.psi.PsiElement)12 PsiFile (com.intellij.psi.PsiFile)9 LinkedList (java.util.LinkedList)7 NotNull (org.jetbrains.annotations.NotNull)7 PsiDirectory (com.intellij.psi.PsiDirectory)5 VirtualFile (com.intellij.openapi.vfs.VirtualFile)4 ArrayList (java.util.ArrayList)4 IdentifierPSINode (org.ballerinalang.plugins.idea.psi.IdentifierPSINode)4 PackageDeclarationNode (org.ballerinalang.plugins.idea.psi.PackageDeclarationNode)4 PackageNameNode (org.ballerinalang.plugins.idea.psi.PackageNameNode)4 Nullable (org.jetbrains.annotations.Nullable)4 LocalQuickFix (com.intellij.codeInspection.LocalQuickFix)3 ProblemDescriptor (com.intellij.codeInspection.ProblemDescriptor)3 PsiReference (com.intellij.psi.PsiReference)3 LeafPsiElement (com.intellij.psi.impl.source.tree.LeafPsiElement)3 FullyQualifiedPackageNameNode (org.ballerinalang.plugins.idea.psi.FullyQualifiedPackageNameNode)3 ImportDeclarationNode (org.ballerinalang.plugins.idea.psi.ImportDeclarationNode)3 RuntimeConfigurationError (com.intellij.execution.configurations.RuntimeConfigurationError)2 Module (com.intellij.openapi.module.Module)2