use of org.wso2.charon3.core.utils.codeutils.Node in project ballerina by ballerina-lang.
the class TreeVisitor method isWithinParameterContext.
/**
* Check whether the cursor resides within the given node type's parameter context.
* Node name is used to identify the correct node
* @param nodeName Name of the node
* @param nodeType Node type (Function, Resource, Action or Connector)
* @return {@link Boolean} Whether the cursor is within the parameter context
*/
private boolean isWithinParameterContext(String nodeName, String nodeType) {
ParserRuleContext parserRuleContext = documentServiceContext.get(DocumentServiceKeys.PARSER_RULE_CONTEXT_KEY);
TokenStream tokenStream = documentServiceContext.get(DocumentServiceKeys.TOKEN_STREAM_KEY);
String terminalToken = "";
// If the parser rule context is not parameter context or parameter list context, we skipp the calculation
if (!(parserRuleContext instanceof BallerinaParser.ParameterContext || parserRuleContext instanceof BallerinaParser.ParameterListContext)) {
return false;
}
int startTokenIndex = parserRuleContext.getStart().getTokenIndex();
ArrayList<String> terminalKeywords = new ArrayList<>(Arrays.asList(NODE_TYPE_ACTION, NODE_TYPE_CONNECTOR, NODE_TYPE_FUNCTION, NODE_TYPE_RESOURCE));
ArrayList<Token> filteredTokens = new ArrayList<>();
Token openBracket = null;
boolean isWithinParams = false;
// Find the index of the closing bracket
while (true) {
if (startTokenIndex > tokenStream.size()) {
// In the ideal case, should not reach this point
startTokenIndex = -1;
break;
}
Token token = tokenStream.get(startTokenIndex);
String tokenString = token.getText();
if (tokenString.equals(")")) {
break;
}
startTokenIndex++;
}
// Backtrack the token stream to find a terminal token
while (true) {
if (startTokenIndex < 0) {
break;
}
Token token = tokenStream.get(startTokenIndex);
String tokenString = token.getText();
if (terminalKeywords.contains(tokenString)) {
terminalToken = tokenString;
break;
}
if (token.getChannel() == Token.DEFAULT_CHANNEL) {
filteredTokens.add(token);
}
startTokenIndex--;
}
Collections.reverse(filteredTokens);
/*
This particular logic identifies a matching pair of closing and opening bracket and then check whether the
cursor is within those bracket pair
*/
if (nodeName.equals(filteredTokens.get(0).getText()) && terminalToken.equals(nodeType)) {
String tokenText;
for (Token token : filteredTokens) {
tokenText = token.getText();
if (tokenText.equals("(")) {
openBracket = token;
} else if (tokenText.equals(")") && openBracket != null) {
Position cursorPos = documentServiceContext.get(DocumentServiceKeys.POSITION_KEY).getPosition();
int openBLine = openBracket.getLine() - 1;
int openBCol = openBracket.getCharPositionInLine();
int closeBLine = token.getLine() - 1;
int closeBCol = token.getCharPositionInLine();
int cursorLine = cursorPos.getLine();
int cursorCol = cursorPos.getCharacter();
isWithinParams = (cursorLine > openBLine && cursorLine < closeBLine) || (cursorLine == openBLine && cursorCol > openBCol && cursorLine < closeBLine) || (cursorLine > openBLine && cursorCol < closeBCol && cursorLine == closeBLine) || (cursorLine == openBLine && cursorLine == closeBLine && cursorCol >= openBCol && cursorCol <= closeBCol);
if (isWithinParams) {
break;
} else {
openBracket = null;
}
}
}
}
return isWithinParams;
}
use of org.wso2.charon3.core.utils.codeutils.Node in project ballerina by ballerina-lang.
the class TreeVisitor method visit.
// Visitor methods
public void visit(BLangPackage pkgNode) {
SymbolEnv pkgEnv = this.symTable.pkgEnvMap.get(pkgNode.symbol);
// Then visit each top-level element sorted using the compilation unit
String fileName = documentServiceContext.get(DocumentServiceKeys.FILE_NAME_KEY);
List<TopLevelNode> topLevelNodes = pkgNode.topLevelNodes.stream().filter(node -> node.getPosition().getSource().getCompilationUnitName().equals(fileName)).collect(Collectors.toList());
if (topLevelNodes.isEmpty()) {
this.setTerminateVisitor(true);
acceptNode(null, null);
} else {
cursorPositionResolver = PackageNodeScopeResolver.class;
topLevelNodes.forEach(topLevelNode -> {
cursorPositionResolver = TopLevelNodeScopeResolver.class;
this.blockOwnerStack.push(pkgNode);
acceptNode((BLangNode) topLevelNode, pkgEnv);
});
}
}
use of org.wso2.charon3.core.utils.codeutils.Node in project ballerina by ballerina-lang.
the class TreeVisitor method acceptNode.
// Private Methods
private void acceptNode(BLangNode node, SymbolEnv env) {
if (this.terminateVisitor) {
return;
}
SymbolEnv prevEnv = this.symbolEnv;
this.symbolEnv = env;
node.accept(this);
this.symbolEnv = prevEnv;
this.setPreviousNode(node);
}
use of org.wso2.charon3.core.utils.codeutils.Node in project ballerina by ballerina-lang.
the class DefinitionUtil method getDefinitionPosition.
/**
* Get definition position for the given definition context.
*
* @param definitionContext context of the definition.
* @param lSPackageCache package context for language server.
* @return position
*/
public static List<Location> getDefinitionPosition(TextDocumentServiceContext definitionContext, LSPackageCache lSPackageCache) {
List<Location> contents = new ArrayList<>();
if (definitionContext.get(NodeContextKeys.SYMBOL_KIND_OF_NODE_KEY) == null) {
return contents;
}
String nodeKind = definitionContext.get(NodeContextKeys.SYMBOL_KIND_OF_NODE_KEY);
BLangPackage bLangPackage = getPackageOfTheOwner(definitionContext.get(NodeContextKeys.NODE_OWNER_PACKAGE_KEY), definitionContext, lSPackageCache);
BLangNode bLangNode = null;
switch(nodeKind) {
case ContextConstants.FUNCTION:
bLangNode = bLangPackage.functions.stream().filter(function -> function.name.getValue().equals(definitionContext.get(NodeContextKeys.NAME_OF_NODE_KEY))).findAny().orElse(null);
break;
case ContextConstants.STRUCT:
bLangNode = bLangPackage.structs.stream().filter(struct -> struct.name.getValue().equals(definitionContext.get(NodeContextKeys.NAME_OF_NODE_KEY))).findAny().orElse(null);
break;
case ContextConstants.OBJECT:
bLangNode = bLangPackage.objects.stream().filter(object -> object.name.getValue().equals(definitionContext.get(NodeContextKeys.NAME_OF_NODE_KEY))).findAny().orElse(null);
break;
case ContextConstants.ENUM:
bLangNode = bLangPackage.enums.stream().filter(enm -> enm.name.getValue().equals(definitionContext.get(NodeContextKeys.NAME_OF_NODE_KEY))).findAny().orElse(null);
// Fixing the position issue with enum node.
bLangNode.getPosition().eLine = bLangNode.getPosition().sLine;
bLangNode.getPosition().eCol = bLangNode.getPosition().sCol;
break;
case ContextConstants.CONNECTOR:
bLangNode = bLangPackage.connectors.stream().filter(bConnector -> bConnector.name.getValue().equals(definitionContext.get(NodeContextKeys.NAME_OF_NODE_KEY))).findAny().orElse(null);
break;
case ContextConstants.ACTION:
bLangNode = bLangPackage.connectors.stream().filter(bConnector -> bConnector.name.getValue().equals(((BLangInvocation) definitionContext.get(NodeContextKeys.PREVIOUSLY_VISITED_NODE_KEY)).symbol.owner.name.getValue())).flatMap(connector -> connector.actions.stream()).filter(bAction -> bAction.name.getValue().equals(definitionContext.get(NodeContextKeys.NAME_OF_NODE_KEY))).findAny().orElse(null);
break;
case ContextConstants.TRANSFORMER:
bLangNode = bLangPackage.transformers.stream().filter(bTransformer -> bTransformer.name.getValue().equals(definitionContext.get(NodeContextKeys.NAME_OF_NODE_KEY))).findAny().orElse(null);
break;
case ContextConstants.ENDPOINT:
bLangNode = bLangPackage.globalEndpoints.stream().filter(globalEndpoint -> globalEndpoint.name.value.equals(definitionContext.get(NodeContextKeys.NAME_OF_NODE_KEY))).findAny().orElse(null);
if (bLangNode == null) {
DefinitionTreeVisitor definitionTreeVisitor = new DefinitionTreeVisitor(definitionContext);
definitionContext.get(NodeContextKeys.NODE_STACK_KEY).pop().accept(definitionTreeVisitor);
if (definitionContext.get(NodeContextKeys.NODE_KEY) != null) {
bLangNode = definitionContext.get(NodeContextKeys.NODE_KEY);
}
}
break;
case ContextConstants.VARIABLE:
bLangNode = bLangPackage.globalVars.stream().filter(globalVar -> globalVar.name.getValue().equals(definitionContext.get(NodeContextKeys.VAR_NAME_OF_NODE_KEY))).findAny().orElse(null);
// BLangNode is null only when node at the cursor position is a local variable.
if (bLangNode == null) {
DefinitionTreeVisitor definitionTreeVisitor = new DefinitionTreeVisitor(definitionContext);
definitionContext.get(NodeContextKeys.NODE_STACK_KEY).pop().accept(definitionTreeVisitor);
if (definitionContext.get(NodeContextKeys.NODE_KEY) != null) {
bLangNode = definitionContext.get(NodeContextKeys.NODE_KEY);
break;
}
}
break;
default:
break;
}
if (bLangNode == null) {
return contents;
}
Location l = new Location();
TextDocumentPositionParams position = definitionContext.get(DocumentServiceKeys.POSITION_KEY);
Path parentPath = CommonUtil.getPath(new LSDocument(position.getTextDocument().getUri())).getParent();
if (parentPath != null) {
String fileName = bLangNode.getPosition().getSource().getCompilationUnitName();
Path filePath = Paths.get(CommonUtil.getPackageURI(definitionContext.get(NodeContextKeys.PACKAGE_OF_NODE_KEY).name.getValue(), parentPath.toString(), definitionContext.get(NodeContextKeys.PACKAGE_OF_NODE_KEY).name.getValue()), fileName);
l.setUri(filePath.toUri().toString());
Range r = new Range();
// Subtract 1 to convert the token lines and char positions to zero based indexing
r.setStart(new Position(bLangNode.getPosition().getStartLine() - 1, bLangNode.getPosition().getStartColumn() - 1));
r.setEnd(new Position(bLangNode.getPosition().getEndLine() - 1, bLangNode.getPosition().getEndColumn() - 1));
l.setRange(r);
contents.add(l);
}
return contents;
}
use of org.wso2.charon3.core.utils.codeutils.Node in project ballerina by ballerina-lang.
the class HoverUtil method filterDocumentationAttributes.
/**
* Filter documentation attributes to each tags.
*
* @param bLangDocumentation documentation node
* @return {@link Map} filtered content map
*/
private static Map<String, List<BLangDocumentationAttribute>> filterDocumentationAttributes(BLangDocumentation bLangDocumentation) {
Map<String, List<BLangDocumentationAttribute>> filteredAttributes = new HashMap<>();
for (BLangDocumentationAttribute bLangDocumentationAttribute : bLangDocumentation.attributes) {
if (filteredAttributes.get(bLangDocumentationAttribute.docTag.name()) == null) {
filteredAttributes.put(bLangDocumentationAttribute.docTag.name(), new ArrayList<>());
filteredAttributes.get(bLangDocumentationAttribute.docTag.name()).add(bLangDocumentationAttribute);
} else {
filteredAttributes.get(bLangDocumentationAttribute.docTag.name()).add(bLangDocumentationAttribute);
}
}
return filteredAttributes;
}
Aggregations