Search in sources :

Example 1 with IdentifierPSINode

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

the class BallerinaPsiImplUtil method getType.

@Nullable
private static PsiElement getType(@NotNull AssignmentStatementNode assignmentStatementNode, @NotNull IdentifierPSINode identifier) {
    if (!BallerinaPsiImplUtil.isVarAssignmentStatement(assignmentStatementNode)) {
        return null;
    }
    ExpressionNode expressionNode = PsiTreeUtil.getChildOfType(assignmentStatementNode, ExpressionNode.class);
    if (expressionNode == null) {
        return null;
    }
    PsiElement expressionNodeFirstChild = expressionNode.getFirstChild();
    if (expressionNodeFirstChild instanceof VariableReferenceNode) {
        PsiElement typeNode = getTypeFromVariableReference(assignmentStatementNode, identifier, expressionNodeFirstChild);
        if (typeNode != null) {
            return typeNode;
        }
    } else if (expressionNodeFirstChild instanceof TypeCastNode) {
        int index = getVariableIndexFromVarAssignment(assignmentStatementNode, identifier);
        if (index == 0) {
            TypeNameNode typeNameNode = PsiTreeUtil.getChildOfType(expressionNodeFirstChild, TypeNameNode.class);
            if (typeNameNode == null) {
                return null;
            }
            return getType(typeNameNode, false);
        }
        StructDefinitionNode errorStruct = BallerinaPsiImplUtil.getErrorStruct(assignmentStatementNode, identifier, true, false);
        if (errorStruct == null) {
            return null;
        }
        return errorStruct.getNameIdentifier();
    } else if (expressionNodeFirstChild instanceof TypeConversionNode) {
        int index = getVariableIndexFromVarAssignment(assignmentStatementNode, identifier);
        if (index == 0) {
            TypeNameNode typeNameNode = PsiTreeUtil.getChildOfType(expressionNodeFirstChild, TypeNameNode.class);
            if (typeNameNode == null) {
                return null;
            }
            return getType(typeNameNode, false);
        }
        StructDefinitionNode errorStruct = BallerinaPsiImplUtil.getErrorStruct(assignmentStatementNode, identifier, false, true);
        if (errorStruct == null) {
            return null;
        }
        return errorStruct.getNameIdentifier();
    }
    PsiReference firstChildReference = expressionNodeFirstChild.findReferenceAt(expressionNodeFirstChild.getTextLength());
    if (firstChildReference == null) {
        return null;
    }
    PsiElement resolvedElement = firstChildReference.resolve();
    if (resolvedElement == null) {
        return null;
    }
    return getType(((IdentifierPSINode) resolvedElement));
}
Also used : StructDefinitionNode(org.ballerinalang.plugins.idea.psi.StructDefinitionNode) ExpressionNode(org.ballerinalang.plugins.idea.psi.ExpressionNode) BuiltInReferenceTypeNameNode(org.ballerinalang.plugins.idea.psi.BuiltInReferenceTypeNameNode) FunctionTypeNameNode(org.ballerinalang.plugins.idea.psi.FunctionTypeNameNode) TypeNameNode(org.ballerinalang.plugins.idea.psi.TypeNameNode) ValueTypeNameNode(org.ballerinalang.plugins.idea.psi.ValueTypeNameNode) AnonStructTypeNameNode(org.ballerinalang.plugins.idea.psi.AnonStructTypeNameNode) TypeConversionNode(org.ballerinalang.plugins.idea.psi.TypeConversionNode) IdentifierPSINode(org.ballerinalang.plugins.idea.psi.IdentifierPSINode) VariableReferenceNode(org.ballerinalang.plugins.idea.psi.VariableReferenceNode) PsiReference(com.intellij.psi.PsiReference) PsiElement(com.intellij.psi.PsiElement) LeafPsiElement(com.intellij.psi.impl.source.tree.LeafPsiElement) TypeCastNode(org.ballerinalang.plugins.idea.psi.TypeCastNode) Nullable(org.jetbrains.annotations.Nullable)

Example 2 with IdentifierPSINode

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

the class BallerinaPsiImplUtil method getAllEndpointsInResolvableScope.

@NotNull
public static List<IdentifierPSINode> getAllEndpointsInResolvableScope(@NotNull ScopeNode scope, int caretOffset) {
    List<IdentifierPSINode> results = new LinkedList<>();
    if (scope instanceof VariableContainer || scope instanceof CodeBlockScope || scope instanceof TopLevelDefinition || scope instanceof LowerLevelDefinition) {
        results.addAll(getAllEndpointsInScope(scope, caretOffset));
        ScopeNode context = scope.getContext();
        if (context != null) {
            results.addAll(getAllEndpointsInResolvableScope(context, caretOffset));
        }
    }
    return results;
}
Also used : VariableContainer(org.ballerinalang.plugins.idea.psi.scopes.VariableContainer) IdentifierPSINode(org.ballerinalang.plugins.idea.psi.IdentifierPSINode) LowerLevelDefinition(org.ballerinalang.plugins.idea.psi.scopes.LowerLevelDefinition) ScopeNode(org.antlr.jetbrains.adaptor.psi.ScopeNode) LinkedList(java.util.LinkedList) CodeBlockScope(org.ballerinalang.plugins.idea.psi.scopes.CodeBlockScope) TopLevelDefinition(org.ballerinalang.plugins.idea.psi.scopes.TopLevelDefinition) NotNull(org.jetbrains.annotations.NotNull)

