use of org.ballerinalang.langserver.common.LSDocument in project ballerina by ballerina-lang.
the class RenameUtil method getRenameTextEdits.
/**
* Get the list of rename related TextEdits.
*
* @param locationList List of locations of occurrences
* @param documentManager {@link WorkspaceDocumentManager} instance
* @param newName New name to be replaced with
* @param replaceSymbolName Symbol name being replaced
* @return {@link List} List of TextEdits
*/
public static List<TextDocumentEdit> getRenameTextEdits(List<Location> locationList, WorkspaceDocumentManager documentManager, String newName, String replaceSymbolName) {
Map<String, ArrayList<Location>> documentLocationMap = new HashMap<>();
List<TextDocumentEdit> documentEdits = new ArrayList<>();
Comparator<Location> locationComparator = (location1, location2) -> location1.getRange().getStart().getCharacter() - location2.getRange().getStart().getCharacter();
locationList.forEach(location -> {
if (documentLocationMap.containsKey(location.getUri())) {
documentLocationMap.get(location.getUri()).add(location);
} else {
documentLocationMap.put(location.getUri(), (ArrayList<Location>) Lists.of(location));
}
});
documentLocationMap.forEach((uri, locations) -> {
Collections.sort(locations, locationComparator);
String fileContent = documentManager.getFileContent(CommonUtil.getPath(new LSDocument(uri)));
String[] contentComponents = fileContent.split("\\n|\\r\\n|\\r");
int lastNewLineCharIndex = Math.max(fileContent.lastIndexOf("\n"), fileContent.lastIndexOf("\r"));
int lastCharCol = fileContent.substring(lastNewLineCharIndex + 1).length();
for (Location location : locations) {
int line = location.getRange().getStart().getLine();
StringBuilder lineComponent = new StringBuilder(contentComponents[line]);
int index = lineComponent.indexOf(replaceSymbolName);
while (index >= 0) {
char previousChar = lineComponent.charAt(index - 1);
if (Character.isLetterOrDigit(previousChar) || String.valueOf(previousChar).equals("_")) {
index = lineComponent.indexOf(replaceSymbolName, index + replaceSymbolName.length());
} else {
lineComponent.replace(index, index + replaceSymbolName.length(), newName);
index = lineComponent.indexOf(replaceSymbolName, index + newName.length());
}
}
contentComponents[line] = lineComponent.toString();
}
Range range = new Range(new Position(0, 0), new Position(contentComponents.length, lastCharCol));
TextEdit textEdit = new TextEdit(range, String.join("\r\n", Arrays.asList(contentComponents)));
VersionedTextDocumentIdentifier textDocumentIdentifier = new VersionedTextDocumentIdentifier();
textDocumentIdentifier.setUri(uri);
TextDocumentEdit textDocumentEdit = new TextDocumentEdit(textDocumentIdentifier, Collections.singletonList(textEdit));
documentEdits.add(textDocumentEdit);
});
return documentEdits;
}
use of org.ballerinalang.langserver.common.LSDocument 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.ballerinalang.langserver.common.LSDocument in project ballerina by ballerina-lang.
the class ReferencesTreeVisitor method getLocation.
/**
* Get the physical source location of the given package.
*
* @param bLangNode ballerina language node references are requested for
* @param ownerPackageName list of name compositions of the node's package name
* @param currentPackageName list of name compositions of the current package
* @return location of the package of the given node
*/
private Location getLocation(BLangNode bLangNode, String ownerPackageName, String currentPackageName) {
Location l = new Location();
Range r = new Range();
TextDocumentPositionParams position = this.context.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(currentPackageName, parentPath.toString(), ownerPackageName), fileName);
l.setUri(filePath.toUri().toString());
// 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);
}
return l;
}
use of org.ballerinalang.langserver.common.LSDocument in project ballerina by ballerina-lang.
the class TextDocumentServiceUtil method getBLangPackage.
/**
* Get the BLangPackage for a given program.
*
* @param context Language Server Context
* @param docManager Document manager
* @param preserveWhitespace Enable preserve whitespace
* @param customErrorStrategy custom error strategy class
* @param compileFullProject compile full project from the source root
* @return {@link BLangPackage} BLang Package
*/
public static List<BLangPackage> getBLangPackage(LanguageServerContext context, WorkspaceDocumentManager docManager, boolean preserveWhitespace, Class customErrorStrategy, boolean compileFullProject) {
String uri = context.get(DocumentServiceKeys.FILE_URI_KEY);
LSDocument document = new LSDocument(uri);
Path filePath = CommonUtil.getPath(document);
Path fileNamePath = filePath.getFileName();
String fileName = "";
if (fileNamePath != null) {
fileName = fileNamePath.toString();
}
String sourceRoot = TextDocumentServiceUtil.getSourceRoot(filePath);
String pkgName = TextDocumentServiceUtil.getPackageNameForGivenFile(sourceRoot, filePath.toString());
LSDocument sourceDocument = new LSDocument();
sourceDocument.setUri(uri);
sourceDocument.setSourceRoot(sourceRoot);
PackageRepository packageRepository = new WorkspacePackageRepository(sourceRoot, docManager);
List<BLangPackage> packages = new ArrayList<>();
if (compileFullProject) {
if (!sourceRoot.isEmpty()) {
File projectDir = new File(sourceRoot);
File[] files = projectDir.listFiles();
if (files != null) {
for (File file : files) {
if ((file.isDirectory() && !file.getName().startsWith(".")) || (!file.isDirectory() && file.getName().endsWith(".bal"))) {
Compiler compiler = getCompiler(context, fileName, packageRepository, sourceDocument, preserveWhitespace, customErrorStrategy, docManager);
packages.add(compiler.compile(file.getName()));
}
}
}
}
} else {
Compiler compiler = getCompiler(context, fileName, packageRepository, sourceDocument, preserveWhitespace, customErrorStrategy, docManager);
if ("".equals(pkgName)) {
packages.add(compiler.compile(fileName));
} else {
packages.add(compiler.compile(pkgName));
}
}
return packages;
}
use of org.ballerinalang.langserver.common.LSDocument in project ballerina by ballerina-lang.
the class BallerinaTextDocumentService method didClose.
@Override
public void didClose(DidCloseTextDocumentParams params) {
LSDocument document = new LSDocument(params.getTextDocument().getUri());
Path closedPath = CommonUtil.getPath(document);
if (closedPath == null) {
return;
}
this.documentManager.closeFile(CommonUtil.getPath(document));
}
Aggregations