use of org.ballerinalang.plugins.idea.psi.IdentifierPSINode in project ballerina by ballerina-lang.
the class EnumFieldReference method resolve.
@Nullable
@Override
public PsiElement resolve() {
IdentifierPSINode identifier = getElement();
PsiElement dot = PsiTreeUtil.prevVisibleLeaf(identifier);
if (dot == null || !".".equals(dot.getText())) {
return null;
}
PsiElement enumReferenceNode = PsiTreeUtil.prevVisibleLeaf(dot);
if (enumReferenceNode == null) {
return null;
}
PsiReference reference = enumReferenceNode.findReferenceAt(enumReferenceNode.getTextLength());
if (reference == null) {
return null;
}
PsiElement resolvedElement = reference.resolve();
if (resolvedElement == null) {
return null;
}
PsiElement resolvedElementParent = resolvedElement.getParent();
if (!(resolvedElementParent instanceof EnumDefinitionNode)) {
return null;
}
return ((EnumDefinitionNode) resolvedElementParent).resolve(identifier);
}
use of org.ballerinalang.plugins.idea.psi.IdentifierPSINode in project ballerina by ballerina-lang.
the class EnumReference method resolve.
@Nullable
@Override
public PsiElement resolve() {
IdentifierPSINode identifier = getElement();
PsiElement parent = identifier.getParent();
PackageNameNode packageNameNode = PsiTreeUtil.getChildOfType(parent, PackageNameNode.class);
if (packageNameNode == null) {
return resolveInCurrentPackage(identifier);
} else {
return resolveInPackage(packageNameNode, identifier);
}
}
use of org.ballerinalang.plugins.idea.psi.IdentifierPSINode in project ballerina by ballerina-lang.
the class FieldReference method resolve.
@Nullable
@Override
public PsiElement resolve() {
// Get the current element.
IdentifierPSINode identifier = getElement();
// Get the parent element.
PsiElement parent = identifier.getParent();
PsiElement prevSibling;
// resolve multi level structs. Eg: user.name.<caret>
if (parent instanceof StatementNode) {
// Get the previous element.
PsiElement prevVisibleLeaf = PsiTreeUtil.prevVisibleLeaf(parent);
if (prevVisibleLeaf == null) {
return null;
}
// Previous leaf element should be "." if the references are correctly defined.
if (!".".equals(prevVisibleLeaf.getText())) {
return null;
}
// Get the prevSibling. This is used to resolve the current field.
prevSibling = PsiTreeUtil.prevVisibleLeaf(prevVisibleLeaf);
if (prevSibling == null) {
return null;
}
} else if (parent instanceof NameReferenceNode) {
prevSibling = PsiTreeUtil.prevVisibleLeaf(parent);
if (prevSibling != null && ".".equals(prevSibling.getText())) {
prevSibling = PsiTreeUtil.prevVisibleLeaf(prevSibling);
}
} else {
PsiElement parentPrevSibling = parent.getPrevSibling();
if (parentPrevSibling != null) {
if (parentPrevSibling instanceof VariableReferenceNode) {
PsiElement[] children = parentPrevSibling.getChildren();
if (children.length <= 0) {
return null;
}
PsiElement firstChild = children[0].getFirstChild();
if (firstChild == null) {
return null;
}
prevSibling = firstChild;
} else {
return null;
}
} else {
// If the current statement is correctly resolved, that means all the fields are identified properly.
// Get the prevSibling. This is used to resolve the current field.
prevSibling = PsiTreeUtil.prevVisibleLeaf(parent);
}
}
// If the prevSibling is null, we return from this method because we cannot resolve the element.
if (prevSibling == null) {
return null;
}
// We get the reference at end. This is because struct field access can be multiple levels deep.
// Eg: user.name.first - If the current node is 'first', then the previous node will be 'user.name'. If
// we get the reference at the beginning, we we get the reference for 'user'. But we want to resolve the
// 'name' field first. That is why we get the reference at the end.
PsiReference variableReference = prevSibling.findReferenceAt(prevSibling.getTextLength());
if (variableReference == null) {
return null;
}
// Resolve the reference. The resolved element can be an identifier of either a struct of a field
// depending on the current node.
// Eg: user.name.firstName - If the current node is 'name', resolved element will be a struct definition. if
// the current element is 'firstName', then the resolved element will be a field definition.
PsiElement resolvedElement = variableReference.resolve();
if (resolvedElement == null || !(resolvedElement instanceof IdentifierPSINode)) {
return null;
}
// Get the parent of the resolved element.
PsiElement resolvedElementParent = resolvedElement.getParent();
StructDefinitionNode structDefinitionNode = null;
// Resolve the corresponding resolvedElementParent to get the struct definition.
if (resolvedElementParent instanceof VariableDefinitionNode || resolvedElementParent instanceof CodeBlockParameterNode || resolvedElementParent instanceof ParameterNode) {
// Resolve the Type of the VariableDefinitionNode to get the corresponding struct.
// Eg: User user = {}
// In here, "User" is resolved and struct identifier is returned.
structDefinitionNode = BallerinaPsiImplUtil.resolveStructFromDefinitionNode(resolvedElementParent);
} else if (resolvedElementParent instanceof FieldDefinitionNode) {
// If the resolvedElementParent is of type FieldDefinitionNode, that means we need to resolve the type of
// the field to get the struct definition.
// Eg: user.name.firstName - In here, if we want to resolve the 'firstName' we will get the 'Name name;'
// field. So we need to resolve the type of the field which is 'Name'. Then we will get the Name struct.
// Then we need to get the 'firstName' field from that.
structDefinitionNode = BallerinaPsiImplUtil.resolveTypeNodeStruct((resolvedElementParent));
} else if (resolvedElementParent instanceof NameReferenceNode) {
structDefinitionNode = BallerinaPsiImplUtil.findStructDefinition((IdentifierPSINode) resolvedElement);
} else if (resolvedElementParent instanceof EnumDefinitionNode) {
return ((EnumDefinitionNode) resolvedElementParent).resolve(identifier);
}
if (structDefinitionNode == null) {
return null;
}
// Resolve the field and return the resolved element.
return structDefinitionNode.resolve(identifier);
}
use of org.ballerinalang.plugins.idea.psi.IdentifierPSINode in project ballerina by ballerina-lang.
the class FunctionReference method resolve.
@Nullable
@Override
public PsiElement resolve() {
IdentifierPSINode identifier = getElement();
PsiElement parent = identifier.getParent();
PackageNameNode packageNameNode = PsiTreeUtil.getChildOfType(parent, PackageNameNode.class);
if (packageNameNode == null) {
return resolveInCurrentPackage(identifier);
} else {
return resolveInPackage(packageNameNode, identifier);
}
}
use of org.ballerinalang.plugins.idea.psi.IdentifierPSINode in project ballerina by ballerina-lang.
the class FunctionReference method getVariants.
@NotNull
@Override
public Object[] getVariants() {
List<LookupElement> results = new LinkedList<>();
IdentifierPSINode identifier = getElement();
PsiElement parent = identifier.getParent();
PackageNameNode packageNameNode = PsiTreeUtil.getChildOfType(parent, PackageNameNode.class);
if (packageNameNode == null) {
results.addAll(getVariantsFromCurrentPackage());
} else {
results.addAll(getVariantsFromPackage(packageNameNode));
}
return results.toArray(new LookupElement[results.size()]);
}
Aggregations