Search in sources :

Example 11 with PackageDeclarationNode

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

the class BallerinaAnnotator method annotatePackageNameNodes.

private void annotatePackageNameNodes(@NotNull PsiElement element, @NotNull AnnotationHolder holder) {
    PsiElement parent = element.getParent();
    if (parent != null) {
        PsiElement superParent = parent.getParent();
        if (superParent != null && superParent instanceof AnnotationAttachmentNode) {
            Annotation annotation = holder.createInfoAnnotation(element, null);
            annotation.setTextAttributes(BallerinaSyntaxHighlightingColors.ANNOTATION);
            return;
        }
    }
    ImportDeclarationNode importDeclarationNode = PsiTreeUtil.getParentOfType(element, ImportDeclarationNode.class);
    if (importDeclarationNode != null) {
        return;
    }
    PackageDeclarationNode packageDeclarationNode = PsiTreeUtil.getParentOfType(element, PackageDeclarationNode.class);
    if (packageDeclarationNode != null) {
        return;
    }
    AnnotationAttachmentNode annotationAttachmentNode = PsiTreeUtil.getParentOfType(element, AnnotationAttachmentNode.class);
    if (annotationAttachmentNode != null) {
        return;
    }
    XmlAttribNode xmlAttribNode = PsiTreeUtil.getParentOfType(element, XmlAttribNode.class);
    if (xmlAttribNode != null) {
        return;
    }
    // Create the annotation.
    Annotation annotation = holder.createInfoAnnotation(element.getTextRange(), null);
    annotation.setTextAttributes(BallerinaSyntaxHighlightingColors.PACKAGE);
}
Also used : ImportDeclarationNode(org.ballerinalang.plugins.idea.psi.ImportDeclarationNode) XmlAttribNode(org.ballerinalang.plugins.idea.psi.XmlAttribNode) PackageDeclarationNode(org.ballerinalang.plugins.idea.psi.PackageDeclarationNode) PsiElement(com.intellij.psi.PsiElement) LeafPsiElement(com.intellij.psi.impl.source.tree.LeafPsiElement) Annotation(com.intellij.lang.annotation.Annotation) AnnotationAttachmentNode(org.ballerinalang.plugins.idea.psi.AnnotationAttachmentNode)

Example 12 with PackageDeclarationNode

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

the class BallerinaExternalAnnotator method getPackageName.

/**
 * Return the package name correspond to the provided file. This method will also consider the directory structure
 * as well. If the directory structure is different than the declared package in the file, relative directory
 * structure will be converted to package name and will be returned. Following 2 scenarios need to be considered.
 * <p>
 * Scenario 1 - Incorrect package declared in file. Correct directory structure.
 * Scenario 2 - Package declared in files in project root.
 *
 * @param file a psi file
 * @return package name correspond to the provided file
 */
private String getPackageName(PsiFile file) {
    // Get the package name specified in the file.
    PackageDeclarationNode packageDeclarationNode = PsiTreeUtil.findChildOfType(file, PackageDeclarationNode.class);
    if (packageDeclarationNode == null) {
        return null;
    }
    FullyQualifiedPackageNameNode packageNameNode = PsiTreeUtil.getChildOfType(packageDeclarationNode, FullyQualifiedPackageNameNode.class);
    if (packageNameNode == null) {
        return null;
    }
    String packageNameInFile = packageNameNode.getText();
    // Get the parent directory.
    PsiDirectory psiDirectory = file.getParent();
    if (psiDirectory == null) {
        return packageNameInFile;
    }
    // Package declaration might have an incorrect package declaration. So need to validate against directory name.
    if (packageNameInFile.endsWith(psiDirectory.getName())) {
        return packageNameInFile;
    }
    // Get the current module.
    Module module = ModuleUtilCore.findModuleForPsiElement(file);
    // Calculate the source root. This is used to get the relative directory path.
    String sourceRoot = file.getProject().getBasePath();
    if (module != null && FileUtil.exists(module.getModuleFilePath())) {
        sourceRoot = StringUtil.trimEnd(PathUtil.getParentPath(module.getModuleFilePath()), BallerinaConstants.IDEA_CONFIG_DIRECTORY);
    }
    // Get the package according to the directory structure.
    String directoryPath = psiDirectory.getVirtualFile().getPath();
    if (sourceRoot == null) {
        return packageNameInFile;
    }
    String packageName = directoryPath.replace(sourceRoot, "").replaceAll("[/\\\\]", "\\.");
    // If the package name is empty, that means the file is in the project root.
    if (packageName.isEmpty()) {
        return null;
    }
    // Otherwise return the calculated package path.
    return packageName;
}
Also used : FullyQualifiedPackageNameNode(org.ballerinalang.plugins.idea.psi.FullyQualifiedPackageNameNode) PsiDirectory(com.intellij.psi.PsiDirectory) Module(com.intellij.openapi.module.Module) PackageDeclarationNode(org.ballerinalang.plugins.idea.psi.PackageDeclarationNode)

Example 13 with PackageDeclarationNode

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

