Search in sources :

Example 1 with BallerinaFile

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

the class BallerinaPsiImplUtil method getAllConstantsInScope.

@NotNull
public static List<IdentifierPSINode> getAllConstantsInScope(@NotNull ScopeNode scope, int caretOffset) {
    List<IdentifierPSINode> results = new LinkedList<>();
    Collection<ConstantDefinitionNode> constantDefinitionNodes = PsiTreeUtil.findChildrenOfType(scope, ConstantDefinitionNode.class);
    for (ConstantDefinitionNode constantDefinitionNode : constantDefinitionNodes) {
        PsiElement identifier = constantDefinitionNode.getNameIdentifier();
        if (caretOffset != -1) {
            if (identifier == null || !(identifier instanceof IdentifierPSINode) || identifier.getTextOffset() > caretOffset) {
                continue;
            }
            PsiElement element = scope.findElementAt(caretOffset);
            if (element != null) {
                ConstantDefinitionNode definition = PsiTreeUtil.getParentOfType(element, ConstantDefinitionNode.class);
                if (definition != null && definition.equals(constantDefinitionNode)) {
                    continue;
                }
            }
        }
        results.add(((IdentifierPSINode) identifier));
    }
    PsiFile originalFile = ((BallerinaFile) scope).getOriginalFile();
    PsiDirectory containingPackage = originalFile.getParent();
    if (containingPackage == null) {
        return results;
    }
    PsiFile[] files = containingPackage.getFiles();
    for (PsiFile file : files) {
        // Do't check the current file again.
        if (file.equals(originalFile)) {
            continue;
        }
        constantDefinitionNodes = PsiTreeUtil.findChildrenOfType(file, ConstantDefinitionNode.class);
        for (ConstantDefinitionNode variableDefinitionNode : constantDefinitionNodes) {
            PsiElement identifier = variableDefinitionNode.getNameIdentifier();
            if (identifier != null && identifier instanceof IdentifierPSINode) {
                results.add(((IdentifierPSINode) identifier));
            }
        }
    }
    return results;
}
Also used : ConstantDefinitionNode(org.ballerinalang.plugins.idea.psi.ConstantDefinitionNode) BallerinaFile(org.ballerinalang.plugins.idea.psi.BallerinaFile) PsiDirectory(com.intellij.psi.PsiDirectory) IdentifierPSINode(org.ballerinalang.plugins.idea.psi.IdentifierPSINode) PsiFile(com.intellij.psi.PsiFile) LinkedList(java.util.LinkedList) PsiElement(com.intellij.psi.PsiElement) LeafPsiElement(com.intellij.psi.impl.source.tree.LeafPsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 2 with BallerinaFile

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

the class BallerinaPsiImplUtil method getAllXmlNamespacesInResolvableScope.

@NotNull
public static List<PsiElement> getAllXmlNamespacesInResolvableScope(@NotNull ScopeNode scope, int caretOffset) {
    List<PsiElement> results = new LinkedList<>();
    if (scope instanceof VariableContainer || scope instanceof CodeBlockScope || scope instanceof BallerinaFile) {
        results.addAll(getAllXmlNamespacesInScope(scope, caretOffset));
        ScopeNode context = scope.getContext();
        if (context != null) {
            results.addAll(getAllXmlNamespacesInResolvableScope(context, caretOffset));
        }
    } else if (scope instanceof ParameterContainer || scope instanceof TopLevelDefinition || scope instanceof LowerLevelDefinition) {
        ScopeNode context = scope.getContext();
        if (context != null) {
            results.addAll(getAllXmlNamespacesInResolvableScope(context, caretOffset));
        }
    }
    if (scope instanceof BallerinaFile) {
        PsiFile originalFile = ((BallerinaFile) scope).getOriginalFile();
        PsiDirectory containingPackage = originalFile.getParent();
        if (containingPackage == null) {
            return results;
        }
        PsiFile[] files = containingPackage.getFiles();
        for (PsiFile file : files) {
            // Do't check the current file again.
            if (file.equals(originalFile)) {
                continue;
            }
            Collection<NamespaceDeclarationNode> namespaceDeclarationNodes = PsiTreeUtil.findChildrenOfType(file, NamespaceDeclarationNode.class);
            for (NamespaceDeclarationNode namespaceDeclarationNode : namespaceDeclarationNodes) {
                PsiElement identifier = namespaceDeclarationNode.getNameIdentifier();
                if (identifier != null) {
                    results.add(identifier);
                }
            }
        }
    }
    return results;
}
Also used : BallerinaFile(org.ballerinalang.plugins.idea.psi.BallerinaFile) LinkedList(java.util.LinkedList) TopLevelDefinition(org.ballerinalang.plugins.idea.psi.scopes.TopLevelDefinition) VariableContainer(org.ballerinalang.plugins.idea.psi.scopes.VariableContainer) ParameterContainer(org.ballerinalang.plugins.idea.psi.scopes.ParameterContainer) NamespaceDeclarationNode(org.ballerinalang.plugins.idea.psi.NamespaceDeclarationNode) PsiDirectory(com.intellij.psi.PsiDirectory) PsiFile(com.intellij.psi.PsiFile) ScopeNode(org.antlr.jetbrains.adaptor.psi.ScopeNode) LowerLevelDefinition(org.ballerinalang.plugins.idea.psi.scopes.LowerLevelDefinition) PsiElement(com.intellij.psi.PsiElement) LeafPsiElement(com.intellij.psi.impl.source.tree.LeafPsiElement) CodeBlockScope(org.ballerinalang.plugins.idea.psi.scopes.CodeBlockScope) NotNull(org.jetbrains.annotations.NotNull)

Example 3 with BallerinaFile

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

the class NameReference method getVariantsFromCurrentPackage.

@NotNull
private List<LookupElement> getVariantsFromCurrentPackage() {
    List<LookupElement> results = new LinkedList<>();
    IdentifierPSINode identifier = getElement();
    PsiFile containingFile = identifier.getContainingFile();
    PsiFile originalFile = containingFile.getOriginalFile();
    PsiDirectory containingPackage = originalFile.getParent();
    AnnotationAttachmentNode attachmentNode = PsiTreeUtil.getParentOfType(identifier, AnnotationAttachmentNode.class);
    if (attachmentNode != null && containingFile instanceof BallerinaFile) {
        ScopeNode scope = (BallerinaFile) containingFile;
        List<IdentifierPSINode> constants = BallerinaPsiImplUtil.getAllConstantsInResolvableScope(scope);
        results.addAll(BallerinaCompletionUtils.createConstantLookupElements(constants));
    } else if (containingPackage != null) {
        List<LookupElement> packages = BallerinaPsiImplUtil.getPackagesAsLookups(originalFile, true, PackageCompletionInsertHandler.INSTANCE_WITH_AUTO_POPUP, true, AutoImportInsertHandler.INSTANCE_WITH_AUTO_POPUP);
        results.addAll(packages);
        PsiElement prevVisibleLeaf = PsiTreeUtil.prevVisibleLeaf(identifier);
        ANTLRPsiNode definitionParent = PsiTreeUtil.getParentOfType(identifier, CallableUnitBodyNode.class, ServiceBodyNode.class, ResourceDefinitionNode.class, ConnectorBodyNode.class);
        TypeNameNode typeNameNode = PsiTreeUtil.getParentOfType(identifier, TypeNameNode.class);
        if ((definitionParent != null && !(definitionParent instanceof ResourceDefinitionNode)) || prevVisibleLeaf != null && (!";".equals(prevVisibleLeaf.getText()) && typeNameNode == null || prevVisibleLeaf.getText().matches("[{}]"))) {
            List<IdentifierPSINode> functions = BallerinaPsiImplUtil.getAllFunctionsFromPackage(containingPackage, true, true);
            results.addAll(BallerinaCompletionUtils.createFunctionLookupElements(functions));
            // Todo - use a util method
            ScopeNode scope = PsiTreeUtil.getParentOfType(identifier, CodeBlockScope.class, VariableContainer.class, TopLevelDefinition.class, LowerLevelDefinition.class);
            if (scope != null) {
                int caretOffset = identifier.getStartOffset();
                List<IdentifierPSINode> variables = BallerinaPsiImplUtil.getAllLocalVariablesInResolvableScope(scope, caretOffset);
                results.addAll(BallerinaCompletionUtils.createVariableLookupElements(variables));
                List<IdentifierPSINode> parameters = BallerinaPsiImplUtil.getAllParametersInResolvableScope(scope, caretOffset);
                results.addAll(BallerinaCompletionUtils.createParameterLookupElements(parameters));
                List<IdentifierPSINode> globalVariables = BallerinaPsiImplUtil.getAllGlobalVariablesInResolvableScope(scope);
                results.addAll(BallerinaCompletionUtils.createGlobalVariableLookupElements(globalVariables));
                List<IdentifierPSINode> constants = BallerinaPsiImplUtil.getAllConstantsInResolvableScope(scope);
                results.addAll(BallerinaCompletionUtils.createConstantLookupElements(constants));
                List<PsiElement> namespaces = BallerinaPsiImplUtil.getAllXmlNamespacesInResolvableScope(scope, caretOffset);
                results.addAll(BallerinaCompletionUtils.createNamespaceLookupElements(namespaces));
                List<IdentifierPSINode> endpoints = BallerinaPsiImplUtil.getAllEndpointsInResolvableScope(scope, caretOffset);
                results.addAll(BallerinaCompletionUtils.createEndpointLookupElements(endpoints));
            } else {
                ConstantDefinitionNode constantDefinitionNode = PsiTreeUtil.getParentOfType(identifier, ConstantDefinitionNode.class);
                GlobalVariableDefinitionNode globalVariableDefinitionNode = PsiTreeUtil.getParentOfType(identifier, GlobalVariableDefinitionNode.class);
                if (constantDefinitionNode != null || globalVariableDefinitionNode != null) {
                    scope = PsiTreeUtil.getParentOfType(constantDefinitionNode, BallerinaFile.class);
                }
                if (globalVariableDefinitionNode != null) {
                    scope = PsiTreeUtil.getParentOfType(globalVariableDefinitionNode, BallerinaFile.class);
                }
                if (scope != null) {
                    int caretOffset = identifier.getStartOffset();
                    List<IdentifierPSINode> globalVars = BallerinaPsiImplUtil.getAllGlobalVariablesInResolvableScope(scope, caretOffset);
                    results.addAll(BallerinaCompletionUtils.createGlobalVariableLookupElements(globalVars));
                    List<IdentifierPSINode> constants = BallerinaPsiImplUtil.getAllConstantsInResolvableScope(scope, caretOffset);
                    results.addAll(BallerinaCompletionUtils.createConstantLookupElements(constants));
                }
            }
        }
        List<IdentifierPSINode> connectors = BallerinaPsiImplUtil.getAllConnectorsFromPackage(containingPackage, true, true);
        results.addAll(BallerinaCompletionUtils.createConnectorLookupElements(connectors, AddSpaceInsertHandler.INSTANCE));
        List<IdentifierPSINode> structs = BallerinaPsiImplUtil.getAllStructsFromPackage(containingPackage, true, true);
        results.addAll(BallerinaCompletionUtils.createStructLookupElements(structs));
        List<IdentifierPSINode> enums = BallerinaPsiImplUtil.getAllEnumsFromPackage(containingPackage, true, true);
        results.addAll(BallerinaCompletionUtils.createEnumLookupElements(enums, null));
        return results;
    }
    // Try to get fields from an anonymous struct.
    PsiElement structDefinitionNode = BallerinaPsiImplUtil.resolveAnonymousStruct(identifier);
    if (structDefinitionNode == null || !(structDefinitionNode instanceof StructDefinitionNode)) {
        return results;
    }
    IdentifierPSINode structNameNode = PsiTreeUtil.getChildOfType(structDefinitionNode, IdentifierPSINode.class);
    if (structNameNode == null) {
        return results;
    }
    Collection<FieldDefinitionNode> fieldDefinitionNodes = PsiTreeUtil.findChildrenOfType(structDefinitionNode, FieldDefinitionNode.class);
    results = BallerinaCompletionUtils.createFieldLookupElements(fieldDefinitionNodes, structNameNode, PackageCompletionInsertHandler.INSTANCE_WITH_AUTO_POPUP);
    return results;
}
Also used : ConstantDefinitionNode(org.ballerinalang.plugins.idea.psi.ConstantDefinitionNode) BallerinaFile(org.ballerinalang.plugins.idea.psi.BallerinaFile) TopLevelDefinition(org.ballerinalang.plugins.idea.psi.scopes.TopLevelDefinition) VariableContainer(org.ballerinalang.plugins.idea.psi.scopes.VariableContainer) PsiDirectory(com.intellij.psi.PsiDirectory) IdentifierPSINode(org.ballerinalang.plugins.idea.psi.IdentifierPSINode) PsiFile(com.intellij.psi.PsiFile) LinkedList(java.util.LinkedList) List(java.util.List) PsiElement(com.intellij.psi.PsiElement) ServiceBodyNode(org.ballerinalang.plugins.idea.psi.ServiceBodyNode) AnnotationAttachmentNode(org.ballerinalang.plugins.idea.psi.AnnotationAttachmentNode) ConnectorBodyNode(org.ballerinalang.plugins.idea.psi.ConnectorBodyNode) ANTLRPsiNode(org.antlr.jetbrains.adaptor.psi.ANTLRPsiNode) LookupElement(com.intellij.codeInsight.lookup.LookupElement) LinkedList(java.util.LinkedList) ResourceDefinitionNode(org.ballerinalang.plugins.idea.psi.ResourceDefinitionNode) StructDefinitionNode(org.ballerinalang.plugins.idea.psi.StructDefinitionNode) TypeNameNode(org.ballerinalang.plugins.idea.psi.TypeNameNode) FieldDefinitionNode(org.ballerinalang.plugins.idea.psi.FieldDefinitionNode) CallableUnitBodyNode(org.ballerinalang.plugins.idea.psi.CallableUnitBodyNode) ScopeNode(org.antlr.jetbrains.adaptor.psi.ScopeNode) LowerLevelDefinition(org.ballerinalang.plugins.idea.psi.scopes.LowerLevelDefinition) CodeBlockScope(org.ballerinalang.plugins.idea.psi.scopes.CodeBlockScope) GlobalVariableDefinitionNode(org.ballerinalang.plugins.idea.psi.GlobalVariableDefinitionNode) NotNull(org.jetbrains.annotations.NotNull)

Example 4 with BallerinaFile

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

the class BallerinaImportOptimizer method processFile.

@NotNull
@Override
public Runnable processFile(PsiFile file) {
    if (!(file instanceof BallerinaFile)) {
        return EmptyRunnable.getInstance();
    }
    // Get all imported packages in the file.
    List<PsiElement> importedPackages = BallerinaPsiImplUtil.getImportedPackages(file);
    // If there are no imported packages, we don't need to optimize imports.
    if (importedPackages.isEmpty()) {
        return EmptyRunnable.getInstance();
    }
    return new CollectingInfoRunnable() {

        private int removedImports;

        @Override
        public void run() {
            // Get all of used imports in the file.
            List<ImportDeclarationNode> usedImportDeclarations = getUsedImportDeclarations(file);
            // Iterate through all of the imports in the file.
            for (PsiElement importedPackage : importedPackages) {
                // Get the ImportDeclarationNode which corresponds to the import.
                ImportDeclarationNode importDeclarationNode = PsiTreeUtil.getParentOfType(importedPackage, ImportDeclarationNode.class);
                // If an ImportDeclarationNode is not found, continue with the next import.
                if (importDeclarationNode == null) {
                    continue;
                }
                // If ImportDeclarationNode is found, delete it since it is not used.
                if (!usedImportDeclarations.contains(importDeclarationNode)) {
                    importDeclarationNode.delete();
                }
            }
            // Sort the used imports.
            Collections.sort(usedImportDeclarations);
            // Get the first element of the list. We start to insert elements after the 1st element. So we
            // consider this element to be the first element which we added to the tree.
            PsiElement addedNode = usedImportDeclarations.get(0);
            for (int i = 1; i < usedImportDeclarations.size(); i++) {
                // Get an element from the list.
                ImportDeclarationNode importDeclarationNode = usedImportDeclarations.get(i);
                // Add it after the element which we have previously added to the tree. Keep the returned value
                // in a temporary variable.
                PsiElement temp = addedNode.getParent().addAfter(importDeclarationNode, addedNode);
                // Add a new line after the previously added node. Otherwise all imports will be in one line. We
                // need to do it in this order, otherwise the next import will be added to the end of the file.
                addedNode.getParent().addAfter(BallerinaElementFactory.createNewLine(file.getProject()), addedNode);
                // Update the added node with the temporary created variable value.
                addedNode = temp;
            }
            // Now we need to delete old imports.
            for (int i = 1; i < usedImportDeclarations.size(); i++) {
                usedImportDeclarations.get(i).delete();
            }
            // Calculate removed imports size.
            removedImports = importedPackages.size() - BallerinaPsiImplUtil.getImportedPackages(file).size();
        }

        @Nullable
        @Override
        public String getUserNotificationInfo() {
            if (removedImports > 0) {
                return "removed " + removedImports + " import" + (removedImports > 1 ? "s" : "");
            }
            return null;
        }
    };
}
Also used : BallerinaFile(org.ballerinalang.plugins.idea.psi.BallerinaFile) ImportDeclarationNode(org.ballerinalang.plugins.idea.psi.ImportDeclarationNode) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 5 with BallerinaFile

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

the class BallerinaStructureViewElement method getChildren.

@NotNull
@Override
public TreeElement[] getChildren() {
    // The element can be one of BallerinaFile, ConnectorDefinitionNode instance.
    if (element instanceof BallerinaFile) {
        List<TreeElement> treeElements = new ArrayList<>();
        // Add services.
        Collection<ServiceDefinitionNode> services = PsiTreeUtil.findChildrenOfType(element, ServiceDefinitionNode.class);
        for (PsiElement service : services) {
            // In here, instead of using the service, we use service.getParent(). This is done because we
            // want to show resources under a service node. This is how the sub nodes can be added.
            treeElements.add(new BallerinaStructureViewElement(service));
        }
        // Add functions.
        Collection<FunctionDefinitionNode> functions = PsiTreeUtil.findChildrenOfType(element, FunctionDefinitionNode.class);
        for (PsiElement function : functions) {
            treeElements.add(new BallerinaStructureViewElement(function));
        }
        // Add connectors.
        Collection<ConnectorDefinitionNode> connectors = PsiTreeUtil.findChildrenOfType(element, ConnectorDefinitionNode.class);
        for (PsiElement connector : connectors) {
            // In here, instead of using the connector, we use connector.getParent(). This is done because we
            // want to show actions under a connector node. This is how the sub nodes can be added.
            treeElements.add(new BallerinaStructureViewElement(connector));
        }
        // Add annotations.
        Collection<AnnotationDefinitionNode> annotations = PsiTreeUtil.findChildrenOfType(element, AnnotationDefinitionNode.class);
        for (PsiElement annotation : annotations) {
            treeElements.add(new BallerinaStructureViewElement(annotation));
        }
        // Add structs
        Collection<StructDefinitionNode> structs = PsiTreeUtil.findChildrenOfType(element, StructDefinitionNode.class);
        for (PsiElement struct : structs) {
            treeElements.add(new BallerinaStructureViewElement(struct));
        }
        // Convert the list to an array and return.
        return treeElements.toArray(new TreeElement[treeElements.size()]);
    } else if (element instanceof ConnectorDefinitionNode) {
        // If the element is a ConnectorDefinitionNode instance, we get all actions.
        List<TreeElement> treeElements = new ArrayList<>();
        // Add actions.
        Collection<ActionDefinitionNode> actions = PsiTreeUtil.findChildrenOfType(element, ActionDefinitionNode.class);
        for (PsiElement action : actions) {
            treeElements.add(new BallerinaStructureViewElement(action));
        }
        // Convert the list to an array and return.
        return treeElements.toArray(new TreeElement[treeElements.size()]);
    } else if (element instanceof ServiceDefinitionNode) {
        // If the element is a ServiceDefinitionNode instance, we get all resources.
        List<TreeElement> treeElements = new ArrayList<>();
        // Add resources.
        Collection<ResourceDefinitionNode> resources = PsiTreeUtil.findChildrenOfType(element, ResourceDefinitionNode.class);
        for (PsiElement resource : resources) {
            treeElements.add(new BallerinaStructureViewElement(resource));
        }
        // Convert the list to an array and return.
        return treeElements.toArray(new TreeElement[treeElements.size()]);
    } else if (element instanceof FunctionDefinitionNode || element instanceof ResourceDefinitionNode || element instanceof ActionDefinitionNode) {
        // If the element is a FunctionDefinitionNode instance, we get all workers.
        List<TreeElement> treeElements = new ArrayList<>();
        // Add workers.
        Collection<WorkerDeclarationNode> workers = PsiTreeUtil.findChildrenOfType(element, WorkerDeclarationNode.class);
        for (PsiElement worker : workers) {
            treeElements.add(new BallerinaStructureViewElement(worker));
        }
        // Convert the list to an array and return.
        return treeElements.toArray(new TreeElement[treeElements.size()]);
    }
    // If the element type other than what we check above, return an empty array.
    return new TreeElement[0];
}
Also used : BallerinaFile(org.ballerinalang.plugins.idea.psi.BallerinaFile) WorkerDeclarationNode(org.ballerinalang.plugins.idea.psi.WorkerDeclarationNode) ActionDefinitionNode(org.ballerinalang.plugins.idea.psi.ActionDefinitionNode) ArrayList(java.util.ArrayList) ConnectorDefinitionNode(org.ballerinalang.plugins.idea.psi.ConnectorDefinitionNode) TreeElement(com.intellij.ide.util.treeView.smartTree.TreeElement) StructureViewTreeElement(com.intellij.ide.structureView.StructureViewTreeElement) SortableTreeElement(com.intellij.ide.util.treeView.smartTree.SortableTreeElement) ServiceDefinitionNode(org.ballerinalang.plugins.idea.psi.ServiceDefinitionNode) ResourceDefinitionNode(org.ballerinalang.plugins.idea.psi.ResourceDefinitionNode) FunctionDefinitionNode(org.ballerinalang.plugins.idea.psi.FunctionDefinitionNode) StructDefinitionNode(org.ballerinalang.plugins.idea.psi.StructDefinitionNode) AnnotationDefinitionNode(org.ballerinalang.plugins.idea.psi.AnnotationDefinitionNode) Collection(java.util.Collection) ArrayList(java.util.ArrayList) List(java.util.List) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

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