Search in sources :

Example 1 with ParameterNode

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

the class BallerinaPsiImplUtil method findStructDefinition.

/**
 * Resolves the corresponding struct definition of the provided identifier node if possible.
 * Eg:
 * <pre>
 * function main (string[] args) {
 *     var person = getData();
 *     var person2 = person;
 *     var person3 = person2;
 *
 *     system:println(person3.&lt;caret&gt;);
 * }
 *
 * function getData () (Person) {
 *     Person person = {name:"Shan", age:26};
 *     return person;
 * }
 *
 * struct Person {
 *    string name;
 *    int age;
 * }
 * </pre>
 * <p>
 * From the above caret position, we should be able to get the type of the 'person3'. So we resolve recursively
 * until we find the struct definition. If the RHS has a variable, we resolve the definition of the variable and
 * call this method again. So in the first call of this function, 'resolvedElement' will be the
 * definition of 'person3'. Next, the definition of 'person2' and definition of 'person' after that. At that point,
 * we find a function invocation in the RHS. So we get the type from that.
 *
 * @param resolvedElement element which was resolved from the variable reference
 * @return corresponding {@link StructDefinitionNode} if the structName can be resolved, {@code null} otherwise.
 */
@Nullable
public static StructDefinitionNode findStructDefinition(@NotNull IdentifierPSINode resolvedElement) {
    // Since this method might get called recursively, it is better to check whether the process is cancelled in the
    // beginning.
    ProgressManager.checkCanceled();
    // Get the assignment statement parent node.
    AssignmentStatementNode assignmentStatementNode = PsiTreeUtil.getParentOfType(resolvedElement, AssignmentStatementNode.class);
    // count as a definition and does not resolve to it.
    if (assignmentStatementNode != null) {
        return getStructDefinition(assignmentStatementNode, resolvedElement);
    }
    // If the resolved element is not in an AssignmentStatement, we check for VariableDefinition parent node.
    // If there is a VariableDefinition parent node, finding the type is quite straight forward.
    VariableDefinitionNode variableDefinitionNode = PsiTreeUtil.getParentOfType(resolvedElement, VariableDefinitionNode.class);
    if (variableDefinitionNode != null) {
        return resolveStructFromDefinitionNode(variableDefinitionNode);
    }
    ParameterNode parameterNode = PsiTreeUtil.getParentOfType(resolvedElement, ParameterNode.class);
    if (parameterNode != null) {
        return resolveStructFromDefinitionNode(parameterNode);
    }
    return null;
}
Also used : GlobalVariableDefinitionNode(org.ballerinalang.plugins.idea.psi.GlobalVariableDefinitionNode) VariableDefinitionNode(org.ballerinalang.plugins.idea.psi.VariableDefinitionNode) AssignmentStatementNode(org.ballerinalang.plugins.idea.psi.AssignmentStatementNode) ParameterNode(org.ballerinalang.plugins.idea.psi.ParameterNode) ReturnParameterNode(org.ballerinalang.plugins.idea.psi.ReturnParameterNode) CodeBlockParameterNode(org.ballerinalang.plugins.idea.psi.CodeBlockParameterNode) Nullable(org.jetbrains.annotations.Nullable)

Example 2 with ParameterNode

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

the class BallerinaPsiImplUtil method getType.

/**
 * Returns the type of the provided identifier.
 *
 * @param identifier an identifier
 * @return the type of the identifier. This can be one of {@link ValueTypeNameNode} (for value types like string),
 * {@link BuiltInReferenceTypeNameNode} (for reference types like json) or {@link TypeNameNode} (for arrays).
 */