Example 3 with IdentifierPSINode

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

the class BallerinaPsiImplUtil method getStructDefinition.

/**
 * Finds a {@link StructDefinitionNode} which corresponds to the provided {@link VariableReferenceNode}.
 *
 * @param variableReferenceNode   an variable reference node in the assignment statement node
 * @param assignmentStatementNode an assignment statement node
 * @param structReferenceNode     an identifier which is a var variable in the assignment node
 * @return
 */
private static StructDefinitionNode getStructDefinition(@NotNull VariableReferenceNode variableReferenceNode, @NotNull AssignmentStatementNode assignmentStatementNode, @NotNull IdentifierPSINode structReferenceNode) {
    InvocationNode invocationNode = PsiTreeUtil.getChildOfType(variableReferenceNode, InvocationNode.class);
    if (invocationNode != null) {
        AnyIdentifierNameNode anyIdentifierNameNode = PsiTreeUtil.getChildOfType(invocationNode, AnyIdentifierNameNode.class);
        if (anyIdentifierNameNode != null) {
            IdentifierPSINode identifier = PsiTreeUtil.getChildOfType(anyIdentifierNameNode, IdentifierPSINode.class);
            if (identifier != null) {
                PsiReference reference = identifier.findReferenceAt(identifier.getTextLength());
                if (reference == null) {
                    return null;
                }
                PsiElement resolvedElement = reference.resolve();
                if (resolvedElement == null) {
                    return null;
                }
                // Check whether the resolved element's parent is a connector definition.
                PsiElement definitionNode = resolvedElement.getParent();
                if (!(definitionNode instanceof ActionDefinitionNode)) {
                    return null;
                }
                return getStructDefinition(assignmentStatementNode, structReferenceNode, definitionNode);
            }
        }
    }
    // Get the first child.
    PsiElement node = variableReferenceNode.getFirstChild();
    // If te first child is a VariableReferenceNode, it can be a function invocation.
    if (node instanceof VariableReferenceNode) {
        // Check whether the node is a function invocation.
        boolean isFunctionInvocation = isFunctionInvocation((VariableReferenceNode) node);
        if (isFunctionInvocation) {
            // If it is a function invocation, the first child node will contain the function name.
            PsiElement functionName = node.getFirstChild();
            // We need to resolve the function name to the corresponding function definition.
            PsiReference reference = functionName.findReferenceAt(functionName.getTextLength());
            if (reference == null) {
                return null;
            }
            PsiElement resolvedFunctionIdentifier = reference.resolve();
            if (resolvedFunctionIdentifier == null) {
                return null;
            }
            // Check whether the resolved element's parent is a function definition.
            PsiElement definitionNode = resolvedFunctionIdentifier.getParent();
            if (!(definitionNode instanceof FunctionDefinitionNode)) {
                return null;
            }
            return getStructDefinition(assignmentStatementNode, structReferenceNode, definitionNode);
        }
    } else if (node instanceof NameReferenceNode) {
        // If the node is a NameReferenceNode, that means RHS contains a variable.
        PsiReference reference = node.findReferenceAt(node.getTextLength());
        if (reference == null) {
            return null;
        }
        // We resolve that variable to the definition.
        PsiElement resolvedDefinition = reference.resolve();
        if (resolvedDefinition == null || !(resolvedDefinition instanceof IdentifierPSINode)) {
            return null;
        }
        // Then recursively call the findStructDefinition method to get the correct definition.
        return findStructDefinition((IdentifierPSINode) resolvedDefinition);
    } else if (node instanceof FunctionInvocationNode) {
        FunctionReferenceNode functionReferenceNode = PsiTreeUtil.getChildOfType(node, FunctionReferenceNode.class);
        if (functionReferenceNode == null) {
            return null;
        }
        PsiReference reference = functionReferenceNode.findReferenceAt(functionReferenceNode.getTextLength());
        if (reference == null) {
            return null;
        }
        PsiElement resolvedDefinition = reference.resolve();
        if (resolvedDefinition == null || !(resolvedDefinition instanceof IdentifierPSINode)) {
            return null;
        }
        PsiElement definitionNode = resolvedDefinition.getParent();
        if (!(definitionNode instanceof FunctionDefinitionNode)) {
            return null;
        }
        return getStructDefinition(assignmentStatementNode, structReferenceNode, definitionNode);
    }
    return null;
}
Also used : AnyIdentifierNameNode(org.ballerinalang.plugins.idea.psi.AnyIdentifierNameNode) FunctionDefinitionNode(org.ballerinalang.plugins.idea.psi.FunctionDefinitionNode) ActionDefinitionNode(org.ballerinalang.plugins.idea.psi.ActionDefinitionNode) IdentifierPSINode(org.ballerinalang.plugins.idea.psi.IdentifierPSINode) PsiReference(com.intellij.psi.PsiReference) VariableReferenceNode(org.ballerinalang.plugins.idea.psi.VariableReferenceNode) FunctionReferenceNode(org.ballerinalang.plugins.idea.psi.FunctionReferenceNode) InvocationNode(org.ballerinalang.plugins.idea.psi.InvocationNode) FunctionInvocationNode(org.ballerinalang.plugins.idea.psi.FunctionInvocationNode) PsiElement(com.intellij.psi.PsiElement) LeafPsiElement(com.intellij.psi.impl.source.tree.LeafPsiElement) NameReferenceNode(org.ballerinalang.plugins.idea.psi.NameReferenceNode) FunctionInvocationNode(org.ballerinalang.plugins.idea.psi.FunctionInvocationNode)

