1

build: upgrade Java

This commit is contained in:
2026-04-15 23:31:24 +03:00
parent 2ff9281704
commit 97f36cb809
17 changed files with 167 additions and 174 deletions

View File

@@ -7,7 +7,7 @@ group = "ru.di9.fluent"
version = "1.0-SNAPSHOT"
java.toolchain {
languageVersion = JavaLanguageVersion.of(17)
languageVersion = JavaLanguageVersion.of(21)
}
repositories {

View File

@@ -5,7 +5,7 @@ import ru.di9.fluent.syntax.ast.*;
import java.util.*;
import java.util.function.Predicate;
import static ru.di9.fluent.syntax.StringUtils.inRange_09;
import static ru.di9.fluent.syntax.utils.StringUtils.inRange_09;
import static ru.di9.fluent.syntax.parser.FluentStream.*;
import static ru.di9.fluent.syntax.parser.ParseException.ErrorCode.*;
@@ -18,13 +18,13 @@ public class FluentParser {
int spanStart = ps.index;
List<TopLevel> entries = new ArrayList<>();
Comment lastComment = null;
var blankLines = ps.skipBlankBlock();
String blankLines = ps.skipBlankBlock();
if (!blankLines.isEmpty()) {
entries.add(new Whitespace(blankLines));
}
while (ps.currentChar().isPresent()) {
var entry = getEntryOrJunk(ps);
TopLevel entry = getEntryOrJunk(ps);
blankLines = ps.skipBlankBlock();
// Regular Comments require special logic. Comments may be attached to
@@ -78,7 +78,7 @@ public class FluentParser {
int entryStartPos = ps.index;
try {
var entry = getEntry(ps);
Entry entry = getEntry(ps);
ps.expectLineEnd();
return entry;
} catch (ParseException e) {
@@ -91,7 +91,7 @@ public class FluentParser {
}
// Create a Junk instance
var slice = ps.string.substring(entryStartPos, nextEntryStart);
String slice = ps.string.substring(entryStartPos, nextEntryStart);
var junk = new Junk(slice);
if (withSpans) {
junk.addSpan(entryStartPos, nextEntryStart);
@@ -107,7 +107,7 @@ public class FluentParser {
}
private Entry getEntry(FluentStream ps) {
var currentChar = ps.currentChar();
Optional<Character> currentChar = ps.currentChar();
if (currentChar.filter(v -> v == '#').isPresent()) {
return getComment(ps);
@@ -126,13 +126,13 @@ public class FluentParser {
private Message getMessage(FluentStream ps) {
int spanStart = ps.index;
var id = getIdentifier(ps);
Identifier id = getIdentifier(ps);
ps.skipBlankInline();
ps.expectChar('=');
var value = maybeGetPattern(ps);
var attrs = getAttributes(ps);
Pattern value = maybeGetPattern(ps);
Collection<Attribute> attrs = getAttributes(ps);
if (value == null && attrs.isEmpty()) {
throw new ParseException(E0005, id.getName());
@@ -150,17 +150,17 @@ public class FluentParser {
int spanStart = ps.index;
ps.expectChar('-');
var id = getIdentifier(ps);
Identifier id = getIdentifier(ps);
ps.skipBlankInline();
ps.expectChar('=');
var value = maybeGetPattern(ps);
Pattern value = maybeGetPattern(ps);
if (value == null) {
throw new ParseException(E0006, id.getName());
}
var attrs = getAttributes(ps);
Collection<Attribute> attrs = getAttributes(ps);
var term = new Term(id, value);
term.getAttributes().addAll(attrs);
@@ -176,7 +176,7 @@ public class FluentParser {
ps.peekBlank();
while (ps.isAttributeStart()) {
ps.skipToPeek();
var attr = getAttribute(ps);
Attribute attr = getAttribute(ps);
attrs.add(attr);
ps.peekBlank();
}
@@ -187,12 +187,12 @@ public class FluentParser {
int spanStart = ps.index;
ps.expectChar('.');
var key = getIdentifier(ps);
Identifier key = getIdentifier(ps);
ps.skipBlankInline();
ps.expectChar('=');
var value = maybeGetPattern(ps);
Pattern value = maybeGetPattern(ps);
if (value == null) {
throw new ParseException(E0012);
}
@@ -234,8 +234,8 @@ public class FluentParser {
if (isBlock) {
// A block pattern is a pattern which starts on a new line. Store and
// measure the indent of this first line for the dedentation logic.
var blankStart = ps.index;
var firstIndent = ps.skipBlankInline();
int blankStart = ps.index;
String firstIndent = ps.skipBlankInline();
elements.add(getIndent(ps, firstIndent, blankStart));
commonIndentLength = firstIndent.length();
}
@@ -243,14 +243,14 @@ public class FluentParser {
Optional<Character> opt;
elements:
while ((opt = ps.currentChar()).isPresent()) {
var ch = opt.get();
Character ch = opt.get();
switch (ch) {
case EOL -> {
var blankStart = ps.index;
var blankLines = ps.peekBlankBlock();
int blankStart = ps.index;
String blankLines = ps.peekBlankBlock();
if (ps.isValueContinuation()) {
ps.skipToPeek();
var indent = ps.skipBlankInline();
String indent = ps.skipBlankInline();
commonIndentLength = Math.min(commonIndentLength, indent.length());
elements.add(getIndent(ps, blankLines + indent, blankStart));
continue;
@@ -267,7 +267,7 @@ public class FluentParser {
}
}
var dedented = dedent(elements, commonIndentLength);
List<PatternElement> dedented = dedent(elements, commonIndentLength);
var pattern = new Pattern(dedented);
if (withSpans) {
pattern.addSpan(spanStart, ps.index);
@@ -281,7 +281,7 @@ public class FluentParser {
private List<PatternElement> dedent(Collection<PatternElement> elements, int commonIndent) {
ArrayList<PatternElement> trimmed = new ArrayList<>();
for (var element : elements) {
for (PatternElement element : elements) {
if (element instanceof Placeable pl) {
trimmed.add(pl);
continue;
@@ -296,22 +296,10 @@ public class FluentParser {
}
if (!trimmed.isEmpty()) {
var prev = trimmed.get(trimmed.size() - 1);
PatternElement prev = trimmed.getLast();
if (prev instanceof TextElement prevTE) {
// Join adjacent TextElements by replacing them with their sum.
String newVal;
if (element instanceof TextElement elmTE) {
newVal = elmTE.getValue();
} else if (element instanceof Indent elmInd) {
newVal = elmInd.getValue();
} else {
throw new IllegalStateException("Unexpected PatternElement type");
}
var sum = new TextElement(prevTE.getValue() + newVal);
if (withSpans && prevTE.getSpan().isPresent() && element.getSpan().isPresent()) {
sum.addSpan(prevTE.getSpan().get().getStart(), element.getSpan().get().getEnd());
}
TextElement sum = getTextElement(element, prevTE);
trimmed.set(trimmed.size() - 1, sum);
continue;
@@ -335,17 +323,34 @@ public class FluentParser {
}
// Trim trailing whitespace from the Pattern.
var lastElement = trimmed.get(trimmed.size() - 1);
PatternElement lastElement = trimmed.getLast();
if (lastElement instanceof TextElement lastElmTE) {
lastElmTE.setValue(TRAILING_WS_RE.matcher(lastElmTE.getValue()).replaceAll(""));
if (lastElmTE.getValue().isEmpty()) {
trimmed.remove(trimmed.size() - 1);
trimmed.removeLast();
}
}
return trimmed;
}
private TextElement getTextElement(PatternElement element, TextElement prevTE) {
String newVal;
if (element instanceof TextElement elmTE) {
newVal = elmTE.getValue();
} else if (element instanceof Indent elmInd) {
newVal = elmInd.getValue();
} else {
throw new IllegalStateException("Unexpected PatternElement type");
}
var sum = new TextElement(prevTE.getValue() + newVal);
if (withSpans && prevTE.getSpan().isPresent() && element.getSpan().isPresent()) {
sum.addSpan(prevTE.getSpan().get().getStart(), element.getSpan().get().getEnd());
}
return sum;
}
private TextElement getTextElement(FluentStream ps) {
var buffer = new StringBuilder();
int spanStart = ps.index;
@@ -375,13 +380,13 @@ public class FluentParser {
}
private PatternElement getPlaceable(FluentStream ps) {
var spanStart = ps.index;
int spanStart = ps.index;
ps.expectChar('{');
ps.skipBlank();
SyntaxNode expression;
if (ps.currentChar().filter(v -> v == '{').isPresent()) {
var child = getPlaceable(ps);
PatternElement child = getPlaceable(ps);
ps.skipBlank();
expression = child;
} else {
@@ -401,7 +406,7 @@ public class FluentParser {
private Expression getExpression(FluentStream ps) {
int spanStart = ps.index;
var selector = getInlineExpression(ps);
Expression selector = getInlineExpression(ps);
ps.skipBlank();
if (ps.currentChar().filter(v -> v == '-').isPresent()) {
@@ -425,7 +430,7 @@ public class FluentParser {
ps.skipBlankInline();
ps.expectLineEnd();
var variants = getVariants(ps);
List<Variant> variants = getVariants(ps);
var selectExpression = new SelectExpression(selector, variants);
if (withSpans) {
@@ -448,7 +453,7 @@ public class FluentParser {
ps.skipBlank();
while (ps.isVariantStart()) {
var variant = getVariant(ps, hasDefault);
Variant variant = getVariant(ps, hasDefault);
if (variant.isDefault()) {
hasDefault = true;
@@ -486,13 +491,13 @@ public class FluentParser {
ps.skipBlank();
var key = getVariantKey(ps);
VariantKey key = getVariantKey(ps);
ps.skipBlank();
ps.expectChar(']');
//val value = this.maybeGetPattern(ps) ?: throw ParseError("E0012")
var value = maybeGetPattern(ps);
Pattern value = maybeGetPattern(ps);
if (value == null) {
throw new ParseException(E0012);
}
@@ -515,7 +520,7 @@ public class FluentParser {
}
private Expression getInlineExpression(FluentStream ps) {
var spanStart = ps.index;
int spanStart = ps.index;
if (ps.isNumberStart()) {
return getNumber(ps);
@@ -527,7 +532,7 @@ public class FluentParser {
if (ps.currentChar().filter(v -> v == '$').isPresent()) {
ps.next();
var id = getIdentifier(ps);
Identifier id = getIdentifier(ps);
var variableReference = new VariableReference(id);
if (withSpans) {
@@ -539,7 +544,7 @@ public class FluentParser {
if (ps.currentChar().filter(v -> v == '-').isPresent()) {
ps.next();
var id = getIdentifier(ps);
Identifier id = getIdentifier(ps);
Identifier attr = null;
if (ps.currentChar().filter(v -> v == '.').isPresent()) {
@@ -563,7 +568,7 @@ public class FluentParser {
}
if (ps.isIdentifierStart()) {
var id = getIdentifier(ps);
Identifier id = getIdentifier(ps);
ps.peekBlank();
if (ps.currentPeek().filter(v -> v == '(').isPresent()) {
@@ -573,7 +578,7 @@ public class FluentParser {
}
ps.skipToPeek();
var args = getCallArguments(ps);
CallArguments args = getCallArguments(ps);
var functionReference = new FunctionReference(id, args);
if (withSpans) {
functionReference.addSpan(spanStart, ps.index);
@@ -599,7 +604,7 @@ public class FluentParser {
}
private CallArguments getCallArguments(FluentStream ps) {
var spanStart = ps.index;
int spanStart = ps.index;
List<Expression> positional = new ArrayList<>();
List<NamedArgument> named = new ArrayList<>();
Set<String> argumentNames = new HashSet<>();
@@ -612,7 +617,7 @@ public class FluentParser {
break;
}
var arg = getCallArgument(ps);
CallArgument arg = getCallArgument(ps);
if (arg instanceof NamedArgument na) {
if (argumentNames.contains(na.getName().getName())) {
throw new ParseException(E0022);
@@ -648,8 +653,8 @@ public class FluentParser {
}
private CallArgument getCallArgument(FluentStream ps) {
var spanStart = ps.index;
var exp = getInlineExpression(ps);
int spanStart = ps.index;
Expression exp = getInlineExpression(ps);
ps.skipBlank();
@@ -661,7 +666,7 @@ public class FluentParser {
ps.next();
ps.skipBlank();
var value = getLiteral(ps);
Literal value = getLiteral(ps);
var namedArgument = new NamedArgument(mr.getId(), value);
if (withSpans) {
@@ -687,7 +692,7 @@ public class FluentParser {
}
private StringLiteral getString(FluentStream ps) {
var spanStart = ps.index;
int spanStart = ps.index;
ps.expectChar('"');
var value = new StringBuilder();
@@ -695,7 +700,7 @@ public class FluentParser {
Predicate<Character> filter = x -> x != '"' && x != EOL;
Optional<Character> opt;
while ((opt = ps.takeChar(filter)).isPresent()) {
var ch = opt.get();
Character ch = opt.get();
value.append(ch == '\\' ? getEscapeSequence(ps) : ch);
}
@@ -714,12 +719,12 @@ public class FluentParser {
}
private String getEscapeSequence(FluentStream ps) {
var nextOpt = ps.currentChar();
Optional<Character> nextOpt = ps.currentChar();
if (nextOpt.isEmpty()) {
throw new ParseException(E0025, (Character) null);
}
var next = nextOpt.get();
Character next = nextOpt.get();
return switch (next) {
case '\\', '"' -> {
ps.next();
@@ -736,7 +741,7 @@ public class FluentParser {
var sequence = new StringBuilder();
for (int i = 0; i < digits; i++) {
var opt = ps.takeHexDigit();
Optional<Character> opt = ps.takeHexDigit();
if (opt.isEmpty()) {
throw new ParseException(E0026, "\\%s%s%s".formatted(u, sequence, ps.currentChar().orElseThrow()));
}
@@ -747,7 +752,7 @@ public class FluentParser {
}
private NumberLiteral getNumber(FluentStream ps) {
var spanStart = ps.index;
int spanStart = ps.index;
var value = new StringBuilder();
if (ps.currentChar().filter(v -> v == '-').isPresent()) {
@@ -794,7 +799,7 @@ public class FluentParser {
private Identifier getIdentifier(FluentStream ps) {
int spanStart = ps.index;
var name = new StringBuilder().append(ps.takeIDStart());
StringBuilder name = new StringBuilder().append(ps.takeIDStart());
Optional<Character> opt;
while ((opt = ps.takeIDChar()).isPresent()) {
name.append(opt.get());
@@ -816,11 +821,11 @@ public class FluentParser {
final int GROUP_COMMENT = 1;
final int RESOURCE_COMMENT = 2;
var level = ANY;
int level = ANY;
var content = new StringBuilder();
while (true) {
var i = -1;
int i = -1;
int thisLevel;
if (level == ANY) {

View File

@@ -1,12 +1,12 @@
package ru.di9.fluent.syntax.parser;
import ru.di9.fluent.syntax.MathUtils;
import ru.di9.fluent.syntax.utils.MathUtils;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import static ru.di9.fluent.syntax.StringUtils.*;
import static ru.di9.fluent.syntax.utils.StringUtils.*;
import static ru.di9.fluent.syntax.parser.ParseException.ErrorCode.E0003;
import static ru.di9.fluent.syntax.parser.ParseException.ErrorCode.E0004;
@@ -29,17 +29,17 @@ public class FluentStream extends ParserStream {
}
public String skipBlankInline() {
var blank = peekBlankInline();
String blank = peekBlankInline();
skipToPeek();
return blank;
}
public String peekBlankBlock() {
var blank = new StringBuilder();
StringBuilder blank = new StringBuilder();
while (true) {
var lineStart = peekOffset;
int lineStart = peekOffset;
peekBlankInline();
var currentPeek = currentPeek();
Optional<Character> currentPeek = currentPeek();
if (currentPeek.filter(v -> v == EOL).isPresent()) {
blank.append(EOL);
peek();
@@ -56,7 +56,7 @@ public class FluentStream extends ParserStream {
}
public String skipBlankBlock() {
var blank = peekBlankBlock();
String blank = peekBlankBlock();
skipToPeek();
return blank;
}
@@ -79,7 +79,7 @@ public class FluentStream extends ParserStream {
}
public void expectLineEnd() {
var opt = currentChar();
Optional<Character> opt = currentChar();
if (opt.isEmpty()/*EOF*/) {
// EOF is a valid line end in Fluent.
@@ -97,7 +97,7 @@ public class FluentStream extends ParserStream {
}
public Optional<Character> takeChar(Predicate<Character> f) {
var ch = currentChar().filter(f);
Optional<Character> ch = currentChar().filter(f);
ch.ifPresent(x -> next());
return ch;
}
@@ -107,7 +107,7 @@ public class FluentStream extends ParserStream {
}
public boolean isNumberStart() {
var opt = currentChar();
Optional<Character> opt = currentChar();
if (opt.filter(v -> v == '-').isPresent()) {
opt = peek();
}
@@ -123,7 +123,7 @@ public class FluentStream extends ParserStream {
}
public boolean isValueContinuation() {
var column1 = peekOffset;
int column1 = peekOffset;
peekBlankInline();
if (currentPeek().filter(v -> v == '{').isPresent()) {
@@ -156,7 +156,7 @@ public class FluentStream extends ParserStream {
}
int lvl = MathUtils.clamp(level, -1, 2);
var i = 0;
int i = 0;
while (i <= lvl || (lvl == -1 && i < 3)) {
if (peek().filter(v -> v != '#').isPresent()) {
if (i <= lvl && lvl != -1) {
@@ -175,7 +175,7 @@ public class FluentStream extends ParserStream {
}
public boolean isVariantStart() {
var currentPeekOffset = peekOffset;
int currentPeekOffset = peekOffset;
if (currentPeek().filter(v -> v == '*').isPresent()) {
peek();
}
@@ -190,7 +190,7 @@ public class FluentStream extends ParserStream {
}
public void skipToNextEntryStart(int junkStart) {
var lastNewline = string.lastIndexOf(EOL, index);
int lastNewline = string.lastIndexOf(EOL, index);
if (junkStart < lastNewline) {
// Last seen newline is _after_ the junk start. It's safe to rewind
// without the risk of resuming at the same broken entry.
@@ -205,7 +205,7 @@ public class FluentStream extends ParserStream {
}
// Break if the first char in this line looks like an entry start.
var firstOpt = next();
Optional<Character> firstOpt = next();
if (firstOpt.isEmpty()/*EOF*/) {
continue;
}
@@ -219,7 +219,7 @@ public class FluentStream extends ParserStream {
public char takeIDStart() {
if (currentChar().map(this::isCharIdStart).orElse(false)) {
var ret = currentChar();
Optional<Character> ret = currentChar();
if (ret.isPresent()) {
next();
return ret.get();

View File

@@ -2,7 +2,7 @@ package ru.di9.fluent.syntax.parser;
import java.util.Optional;
import static ru.di9.fluent.syntax.StringUtils.getCharAt;
import static ru.di9.fluent.syntax.utils.StringUtils.getCharAt;
public class ParserStream {
@@ -71,9 +71,10 @@ public class ParserStream {
// beginning of the compound CRLF sequence. This ensures slices of
// [inclusive, exclusive) continue to work properly.
var ch = getCharAt(string, offset);
var opt = ch.filter(v -> v == '\r')
.flatMap(x -> getCharAt(string, offset + 1).filter(v -> v == '\n'));
Optional<Character> ch = getCharAt(string, offset);
Optional<Character> opt = ch.filter(v -> v == '\r')
.flatMap(x -> getCharAt(string, offset + 1)
.filter(v -> v == '\n'));
return opt.isPresent() ? opt : ch;
}

View File

@@ -17,33 +17,25 @@ public class FluentSerializer {
}
public String serialize(TopLevel topLevel) {
if (topLevel instanceof Entry entry) {
return serializeEntry(entry);
} else if (topLevel instanceof Whitespace whitespace) {
return whitespace.getContent();
} else if (topLevel instanceof Junk junk) {
return withJunk ? junk.getContent() : "";
} else {
throw new SerializeException("Unknown top-level entry type '%s'".formatted(topLevel.getClass()));
}
return switch (topLevel) {
case Entry entry -> serializeEntry(entry);
case Whitespace whitespace -> whitespace.getContent();
case Junk junk -> withJunk ? junk.getContent() : "";
default -> throw new SerializeException("Unknown top-level entry type '%s'".formatted(topLevel.getClass()));
};
}
/// PRIVATE ////////////////////////////////////////////////////////////////////////////////////////////////////////
private String serializeEntry(Entry entry) {
if (entry instanceof Message message) {
return serializeMessage(message);
} else if (entry instanceof Term term) {
return serializeTerm(term);
} else if (entry instanceof Comment comment) {
return serializeComment(comment, "#");
} else if (entry instanceof GroupComment comment) {
return serializeComment(comment, "##");
} else if (entry instanceof ResourceComment comment) {
return serializeComment(comment, "###");
} else {
throw new SerializeException("Unknown entry type '%s'".formatted(entry.getClass()));
}
return switch (entry) {
case Message message -> serializeMessage(message);
case Term term -> serializeTerm(term);
case Comment comment -> serializeComment(comment, "#");
case GroupComment comment -> serializeComment(comment, "##");
case ResourceComment comment -> serializeComment(comment, "###");
default -> throw new SerializeException("Unknown entry type '%s'".formatted(entry.getClass()));
};
}
private String serializeMessage(Message message) {
@@ -129,51 +121,47 @@ public class FluentSerializer {
private String serializePlaceable(Placeable placeable) {
InsidePlaceable expression = placeable.getExpression();
if (expression instanceof Placeable placeable1) {
return "{" + serializePlaceable(placeable1) + "}";
} else if (expression instanceof SelectExpression selectExpression) {
return "{ " + serializeExpression(selectExpression) + "}";
} else if (expression instanceof Expression expression1) {
return "{ " + serializeExpression(expression1) + " }";
} else {
throw new SerializeException("Unknown placeable type '%s'".formatted(expression.getClass()));
}
return switch (expression) {
case Placeable placeable1 -> "{" + serializePlaceable(placeable1) + "}";
case SelectExpression selectExpression -> "{ " + serializeExpression(selectExpression) + "}";
case Expression expression1 -> "{ " + serializeExpression(expression1) + " }";
default -> throw new SerializeException("Unknown placeable type '%s'".formatted(expression.getClass()));
};
}
private String serializeExpression(Expression expression) {
var builder = new StringBuilder();
if (expression instanceof StringLiteral stringLiteral) {
builder.append('"').append(stringLiteral.getValue()).append('"');
} else if (expression instanceof NumberLiteral numberLiteral) {
builder.append(numberLiteral.getValue());
} else if (expression instanceof VariableReference variableReference) {
builder.append('$').append(variableReference.getId().getName());
} else if (expression instanceof TermReference termReference) {
builder.append('-').append(termReference.getId().getName());
switch (expression) {
case StringLiteral stringLiteral -> builder.append('"').append(stringLiteral.getValue()).append('"');
case NumberLiteral numberLiteral -> builder.append(numberLiteral.getValue());
case VariableReference variableReference -> builder.append('$').append(variableReference.getId().getName());
case TermReference termReference -> {
builder.append('-').append(termReference.getId().getName());
termReference.getAttribute().ifPresent(attribute ->
termReference.getAttribute().ifPresent(attribute ->
builder.append('.').append(attribute.getName()));
termReference.getArguments().ifPresent(arguments ->
termReference.getArguments().ifPresent(arguments ->
builder.append(serializeCallArguments(arguments)));
} else if (expression instanceof MessageReference messageReference) {
builder.append(messageReference.getId().getName());
}
case MessageReference messageReference -> {
builder.append(messageReference.getId().getName());
messageReference.getAttribute().ifPresent(attribute ->
messageReference.getAttribute().ifPresent(attribute ->
builder.append('.').append(attribute.getName()));
} else if (expression instanceof FunctionReference functionReference) {
builder
}
case FunctionReference functionReference -> builder
.append(functionReference.getId().getName())
.append(serializeCallArguments(functionReference.getArguments()));
} else if (expression instanceof SelectExpression selectExpression) {
builder.append(serializeExpression(selectExpression.getSelector())).append(" ->");
for (Variant variant : selectExpression.getVariants()) {
builder.append(serializeVariant(variant));
case SelectExpression selectExpression -> {
builder.append(serializeExpression(selectExpression.getSelector())).append(" ->");
for (Variant variant : selectExpression.getVariants()) {
builder.append(serializeVariant(variant));
}
builder.append('\n');
}
builder.append('\n');
} else {
throw new SerializeException("Unknown expression type '%s".formatted(expression.getClass()));
default -> throw new SerializeException("Unknown expression type '%s".formatted(expression.getClass()));
}
return builder.toString();
@@ -185,7 +173,7 @@ public class FluentSerializer {
var builder = new StringBuilder("(");
if (hasPositional) {
var positional = callArguments.getPositional()
String positional = callArguments.getPositional()
.stream()
.map(this::serializeExpression)
.collect(Collectors.joining(", "));
@@ -193,7 +181,7 @@ public class FluentSerializer {
}
if (hasNamed) {
var named = callArguments.getNamed()
String named = callArguments.getNamed()
.stream()
.map(this::serializeNamedArgument)
.collect(Collectors.joining(", "));
@@ -209,8 +197,8 @@ public class FluentSerializer {
}
private String serializeVariant(Variant variant) {
var key = serializeVariantKey(variant.getKey());
var value = serializePattern(variant.getValue()).replaceAll("\n", "\n ");
String key = serializeVariantKey(variant.getKey());
String value = serializePattern(variant.getValue()).replaceAll("\n", "\n ");
var builder = new StringBuilder("\n ");
if (variant.isDefault()) {
@@ -240,7 +228,7 @@ public class FluentSerializer {
boolean isMultiline = pattern.getElements().stream().anyMatch(it -> isSelectExpr(it) || includesLine(it));
if (isMultiline) {
if (!pattern.getElements().isEmpty()) {
var firstElement = pattern.getElements().get(0);
PatternElement firstElement = pattern.getElements().getFirst();
if (firstElement instanceof TextElement te) {
if (!te.getValue().isEmpty()) {
char firstChar = te.getValue().charAt(0);

View File

@@ -1,4 +1,4 @@
package ru.di9.fluent.syntax;
package ru.di9.fluent.syntax.utils;
public interface MathUtils {
static int clamp(int value, int min, int max) {

View File

@@ -1,4 +1,4 @@
package ru.di9.fluent.syntax;
package ru.di9.fluent.syntax.utils;
import java.util.Optional;

View File

@@ -2,8 +2,7 @@ package ru.di9.fluent.syntax.ast;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.assertj.core.api.Assertions.assertThat;
class BaseNodeTest {
@@ -13,12 +12,11 @@ class BaseNodeTest {
var m11 = new Message(new Identifier("test-id"), new Pattern(new TextElement("localized")));
var m2 = new Message(new Identifier("test-id"), new Pattern(new TextElement("different")));
assertEquals(m1, m11);
assertNotEquals(m1, m2);
assertEquals(m1.getId(), m2.getId());
assertNotEquals(m1.getValue(), m2.getValue());
//Шта?
assertNotEquals(m1, null);
assertNotEquals(null, m1);
assertThat(m1)
.isEqualTo(m11)
.isNotEqualTo(m2);
assertThat(m1.getId()).isEqualTo(m2.getId());
assertThat(m1.getValue()).isNotEqualTo(m2.getValue());
}
}

View File

@@ -2,7 +2,8 @@ package ru.di9.fluent.syntax.parser;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;
import ru.di9.fluent.test.utils.AstAssert;
import ru.di9.fluent.syntax.ast.Resource;
import ru.di9.fluent.syntax.test.utils.AstAssert;
import ru.di9.fluent.test.utils.Tuple3;
import java.io.IOException;
@@ -43,7 +44,7 @@ public abstract class AbstractFixturesTest {
var parser = new FluentParser();
parser.withSpans = isWithSpans(tuple.value1());
parser.withJunkAnnotations = isWithJunkAnnotations(tuple.value1());
var resource = parser.parse(tuple.value2());
Resource resource = parser.parse(tuple.value2());
AstAssert.assertThat(resource)
.isEqualAstJson(tuple.value3());

View File

@@ -42,7 +42,7 @@ class FluentStreamTest {
assertThatNoException().isThrownBy(ps2::expectLineEnd);
var ps3 = new FluentStream(" ");
var catchException = catchThrowableOfType(ps3::expectLineEnd, ParseException.class);
ParseException catchException = catchThrowableOfType(ps3::expectLineEnd, ParseException.class);
assertThat(catchException.getCode()).isEqualTo(E0003);
}
@@ -50,7 +50,7 @@ class FluentStreamTest {
void testExpectChar() {
var ps = new FluentStream("z");
assertThatNoException().isThrownBy(() -> ps.expectChar('z'));
var catchException = catchThrowableOfType(() -> ps.expectChar('a'), ParseException.class);
ParseException catchException = catchThrowableOfType(() -> ps.expectChar('a'), ParseException.class);
assertThat(catchException.getCode()).isEqualTo(E0003);
}

View File

@@ -1,6 +1,7 @@
package ru.di9.fluent.syntax.serializer;
import org.junit.jupiter.api.Test;
import ru.di9.fluent.syntax.ast.TopLevel;
import ru.di9.fluent.syntax.parser.FluentParser;
import static org.assertj.core.api.Assertions.assertThat;
@@ -14,10 +15,10 @@ class SerializeEntryTest {
key = Value""";
var parser = new FluentParser();
var topLevel = parser.parse(input).getBody().get(0);
TopLevel topLevel = parser.parse(input).getBody().getFirst();
var serializer = new FluentSerializer();
var serialized = serializer.serialize(topLevel).trim();
String serialized = serializer.serialize(topLevel).trim();
assertThat(serialized).isEqualTo(input);
}

View File

@@ -1,4 +1,4 @@
package ru.di9.fluent.test.utils;
package ru.di9.fluent.syntax.test.utils;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
@@ -7,6 +7,8 @@ import org.json.JSONException;
import org.skyscreamer.jsonassert.JSONAssert;
import org.skyscreamer.jsonassert.JSONCompareMode;
import ru.di9.fluent.syntax.ast.BaseNode;
import ru.di9.fluent.test.utils.BaseNodeJsonSerializer;
import ru.di9.fluent.test.utils.NullIgnoreComparator;
import java.io.PrintStream;
@@ -26,13 +28,13 @@ public class AstAssert extends AbstractAssert<AstAssert, BaseNode> {
@SuppressWarnings("unused")
public AstAssert printAstJson(PrintStream printStream) {
var json = gson.toJson(actual);
String json = gson.toJson(actual);
printStream.println(json);
return this;
}
public AstAssert isEqualAstJson(String astJson) {
var actualJson = gson.toJson(actual);
String actualJson = gson.toJson(actual);
try {
JSONAssert.assertEquals(astJson, actualJson, nullIgnoreComparator);

View File

@@ -1,4 +1,4 @@
package ru.di9.fluent.syntax;
package ru.di9.fluent.syntax.utils;
import org.junit.jupiter.api.Test;

View File

@@ -1,4 +1,4 @@
package ru.di9.fluent.syntax;
package ru.di9.fluent.syntax.utils;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;

View File

@@ -3,10 +3,7 @@ package ru.di9.fluent.syntax.visitor;
import lombok.Getter;
import lombok.Setter;
import org.junit.jupiter.api.Test;
import ru.di9.fluent.syntax.ast.Identifier;
import ru.di9.fluent.syntax.ast.Pattern;
import ru.di9.fluent.syntax.ast.TextElement;
import ru.di9.fluent.syntax.ast.Variant;
import ru.di9.fluent.syntax.ast.*;
import ru.di9.fluent.syntax.parser.FluentParser;
import java.util.Iterator;
@@ -29,7 +26,7 @@ class VisitorTest {
msg = foo {$var ->
*[other] bar
} baz""";
var res = parser.parse(source);
Resource res = parser.parse(source);
visitor.visit(res);
assertEquals(3, visitor.wordCount);
assertEquals(2, visitor.patternCount);

View File

@@ -16,7 +16,7 @@ public class BaseNodeJsonSerializer implements JsonSerializer<BaseNode> {
var root = new JsonObject();
root.add("type", new JsonPrimitive(baseNode.getClass().getSimpleName()));
var fields = Reflect.on(baseNode).fields();
Map<String, Reflect> fields = Reflect.on(baseNode).fields();
for (Map.Entry<String, Reflect> field : fields.entrySet()) {
String name = field.getKey().equalsIgnoreCase("isDefault") ? "default" : field.getKey();

View File

@@ -5,13 +5,13 @@ import java.nio.file.Path;
public interface FileUtils {
static String getExt(String fileName) {
var idx = fileName.lastIndexOf('.');
int idx = fileName.lastIndexOf('.');
if (idx < 0) return "";
return fileName.substring(idx + 1);
}
static String getName(String fileName) {
var idx = fileName.lastIndexOf('.');
int idx = fileName.lastIndexOf('.');
if (idx < 0) return fileName;
return fileName.substring(0, idx);
}