@Nullable
public static PsiElement getType(@NotNull IdentifierPSINode identifier) {
    PsiElement parent = identifier.getParent();
    // In case of lambda functions or functions attached to types.
    if (parent instanceof FunctionDefinitionNode) {
        CodeBlockParameterNode codeBlockParameterNode = PsiTreeUtil.getChildOfType(parent, CodeBlockParameterNode.class);
        if (codeBlockParameterNode != null) {
            TypeNameNode typeNameNode = PsiTreeUtil.getChildOfType(codeBlockParameterNode, TypeNameNode.class);
            if (typeNameNode != null) {
                return typeNameNode.getFirstChild();
            }
        }
    }
    PsiReference reference = identifier.findReferenceAt(0);
    if (reference != null) {
    // Todo - Do we need to consider this situation?
    }
    VariableDefinitionNode variableDefinitionNode = PsiTreeUtil.getParentOfType(identifier, VariableDefinitionNode.class);
    if (variableDefinitionNode != null) {
        PsiElement typeNode = getType(variableDefinitionNode);
        if (typeNode != null) {
            return typeNode;
        }
    }
    AssignmentStatementNode assignmentStatementNode = PsiTreeUtil.getParentOfType(identifier, AssignmentStatementNode.class);
    if (assignmentStatementNode != null) {
        PsiElement typeNode = getType(assignmentStatementNode, identifier);
        if (typeNode != null) {
            return typeNode;
        }
    }
    ParameterNode parameterNode = PsiTreeUtil.getParentOfType(identifier, ParameterNode.class);
    if (parameterNode != null) {
        PsiElement typeNode = getType(parameterNode);
        if (typeNode != null) {
            return typeNode;
        }
    }
    FieldDefinitionNode fieldDefinitionNode = PsiTreeUtil.getParentOfType(identifier, FieldDefinitionNode.class);
    if (fieldDefinitionNode != null) {
        PsiElement typeNode = getType(fieldDefinitionNode);
        if (typeNode != null) {
            return typeNode;
        }
    }
    return null;
}
Also used : GlobalVariableDefinitionNode(org.ballerinalang.plugins.idea.psi.GlobalVariableDefinitionNode) VariableDefinitionNode(org.ballerinalang.plugins.idea.psi.VariableDefinitionNode) AssignmentStatementNode(org.ballerinalang.plugins.idea.psi.AssignmentStatementNode) ParameterNode(org.ballerinalang.plugins.idea.psi.ParameterNode) ReturnParameterNode(org.ballerinalang.plugins.idea.psi.ReturnParameterNode) CodeBlockParameterNode(org.ballerinalang.plugins.idea.psi.CodeBlockParameterNode) FunctionDefinitionNode(org.ballerinalang.plugins.idea.psi.FunctionDefinitionNode) 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) PsiReference(com.intellij.psi.PsiReference) FieldDefinitionNode(org.ballerinalang.plugins.idea.psi.FieldDefinitionNode) PsiElement(com.intellij.psi.PsiElement) LeafPsiElement(com.intellij.psi.impl.source.tree.LeafPsiElement) CodeBlockParameterNode(org.ballerinalang.plugins.idea.psi.CodeBlockParameterNode) Nullable(org.jetbrains.annotations.Nullable)

Example 3 with ParameterNode

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

the class BallerinaPsiImplUtil method getAllParametersInScope.

@NotNull
private static List<IdentifierPSINode> getAllParametersInScope(@NotNull ScopeNode scope, int caretOffset) {
    List<IdentifierPSINode> results = new LinkedList<>();
    Collection<ParameterNode> parameterNodes = PsiTreeUtil.findChildrenOfType(scope, ParameterNode.class);
    for (ParameterNode parameter : parameterNodes) {
        ScopeNode parentScope = PsiTreeUtil.getParentOfType(parameter, ScopeNode.class);
        if (!scope.equals(parentScope)) {
            continue;
        }
        PsiElement identifier = parameter.getNameIdentifier();
        if (identifier != null && identifier instanceof IdentifierPSINode) {
            results.add(((IdentifierPSINode) identifier));
        }
    }
    Collection<CodeBlockParameterNode> codeBlockParameterNodes = PsiTreeUtil.findChildrenOfType(scope, CodeBlockParameterNode.class);
    for (CodeBlockParameterNode parameter : codeBlockParameterNodes) {
        PsiElement elementAtCaret = scope.getContainingFile().findElementAt(caretOffset);
        if (elementAtCaret == null) {
            return results;
        }
        if (parameter.getTextRange().getEndOffset() >= caretOffset) {
            return results;
        }
        ScopeNode closestScope = PsiTreeUtil.getParentOfType(parameter, ScopeNode.class);
        if (closestScope == null || !closestScope.equals(scope)) {
            continue;
        }
        PsiElement identifier = parameter.getNameIdentifier();
        if (identifier != null && identifier instanceof IdentifierPSINode) {
            results.add(((IdentifierPSINode) identifier));
        }
    }
    return results;
}
Also used : ParameterNode(org.ballerinalang.plugins.idea.psi.ParameterNode) ReturnParameterNode(org.ballerinalang.plugins.idea.psi.ReturnParameterNode) CodeBlockParameterNode(org.ballerinalang.plugins.idea.psi.CodeBlockParameterNode) IdentifierPSINode(org.ballerinalang.plugins.idea.psi.IdentifierPSINode) ScopeNode(org.antlr.jetbrains.adaptor.psi.ScopeNode) LinkedList(java.util.LinkedList) PsiElement(com.intellij.psi.PsiElement) LeafPsiElement(com.intellij.psi.impl.source.tree.LeafPsiElement) CodeBlockParameterNode(org.ballerinalang.plugins.idea.psi.CodeBlockParameterNode) NotNull(org.jetbrains.annotations.NotNull)

Example 4 with ParameterNode

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

the class BallerinaParameterInfoHandler method getParameterPresentations.

/**
 * Creates a list of parameter presentations.
 *
 * @param node parameterListNode which contains the parameters
 * @return list of parameter presentations
 */
public static List<String> getParameterPresentations(ParameterListNode node) {
    List<String> params = new LinkedList<>();
    if (node == null) {
        return params;
    }
    // Get parameter nodes.
    Collection<ParameterNode> parameterNodes = PsiTreeUtil.getChildrenOfTypeAsList(node, ParameterNode.class);
    for (ParameterNode parameterNode : parameterNodes) {
        // Parameters might have spaces in between. So we need to remove them as well.
        params.add(formatParameter(parameterNode.getText()));
    }
    return params;
}
Also used : ParameterNode(org.ballerinalang.plugins.idea.psi.ParameterNode) LinkedList(java.util.LinkedList)