the class BallerinaPsiImplUtil method addImport.

/**
 * Adds an import declaration node to the file.
 *
 * @param file       file which is to be used to insert the import declaration node
 * @param importPath import path to be used in the import declaration node
 * @param alias      alias if needed. If this is {@code null}, it will be ignored
 * @return import declaration node which is added
 */
@NotNull
public static ImportDeclarationNode addImport(@NotNull PsiFile file, @NotNull String importPath, @Nullable String alias) {
    PsiElement addedNode;
    Collection<ImportDeclarationNode> importDeclarationNodes = PsiTreeUtil.findChildrenOfType(file, ImportDeclarationNode.class);
    Project project = file.getProject();
    ImportDeclarationNode importDeclaration = BallerinaElementFactory.createImportDeclaration(project, importPath, alias);
    if (importDeclarationNodes.isEmpty()) {
        Collection<PackageDeclarationNode> packageDeclarationNodes = PsiTreeUtil.findChildrenOfType(file, PackageDeclarationNode.class);
        if (packageDeclarationNodes.isEmpty()) {
            PsiElement[] children = file.getChildren();
            // Children cannot be empty since the IDEA adds placeholder string
            PsiElement nonEmptyElement = PsiTreeUtil.skipSiblingsForward(children[0], PsiWhiteSpace.class, PsiComment.class);
            if (nonEmptyElement == null) {
                nonEmptyElement = children[0];
            }
            addedNode = file.addBefore(importDeclaration, children[0]);
            file.addBefore(BallerinaElementFactory.createDoubleNewLine(project), nonEmptyElement);
        } else {
            PackageDeclarationNode packageDeclarationNode = packageDeclarationNodes.iterator().next();
            PsiElement parent = packageDeclarationNode.getParent();
            addedNode = parent.addAfter(importDeclaration, packageDeclarationNode);
            parent.addAfter(BallerinaElementFactory.createDoubleNewLine(project), packageDeclarationNode);
        }
    } else {
        LinkedList<ImportDeclarationNode> importDeclarations = new LinkedList<>(importDeclarationNodes);
        ImportDeclarationNode lastImport = importDeclarations.getLast();
        addedNode = lastImport.getParent().addAfter(importDeclaration, lastImport);
        lastImport.getParent().addAfter(BallerinaElementFactory.createNewLine(project), lastImport);
    }
    return ((ImportDeclarationNode) addedNode);
}
Also used : Project(com.intellij.openapi.project.Project) ImportDeclarationNode(org.ballerinalang.plugins.idea.psi.ImportDeclarationNode) PackageDeclarationNode(org.ballerinalang.plugins.idea.psi.PackageDeclarationNode) PsiElement(com.intellij.psi.PsiElement) LeafPsiElement(com.intellij.psi.impl.source.tree.LeafPsiElement) LinkedList(java.util.LinkedList) NotNull(org.jetbrains.annotations.NotNull)

Example 14 with PackageDeclarationNode

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

the class PackageNameReference method multiResolve.

@NotNull
@Override
public ResolveResult[] multiResolve(boolean incompleteCode) {
    IdentifierPSINode identifier = getElement();
    if (identifier == null) {
        return new ResolveResult[0];
    }
    AliasNode aliasNode = PsiTreeUtil.getParentOfType(identifier, AliasNode.class);
    if (aliasNode != null) {
        return new ResolveResult[0];
    }
    List<ResolveResult> results = new ArrayList<>();
    ImportDeclarationNode importDeclarationNode = PsiTreeUtil.getParentOfType(identifier, ImportDeclarationNode.class);
    if (importDeclarationNode != null) {
        List<PsiDirectory> directories = BallerinaPsiImplUtil.resolveDirectory(identifier);
        for (PsiDirectory directory : directories) {
            results.add(new PsiElementResolveResult(directory));
        }
        // Return the results.
        return results.toArray(new ResolveResult[results.size()]);
    }
    PackageDeclarationNode packageDeclarationNode = PsiTreeUtil.getParentOfType(identifier, PackageDeclarationNode.class);
    if (packageDeclarationNode != null) {
        // If this is a package declaration, resolve the directory.
        List<PsiDirectory> directories = BallerinaPsiImplUtil.resolveDirectory(identifier);
        for (PsiDirectory directory : directories) {
            results.add(new PsiElementResolveResult(directory));
        }
        // Return the results.
        return results.toArray(new ResolveResult[results.size()]);
    }
    PsiFile containingFile = identifier.getContainingFile();
    if (containingFile == null) {
        return new ResolveResult[0];
    }
    List<PsiElement> importedPackages = BallerinaPsiImplUtil.getImportedPackagesInCurrentFile(containingFile);
    for (PsiElement importedPackage : importedPackages) {
        String packageName = importedPackage.getText();
        if (packageName == null || packageName.isEmpty()) {
            continue;
        }
        if (packageName.equals(identifier.getText())) {
            PsiReference reference = importedPackage.findReferenceAt(0);
            if (reference != null) {
                PsiElement resolvedElement = reference.resolve();
                if (resolvedElement != null) {
                    results.add(new PsiElementResolveResult(resolvedElement));
                }
            }
        }
    }
    importedPackages = BallerinaPsiImplUtil.getPackagesImportedAsAliasInCurrentFile(containingFile);
    for (PsiElement importedPackage : importedPackages) {
        String packageName = importedPackage.getText();
        if (packageName == null || packageName.isEmpty()) {
            continue;
        }
        if (packageName.equals(identifier.getText())) {
            IdentifierPSINode nameNode = PsiTreeUtil.findChildOfType(importedPackage, IdentifierPSINode.class);
            if (nameNode != null) {
                results.add(new PsiElementResolveResult(nameNode));
            }
        }
    }
    return results.toArray(new ResolveResult[results.size()]);
}
Also used : ImportDeclarationNode(org.ballerinalang.plugins.idea.psi.ImportDeclarationNode) ArrayList(java.util.ArrayList) PsiReference(com.intellij.psi.PsiReference) PsiElementResolveResult(com.intellij.psi.PsiElementResolveResult) PackageDeclarationNode(org.ballerinalang.plugins.idea.psi.PackageDeclarationNode) PsiDirectory(com.intellij.psi.PsiDirectory) IdentifierPSINode(org.ballerinalang.plugins.idea.psi.IdentifierPSINode) PsiFile(com.intellij.psi.PsiFile) PsiElementResolveResult(com.intellij.psi.PsiElementResolveResult) ResolveResult(com.intellij.psi.ResolveResult) PsiElement(com.intellij.psi.PsiElement) AliasNode(org.ballerinalang.plugins.idea.psi.AliasNode) NotNull(org.jetbrains.annotations.NotNull)