Example 4 with IdentifierPSINode

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

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

the class BallerinaPsiImplUtil method resolveElementInScope.

@Nullable
public static PsiElement resolveElementInScope(@NotNull IdentifierPSINode identifier, boolean matchLocalVariables, boolean matchParameters, boolean matchGlobalVariables, boolean matchConstants, boolean matchEndpoint) {
    ScopeNode scope = PsiTreeUtil.getParentOfType(identifier, CodeBlockScope.class, VariableContainer.class, TopLevelDefinition.class, LowerLevelDefinition.class);
    if (scope == null) {
        return null;
    }
    int caretOffset = identifier.getStartOffset();
    if (matchLocalVariables) {
        List<IdentifierPSINode> variables = BallerinaPsiImplUtil.getAllLocalVariablesInResolvableScope(scope, caretOffset);
        PsiElement element = getMatchingElement(identifier, variables);
        if (element != null) {
            return element;
        }
    }
    if (matchEndpoint) {
        List<IdentifierPSINode> endpoints = BallerinaPsiImplUtil.getAllEndpointsInResolvableScope(scope, caretOffset);
        PsiElement element = getMatchingElement(identifier, endpoints);
        if (element != null) {
            return element;
        }
    }
    if (matchParameters) {
        List<IdentifierPSINode> parameters = BallerinaPsiImplUtil.getAllParametersInResolvableScope(scope, caretOffset);
        PsiElement element = getMatchingElement(identifier, parameters);
        if (element != null) {
            return element;
        }
    }
    if (matchGlobalVariables) {
        List<IdentifierPSINode> globalVariables = BallerinaPsiImplUtil.getAllGlobalVariablesInResolvableScope(scope);
        PsiElement element = getMatchingElement(identifier, globalVariables);
        if (element != null) {
            return element;
        }
    }
    if (matchConstants) {
        List<IdentifierPSINode> constants = BallerinaPsiImplUtil.getAllConstantsInResolvableScope(scope);
        PsiElement element = getMatchingElement(identifier, constants);
        if (element != null) {
            return element;
        }
    }
    return null;
}
Also used : IdentifierPSINode(org.ballerinalang.plugins.idea.psi.IdentifierPSINode) ScopeNode(org.antlr.jetbrains.adaptor.psi.ScopeNode) PsiElement(com.intellij.psi.PsiElement) LeafPsiElement(com.intellij.psi.impl.source.tree.LeafPsiElement) Nullable(org.jetbrains.annotations.Nullable)

Aggregations

IdentifierPSINode (org.ballerinalang.plugins.idea.psi.IdentifierPSINode)109 PsiElement (com.intellij.psi.PsiElement)70 NotNull (org.jetbrains.annotations.NotNull)63 LinkedList (java.util.LinkedList)58 LookupElement (com.intellij.codeInsight.lookup.LookupElement)48 Nullable (org.jetbrains.annotations.Nullable)32 PsiDirectory (com.intellij.psi.PsiDirectory)29 PsiReference (com.intellij.psi.PsiReference)25 PsiFile (com.intellij.psi.PsiFile)24 PackageNameNode (org.ballerinalang.plugins.idea.psi.PackageNameNode)20 LeafPsiElement (com.intellij.psi.impl.source.tree.LeafPsiElement)17 ScopeNode (org.antlr.jetbrains.adaptor.psi.ScopeNode)15 PrioritizedLookupElement (com.intellij.codeInsight.completion.PrioritizedLookupElement)12 FieldDefinitionNode (org.ballerinalang.plugins.idea.psi.FieldDefinitionNode)12 StructDefinitionNode (org.ballerinalang.plugins.idea.psi.StructDefinitionNode)12 VariableDefinitionNode (org.ballerinalang.plugins.idea.psi.VariableDefinitionNode)10 GlobalVariableDefinitionNode (org.ballerinalang.plugins.idea.psi.GlobalVariableDefinitionNode)9 TypeNameNode (org.ballerinalang.plugins.idea.psi.TypeNameNode)9 ArrayList (java.util.ArrayList)8 NameReferenceNode (org.ballerinalang.plugins.idea.psi.NameReferenceNode)8