Skip to content

Commit

Permalink
perf: Remove quadratic node check
Browse files Browse the repository at this point in the history
  • Loading branch information
slavek-kucera authored and ishche committed Oct 29, 2024
1 parent ce3cfe0 commit 8fe79ad
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,20 @@
*/
package org.eclipse.lsp.cobol.core.engine.processors;

import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.lsp.cobol.common.VariableConstants;
import org.eclipse.lsp.cobol.common.error.ErrorSeverity;
import org.eclipse.lsp.cobol.common.error.SyntaxError;
import org.eclipse.lsp.cobol.common.message.MessageTemplate;
import org.eclipse.lsp.cobol.common.model.NodeType;
import org.eclipse.lsp.cobol.common.model.tree.Node;
import org.eclipse.lsp.cobol.common.model.tree.variable.*;
import org.eclipse.lsp.cobol.common.processor.ProcessingContext;
import org.eclipse.lsp.cobol.common.processor.Processor;
import org.eclipse.lsp.cobol.common.utils.UsageFormatUtils;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;

import static org.eclipse.lsp.cobol.common.VariableConstants.PICTURE_NOT_ALLOWED;

/** Validate proper use of PIC and USAGE clause for elementary nodes */
public class ElementaryNodeCheck implements Processor<ElementaryNode> {
private static final String SEMANTICS_NO_PIC_CLAUSE = "semantics.noPicClause";
Expand All @@ -47,7 +40,6 @@ public class ElementaryNodeCheck implements Processor<ElementaryNode> {
public void accept(ElementaryNode node, ProcessingContext ctx) {
ctx.getErrors().addAll(validatePicClauseUsage(node));
ctx.getErrors().addAll(validateCompatibleUsageClause(node));
ctx.getErrors().addAll(validatePictureClauseAllowed(node));
}

private List<SyntaxError> validatePicClauseUsage(ElementaryNode node) {
Expand All @@ -66,40 +58,6 @@ private List<SyntaxError> validatePicClauseUsage(ElementaryNode node) {
.apply(node);
}

private List<SyntaxError> validatePictureClauseAllowed(ElementaryNode node) {
List<SyntaxError> result = new LinkedList<>();
if (!Strings.isNullOrEmpty(node.getPicClause()) && hasChildrenVariables(node)) {
result.add(node.getError(MessageTemplate.of(PICTURE_NOT_ALLOWED, node.getName())));
}
return result;
}

private boolean hasChildrenVariables(ElementaryNode node) {
if (!(node.getParent() instanceof GroupItemNode)) {
return false;
}

GroupItemNode parent = (GroupItemNode) node.getParent();
int nodeIndex = parent.getChildren().indexOf(node);
int level = node.getLevel();
nodeIndex++;

if (nodeIndex < parent.getChildren().size()) {
Node nextNode = parent.getChildren().get(nodeIndex);
if (nextNode.getNodeType() == NodeType.VARIABLE && nextNode instanceof VariableWithLevelNode
&& !(nextNode instanceof MultiTableDataNameNode)) {
int nextVariableLevel = VariableWithLevelNode.class.cast(nextNode).getLevel();
if (nextVariableLevel != VariableConstants.LEVEL_66
&& nextVariableLevel != VariableConstants.LEVEL_77
&& nextVariableLevel != VariableConstants.LEVEL_88
&& level < nextVariableLevel) {
return !Strings.isNullOrEmpty(node.getPicClause());
}
}
}
return false;
}

private MessageTemplate getInCompatibleClause(ElementaryNode node) {
return node.isBlankWhenZeroPresent()
? MessageTemplate.of(BLANK_WHEN_ZERO)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,25 @@
*/
package org.eclipse.lsp.cobol.core.engine.processors;

import org.eclipse.lsp.cobol.common.VariableConstants;
import org.eclipse.lsp.cobol.common.message.MessageTemplate;
import org.eclipse.lsp.cobol.common.model.tree.Node;
import org.eclipse.lsp.cobol.common.model.NodeType;
import org.eclipse.lsp.cobol.common.processor.ProcessingContext;
import org.eclipse.lsp.cobol.common.processor.Processor;

import com.google.common.base.Strings;

import org.eclipse.lsp.cobol.common.model.tree.variable.ElementaryNode;
import org.eclipse.lsp.cobol.common.model.tree.variable.GroupItemNode;
import org.eclipse.lsp.cobol.common.model.tree.variable.MultiTableDataNameNode;
import org.eclipse.lsp.cobol.common.model.tree.variable.UsageFormat;
import org.eclipse.lsp.cobol.common.model.tree.variable.VariableWithLevelNode;

import static org.eclipse.lsp.cobol.common.VariableConstants.EMPTY_STRUCTURE_MSG;
import static org.eclipse.lsp.cobol.common.VariableConstants.PICTURE_NOT_ALLOWED;

import java.util.List;

/** GroupItemNode processor */
public class GroupItemCheck implements Processor<GroupItemNode> {
Expand All @@ -33,5 +43,29 @@ public void accept(GroupItemNode node, ProcessingContext ctx) {
&& node.getChildren().stream().noneMatch(Node.hasType(NodeType.VARIABLE))) {
ctx.getErrors().add(node.getError(MessageTemplate.of(EMPTY_STRUCTURE_MSG, node.getName())));
}

final List<Node> children = node.getChildren();
for (int nodeIndex = 0; nodeIndex < children.size() - 1; ++nodeIndex) {
final Node child = children.get(nodeIndex);
if (!(child instanceof ElementaryNode))
continue;
final ElementaryNode childE = (ElementaryNode) child;
if (Strings.isNullOrEmpty(childE.getPicClause()))
continue;
final Node nextNode = children.get(nodeIndex + 1);
if (nextNode.getNodeType() != NodeType.VARIABLE
|| !(nextNode instanceof VariableWithLevelNode)
|| nextNode instanceof MultiTableDataNameNode)
continue;

int nextVariableLevel = VariableWithLevelNode.class.cast(nextNode).getLevel();
if (nextVariableLevel == VariableConstants.LEVEL_66
|| nextVariableLevel == VariableConstants.LEVEL_77
|| nextVariableLevel == VariableConstants.LEVEL_88
|| childE.getLevel() >= nextVariableLevel)
continue;

ctx.getErrors().add(childE.getError(MessageTemplate.of(PICTURE_NOT_ALLOWED, childE.getName())));
}
}
}

0 comments on commit 8fe79ad

Please sign in to comment.