Example 15 with PackageDeclarationNode

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

the class BallerinaImportOptimizer method getUsedImportDeclarations.

/**
 * Used to get used imports in a file.
 *
 * @param file a {@link PsiFile} element
 * @return list of used {@link ImportDeclarationNode} in the file.
 */
private List<ImportDeclarationNode> getUsedImportDeclarations(@NotNull PsiFile file) {
    // This is used to track all packages used in the file.
    List<String> usedPackages = 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());
    }
    List<ImportDeclarationNode> usedImportDeclarations = new LinkedList<>();
    List<String> fullyQualifiedImportedPackages = new LinkedList<>();
    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)) {
            continue;
        }
        // Check conflicting imports (which ends with same package name).
        if (importedPackages.contains(lastPackageName)) {
            continue;
        }
        importedPackages.add(lastPackageName);
        // Check redeclared imports.
        FullyQualifiedPackageNameNode fullyQualifiedPackageName = PsiTreeUtil.getChildOfType(importDeclarationNode, FullyQualifiedPackageNameNode.class);
        if (fullyQualifiedPackageName == null) {
            continue;
        }
        if (fullyQualifiedImportedPackages.contains(fullyQualifiedPackageName.getText())) {
            continue;
        }
        fullyQualifiedImportedPackages.add(fullyQualifiedPackageName.getText());
        usedImportDeclarations.add(importDeclarationNode);
    }
    return usedImportDeclarations;
}
Also used : ImportDeclarationNode(org.ballerinalang.plugins.idea.psi.ImportDeclarationNode) ArrayList(java.util.ArrayList) 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)

Aggregations

PackageDeclarationNode (org.ballerinalang.plugins.idea.psi.PackageDeclarationNode)15 PsiElement (com.intellij.psi.PsiElement)10 ImportDeclarationNode (org.ballerinalang.plugins.idea.psi.ImportDeclarationNode)9 FullyQualifiedPackageNameNode (org.ballerinalang.plugins.idea.psi.FullyQualifiedPackageNameNode)7 LinkedList (java.util.LinkedList)5 PackageNameNode (org.ballerinalang.plugins.idea.psi.PackageNameNode)5 XmlAttribNode (org.ballerinalang.plugins.idea.psi.XmlAttribNode)5 PsiDirectory (com.intellij.psi.PsiDirectory)4 PsiFile (com.intellij.psi.PsiFile)4 PsiReference (com.intellij.psi.PsiReference)4 ArrayList (java.util.ArrayList)4 AliasNode (org.ballerinalang.plugins.idea.psi.AliasNode)4 BallerinaFile (org.ballerinalang.plugins.idea.psi.BallerinaFile)4 LocalQuickFix (com.intellij.codeInspection.LocalQuickFix)3 ProblemDescriptor (com.intellij.codeInspection.ProblemDescriptor)3 Module (com.intellij.openapi.module.Module)3 LeafPsiElement (com.intellij.psi.impl.source.tree.LeafPsiElement)3 AnnotationAttachmentNode (org.ballerinalang.plugins.idea.psi.AnnotationAttachmentNode)3 FunctionDefinitionNode (org.ballerinalang.plugins.idea.psi.FunctionDefinitionNode)3 NameReferenceNode (org.ballerinalang.plugins.idea.psi.NameReferenceNode)3