Skip to content

Commit

Permalink
fix: improve folding
Browse files Browse the repository at this point in the history
1. Folding for evaluate when clause
2. Folding for if clause to not include else block

Signed-off-by: Aman Prashant <aman.prashant@broadcom.com>
  • Loading branch information
ap891843 committed Jan 11, 2024
1 parent d6831fa commit 721a498
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,7 @@ public FoldingRangeHandler(DocumentModelService documentService, AsyncAnalysisSe
*/
public List<FoldingRange> foldingRange(FoldingRangeRequestParams params) {
String uri = uriDecodeService.decode(params.getTextDocument().getUri());
Node rootNode =
documentService.isDocumentSynced(uri)
? documentService.get(uri).getAnalysisResult().getRootNode()
: null;
Node rootNode = documentService.get(uri).getAnalysisResult().getRootNode();
return new ArrayList<>(DocumentServiceHelper.getFoldingRange(rootNode, uri));
}

Expand All @@ -71,8 +68,9 @@ public List<FoldingRange> foldingRange(FoldingRangeRequestParams params) {
public LspEvent<List<FoldingRange>> createEvent(FoldingRangeRequestParams params) {
String uri = uriDecodeService.decode(params.getTextDocument().getUri());
return new LspEvent<List<FoldingRange>>() {
final List<LspEventDependency> lspEventDependencies = ImmutableList.of(
asyncAnalysisService.createDependencyOn(uri));
final List<LspEventDependency> lspEventDependencies = ImmutableList.of(() ->
documentService.get(uri).getAnalysisResult() != null
&& documentService.get(uri).getAnalysisResult().getRootNode() != null);
final ImmutableList<LspEventCancelCondition> lspEventCancelConditions = ImmutableList.of(
asyncAnalysisService.createCancelConditionOnClose(uri));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,24 @@
import static org.eclipse.lsp.cobol.common.model.tree.Node.hasType;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.NonNull;
import lombok.experimental.UtilityClass;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.lsp.cobol.common.AnalysisResult;
import org.eclipse.lsp.cobol.common.model.NodeType;
import org.eclipse.lsp.cobol.common.model.tree.CopyNode;
import org.eclipse.lsp.cobol.common.model.tree.EvaluateNode;
import org.eclipse.lsp.cobol.common.model.tree.EvaluateWhenNode;
import org.eclipse.lsp.cobol.common.model.tree.EvaluateWhenOtherNode;
import org.eclipse.lsp.cobol.common.model.tree.IfElseNode;
import org.eclipse.lsp.cobol.common.model.tree.IfNode;
import org.eclipse.lsp.cobol.common.model.tree.Node;
import org.eclipse.lsp4j.FoldingRange;

Expand Down Expand Up @@ -55,8 +65,7 @@ public class DocumentServiceHelper {
* @param uri
* @return Set of folding ranges
*/
public static Set<FoldingRange> getFoldingRange(Node rootNode, String uri) {
if (Objects.isNull(rootNode)) return ImmutableSet.of();
public static Set<FoldingRange> getFoldingRange(@NonNull Node rootNode, @NonNull String uri) {
return rootNode
.getDepthFirstStream()
.filter(node -> node.getLocality().getUri().equals(uri))
Expand All @@ -65,14 +74,63 @@ public static Set<FoldingRange> getFoldingRange(Node rootNode, String uri) {
node ->
node.getLocality().getRange().getStart().getLine()
!= node.getLocality().getRange().getEnd().getLine())
.map(
node ->
new FoldingRange(
node.getLocality().getRange().getStart().getLine(),
node.getLocality().getRange().getEnd().getLine()))
.map(DocumentServiceHelper::getFoldingRange)
.flatMap(List::stream)
.collect(Collectors.toSet());
}

private static FoldingRange getFoldingRange(List<Node> node) {
IntSummaryStatistics start =
node.stream()
.map(n -> n.getLocality().getRange().getStart().getLine())
.collect(Collectors.summarizingInt(Integer::intValue));
IntSummaryStatistics end =
node.stream()
.map(n -> n.getLocality().getRange().getEnd().getLine())
.collect(Collectors.summarizingInt(Integer::intValue));
return new FoldingRange(start.getMin(), end.getMax());
}

private static List<FoldingRange> getFoldingRange(IfNode node) {
List<Node> ifThenStatements =
node.getChildren().stream().filter(n -> !(n instanceof IfElseNode)).collect(toList());
return ImmutableList.of(getFoldingRange(ifThenStatements));
}

private static List<FoldingRange> getFoldingRange(EvaluateNode node) {
Map<Node, List<Node>> accumulator = new HashMap<>();
Node lastEvaluateNode = null;
for (Node child : node.getChildren()) {
if (child instanceof EvaluateWhenNode || child instanceof EvaluateWhenOtherNode) {
lastEvaluateNode = child;
accumulator.putIfAbsent(lastEvaluateNode, new ArrayList<>());
}
if (lastEvaluateNode == null) continue;
accumulator.get(lastEvaluateNode).add(child);
}
return accumulator.values().stream()
.map(DocumentServiceHelper::getFoldingRange)
.collect(toList());
}

private static List<FoldingRange> getFoldingRange(Node node) {
if (node instanceof IfNode) {
return getFoldingRange((IfNode) node);
}
if (node instanceof EvaluateNode) {
List<FoldingRange> foldingRange = getFoldingRange((EvaluateNode) node);
foldingRange.add(getFoldingRangeFromNode(node));
return foldingRange;
}
return ImmutableList.of(getFoldingRangeFromNode(node));
}

private static FoldingRange getFoldingRangeFromNode(Node node) {
return new FoldingRange(
node.getLocality().getRange().getStart().getLine(),
node.getLocality().getRange().getEnd().getLine());
}

/**
* Extracts copybook uris from analysis result
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,17 @@

import java.util.Set;
import org.eclipse.lsp.cobol.common.model.Locality;
import org.eclipse.lsp.cobol.common.model.tree.EvaluateNode;
import org.eclipse.lsp.cobol.common.model.tree.EvaluateWhenNode;
import org.eclipse.lsp.cobol.common.model.tree.ExitNode;
import org.eclipse.lsp.cobol.common.model.tree.IfNode;
import org.eclipse.lsp.cobol.common.model.tree.Node;
import org.eclipse.lsp.cobol.common.model.tree.RootNode;
import org.eclipse.lsp.cobol.common.model.tree.variable.QualifiedReferenceNode;
import org.eclipse.lsp4j.FoldingRange;
import org.eclipse.lsp4j.Position;
import org.eclipse.lsp4j.Range;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;

/** Tests {@link DocumentServiceHelper} */
Expand All @@ -33,6 +37,7 @@ class DocumentServiceHelperTest {
public static final String DOCUMENT_URI = "file:///c:/workspace/document.cbl";

@Test
@Disabled("No longer valid")
void getFoldingRange_whenRootNodelIsNull() {
Set<FoldingRange> foldingRange = DocumentServiceHelper.getFoldingRange(null, DOCUMENT_URI);
assertEquals(0, foldingRange.size());
Expand Down Expand Up @@ -68,6 +73,32 @@ void getFoldingRange_whenNoConditionalNodePresent() {
assertEquals(0, foldingRange.size());
}

@Test
void getFoldingRange_whenEvaluateStatementIsPresent() {
RootNode rootNode = new RootNode(LOCALITY);
EvaluateNode evaluateNode = new EvaluateNode(Locality.builder()
.range(new Range(new Position(0, 0), new Position(10, 10)))
.uri(DOCUMENT_URI).build());
EvaluateWhenNode evaluateWhenNode = new EvaluateWhenNode(Locality.builder()
.range(new Range(new Position(2, 0), new Position(4, 10)))
.uri(DOCUMENT_URI).build());
EvaluateWhenNode evaluateWhenNode2 = new EvaluateWhenNode(Locality.builder()
.range(new Range(new Position(5, 0), new Position(6, 10)))
.uri(DOCUMENT_URI).build());
IfNode ifNode = new IfNode(Locality.builder()
.range(new Range(new Position(3, 0), new Position(4, 10)))
.uri(DOCUMENT_URI).build());
ifNode.addChild(new QualifiedReferenceNode(Locality.builder()
.range(new Range(new Position(3, 0), new Position(4, 10)))
.uri(DOCUMENT_URI).build()));
evaluateWhenNode.addChild(ifNode);
evaluateNode.addChild(evaluateWhenNode);
evaluateNode.addChild(evaluateWhenNode2);
rootNode.addChild(evaluateNode);
Set<FoldingRange> foldingRange = DocumentServiceHelper.getFoldingRange(rootNode, DOCUMENT_URI);
assertEquals(4, foldingRange.size());
}

private static Node getRootNode() {
Node rootNode = new RootNode(LOCALITY);
Node ifNode =
Expand Down

0 comments on commit 721a498

Please sign in to comment.