Example 5 with ParameterNode

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

the class BallerinaDocumentationProvider method getReturnTypes.

/**
 * Returns the return types of the given definition node. This return types are later used to generate the
 * signature.
 *
 * @param definitionNode definition node which we want to get the return types
 * @return list of return type strings.
 */
private static List<String> getReturnTypes(PsiElement definitionNode) {
    List<String> results = new LinkedList<>();
    // Parameters are in the ReturnParameterNode. So we first get the ReturnParameterNode from the definition
    // node.
    ReturnParameterNode node = PsiTreeUtil.findChildOfType(definitionNode, ReturnParameterNode.class);
    if (node == null) {
        return results;
    }
    // But there can be two possible scenarios. The actual return types can be in either ParameterTypeNameList or
    // ParameterListNode. This is because return types can be named parameters. In that case, ParameterListNode is
    // available.
    // First we check for ParameterTypeNameList.
    ParameterTypeNameList parameterTypeNameList = PsiTreeUtil.findChildOfType(node, ParameterTypeNameList.class);
    // If it is available, that means the return types are not named parameters.
    if (parameterTypeNameList != null) {
        // Each parameter will be of type TypeNameNode. So we get all return types.
        Collection<ParameterTypeName> parameterTypeNames = PsiTreeUtil.getChildrenOfTypeAsList(parameterTypeNameList, ParameterTypeName.class);
        // Add each TypeNameNode to the result list.
        parameterTypeNames.forEach(parameterTypeName -> {
            TypeNameNode typeNameNode = PsiTreeUtil.getChildOfType(parameterTypeName, TypeNameNode.class);
            if (typeNameNode != null) {
                results.add(BallerinaParameterInfoHandler.formatParameter(typeNameNode.getText()));
            }
        });
        // Return the results.
        return results;
    }
    // If there is no return type node, we check for ParameterListNode.
    ParameterListNode parameterListNode = PsiTreeUtil.findChildOfType(node, ParameterListNode.class);
    if (parameterListNode != null) {
        // Actual parameters are in ParameterNodes.
        Collection<ParameterNode> parameterNodes = PsiTreeUtil.findChildrenOfType(parameterListNode, ParameterNode.class);
        // Add each ParameterNode to the result list.
        parameterNodes.forEach(parameterNode -> results.add(BallerinaParameterInfoHandler.formatParameter(parameterNode.getText())));
        // Return the results.
        return results;
    }
    // Return empty list.
    return results;
}
Also used : ParameterListNode(org.ballerinalang.plugins.idea.psi.ParameterListNode) ParameterNode(org.ballerinalang.plugins.idea.psi.ParameterNode) ReturnParameterNode(org.ballerinalang.plugins.idea.psi.ReturnParameterNode) ParameterTypeNameList(org.ballerinalang.plugins.idea.psi.ParameterTypeNameList) TypeNameNode(org.ballerinalang.plugins.idea.psi.TypeNameNode) ParameterTypeName(org.ballerinalang.plugins.idea.psi.ParameterTypeName) LinkedList(java.util.LinkedList) ReturnParameterNode(org.ballerinalang.plugins.idea.psi.ReturnParameterNode)

Aggregations

ParameterNode (org.ballerinalang.plugins.idea.psi.ParameterNode)17 PsiElement (com.intellij.psi.PsiElement)12 PsiReference (com.intellij.psi.PsiReference)9 CodeBlockParameterNode (org.ballerinalang.plugins.idea.psi.CodeBlockParameterNode)9 VariableDefinitionNode (org.ballerinalang.plugins.idea.psi.VariableDefinitionNode)9 ReturnParameterNode (org.ballerinalang.plugins.idea.psi.ReturnParameterNode)8 LeafPsiElement (com.intellij.psi.impl.source.tree.LeafPsiElement)7 GlobalVariableDefinitionNode (org.ballerinalang.plugins.idea.psi.GlobalVariableDefinitionNode)7 IdentifierPSINode (org.ballerinalang.plugins.idea.psi.IdentifierPSINode)7 StructDefinitionNode (org.ballerinalang.plugins.idea.psi.StructDefinitionNode)7 Nullable (org.jetbrains.annotations.Nullable)7 LinkedList (java.util.LinkedList)6 FieldDefinitionNode (org.ballerinalang.plugins.idea.psi.FieldDefinitionNode)6 ParameterListNode (org.ballerinalang.plugins.idea.psi.ParameterListNode)6 AssignmentStatementNode (org.ballerinalang.plugins.idea.psi.AssignmentStatementNode)5 TypeNameNode (org.ballerinalang.plugins.idea.psi.TypeNameNode)5 EnumDefinitionNode (org.ballerinalang.plugins.idea.psi.EnumDefinitionNode)4 FunctionDefinitionNode (org.ballerinalang.plugins.idea.psi.FunctionDefinitionNode)4 NameReferenceNode (org.ballerinalang.plugins.idea.psi.NameReferenceNode)4 NotNull (org.jetbrains.annotations.NotNull)4