Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor empty list and empty structure handling #434

Merged
merged 1 commit into from
Nov 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,6 @@ public Object getArgument(DecryptionService decryptionService) {
return null;
}

protected String toPrettyString(int depth, int prefixDepth) {
return null;
}

public Integer getInteger() {
return null;
}
Expand All @@ -54,6 +50,14 @@ public Map<String, ApmType> getMap() {
return null;
}

public boolean isEmpty() {
return false;
}

protected String toPrettyString(int depth, int prefixDepth) {
return null;
}

@Override
public String toString() {
return toPrettyString(0, 0);
Expand Down Expand Up @@ -149,6 +153,11 @@ public List<ApmType> getList() {
return values;
}

@Override
public boolean isEmpty() {
return values.isEmpty();
}

@Override
protected String toPrettyString(int depth, int prefixDepth) {
boolean simpleList = values.stream()
Expand Down Expand Up @@ -196,6 +205,11 @@ public Map<String, ApmType> getMap() {
return values;
}

@Override
public boolean isEmpty() {
return values.isEmpty();
}

@Override
protected String toPrettyString(int depth, int prefixDepth) {
ApmType firstEntry = values.values()
Expand Down Expand Up @@ -254,6 +268,11 @@ public ApmType getValue() {
return value;
}

@Override
public boolean isEmpty() {
return value.isEmpty();
}

@Override
protected String toPrettyString(int depth, int prefixDepth) {
return StringUtils.repeat('\t', depth) + key + ": " + value.toPrettyString(depth, 0);
Expand All @@ -262,5 +281,9 @@ protected String toPrettyString(int depth, int prefixDepth) {

public static class ApmEmpty extends ApmType {

@Override
public boolean isEmpty() {
return true;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,8 @@
import com.cognifide.apm.api.scripts.Script;
import com.cognifide.apm.api.services.ScriptFinder;
import com.cognifide.apm.api.status.Status;
import com.cognifide.apm.core.grammar.ApmType.ApmEmpty;
import com.cognifide.apm.core.grammar.ApmType.ApmList;
import com.cognifide.apm.core.grammar.ApmType.ApmMap;
import com.cognifide.apm.core.grammar.ApmType.ApmPair;
import com.cognifide.apm.core.grammar.ApmType.ApmString;
import com.cognifide.apm.core.grammar.antlr.ApmLangBaseVisitor;
import com.cognifide.apm.core.grammar.antlr.ApmLangParser.AllowDenyCommandContext;
Expand All @@ -49,7 +48,6 @@
import com.cognifide.apm.core.logger.Position;
import com.cognifide.apm.core.logger.Progress;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
Expand Down Expand Up @@ -148,25 +146,25 @@ public Status visitRequireVariable(RequireVariableContext ctx) {

@Override
public Status visitForEach(ForEachContext ctx) {
List<Map<String, ApmType>> values = readValues(ctx);
ListIterator<Map<String, ApmType>> iterator = values.listIterator();
List<ApmPair> values = readValues(ctx);
ListIterator<ApmPair> iterator = values.listIterator();
if (!iterator.hasNext() && shouldVisitNextChild()) {
String key = ctx.IDENTIFIER().toString();
progress(ctx, Status.SKIPPED, "for-each", String.format("%s is always empty", key));
}
while (iterator.hasNext() && shouldVisitNextChild()) {
try {
int index = iterator.nextIndex();
Map<String, ApmType> value = iterator.next();
executionContext.createLocalContext();
String valueStr = value.entrySet()
.stream()
.map(entry -> String.format("%s=%s", entry.getKey(), entry.getValue()))
.collect(Collectors.joining("\n"));
progress(ctx, Status.SUCCESS, "for-each", String.format("%d. Begin: %s", index, valueStr));
value.forEach(executionContext::setVariable);
visit(ctx.body());
progress(ctx, Status.SUCCESS, "for-each", String.format("%d. End", index));
ApmPair value = iterator.next();
if (value.isEmpty()) {
progress(ctx, Status.SKIPPED, "for-each", String.format("%d. %s is empty", index, value.getKey()));
} else {
executionContext.createLocalContext();
progress(ctx, Status.SUCCESS, "for-each", String.format("%d. Begin: %s=%s", index, value.getKey(), value.getValue()));
executionContext.setVariable(value.getKey(), value.getValue());
visit(ctx.body());
progress(ctx, Status.SUCCESS, "for-each", String.format("%d. End", index));
}
} finally {
executionContext.removeLocalContext();
}
Expand Down Expand Up @@ -278,21 +276,19 @@ public Status visitImportScript(ImportScriptContext ctx) {
return Status.SUCCESS;
}

private List<Map<String, ApmType>> readValues(ForEachContext ctx) {
private List<ApmPair> readValues(ForEachContext ctx) {
String key = ctx.IDENTIFIER().toString();
ApmType variableValue = executionContext.resolveArgument(ctx.argument());
List<ApmType> values;
if (variableValue instanceof ApmList) {
values = variableValue.getList();
} else if (variableValue instanceof ApmEmpty) {
values = Collections.emptyList();
} else if (variableValue instanceof ApmMap && variableValue.getMap().isEmpty()) {
if (variableValue.isEmpty()) {
values = Collections.emptyList();
} else if (variableValue instanceof ApmList) {
values = variableValue.getList();
} else {
values = ImmutableList.of(variableValue);
}
return values.stream()
.map(value -> ImmutableMap.of(key, value))
.map(value -> new ApmPair(key, value))
.collect(Collectors.toList());
}

Expand Down