Skip to content

Commit

Permalink
Merge branch '__rultor'
Browse files Browse the repository at this point in the history
  • Loading branch information
rultor committed Dec 28, 2023
2 parents f85195c + 7bc20ce commit 63864e3
Show file tree
Hide file tree
Showing 6 changed files with 238 additions and 105 deletions.
36 changes: 26 additions & 10 deletions eo-maven-plugin/src/main/java/org/eolang/maven/UnphiMojo.java
Expand Up @@ -24,14 +24,18 @@
package org.eolang.maven;

import com.jcabi.log.Logger;
import com.jcabi.xml.XML;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.cactoos.experimental.Threads;
import org.cactoos.iterable.Mapped;
import org.cactoos.list.ListOf;
import org.cactoos.number.SumOf;
import org.cactoos.text.TextOf;
import org.eolang.maven.util.HmBase;
Expand Down Expand Up @@ -73,36 +77,48 @@ public final class UnphiMojo extends SafeMojo {

@Override
public void exec() {
final List<Path> errors = new ListOf<>();
final Home home = new HmBase(this.unphiOutputDir);
final int count = new SumOf(
new Threads<>(
Runtime.getRuntime().availableProcessors(),
new Mapped<>(
phi -> () -> {
final Path relative = Paths.get(
this.unphiInputDir.toPath().relativize(phi).toString().replace(
final Path relative = this.unphiInputDir.toPath().relativize(phi);
final Path xmir = Paths.get(
relative.toString().replace(
String.format(".%s", PhiMojo.EXT),
String.format(".%s", TranspileMojo.EXT)
)
);
home.save(
new PhiSyntax(
phi.getFileName().toString().replace(".phi", ""),
new TextOf(phi)
).parsed().toString(),
relative
);
final XML parsed = new PhiSyntax(
phi.getFileName().toString().replace(".phi", ""),
new TextOf(phi)
).parsed();
home.save(parsed.toString(), xmir);
Logger.info(
this,
"Parsed to xmir: %s -> %s",
phi, this.unphiOutputDir.toPath().resolve(relative)
phi, this.unphiOutputDir.toPath().resolve(xmir)
);
if (parsed.nodes("//errors[count(error)=0]").isEmpty()) {
errors.add(relative);
}
return 1;
},
new Walk(this.unphiInputDir.toPath())
)
)
).intValue();
Logger.info(this, "Parsed %d phi files to xmir", count);
if (!errors.isEmpty()) {
throw new IllegalStateException(
String.format(
"%d files with parsing errors were found: %s",
errors.size(),
Arrays.toString(errors.toArray())
)
);
}
}
}
15 changes: 15 additions & 0 deletions eo-maven-plugin/src/test/java/org/eolang/maven/UnphiMojoTest.java
Expand Up @@ -40,6 +40,7 @@
import org.eolang.parser.EoSyntax;
import org.hamcrest.MatcherAssert;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
Expand Down Expand Up @@ -69,6 +70,20 @@ void createsFile(@TempDir final Path temp) throws Exception {
);
}

@Test
void failsIfParsedWithErrors(@TempDir final Path temp) throws IOException {
new HmBase(temp).save(
"std ↦ Φ.org.eolang.io.stdout, y ↦ Φ.org.eolang.x",
Paths.get("target/phi/std.phi")
);
Assertions.assertThrows(
IllegalStateException.class,
() -> new FakeMaven(temp)
.execute(UnphiMojo.class),
"UnphiMojo execution should fail because of parsing errors"
);
}

@ParameterizedTest
@ClasspathSource(value = "org/eolang/maven/unphi", glob = "**.yaml")
void checksUnphiPacks(final String pack, @TempDir final Path temp) throws Exception {
Expand Down
82 changes: 0 additions & 82 deletions eo-parser/src/main/java/org/eolang/parser/EoSyntax.java
Expand Up @@ -27,24 +27,16 @@
import com.jcabi.xml.XML;
import com.jcabi.xml.XMLDocument;
import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.antlr.v4.runtime.ANTLRErrorListener;
import org.antlr.v4.runtime.BaseErrorListener;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.RecognitionException;
import org.antlr.v4.runtime.Recognizer;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
import org.cactoos.Input;
import org.cactoos.Text;
import org.cactoos.iterable.Mapped;
import org.cactoos.list.ListOf;
import org.cactoos.text.FormattedText;
import org.cactoos.text.Joined;
import org.cactoos.text.Split;
import org.cactoos.text.TextOf;
import org.xembly.Directive;
import org.xembly.Directives;
import org.xembly.Xembler;

Expand Down Expand Up @@ -137,78 +129,4 @@ private Text normalize() {
private List<Text> lines() {
return new ListOf<>(new Split(new TextOf(this.input), "\r?\n"));
}

/**
* Accumulates all parsing errors.
*
* @since 0.30.0
*/
private static final class ParsingErrors extends BaseErrorListener
implements ANTLRErrorListener, Iterable<Directive> {
/**
* Errors accumulated.
*/
private final List<ParsingException> errors;

/**
* The source.
*/
private final List<Text> lines;

/**
* Ctor.
* @param src The source in lines
*/
private ParsingErrors(final List<Text> src) {
this.errors = new LinkedList<>();
this.lines = src;
}

// @checkstyle ParameterNumberCheck (10 lines)
@Override
public void syntaxError(final Recognizer<?, ?> recognizer,
final Object symbol, final int line,
final int position, final String msg,
final RecognitionException error
) {
this.errors.add(
new ParsingException(
String.format(
"[%d:%d] %s: \"%s\"",
line, position, msg,
// @checkstyle AvoidInlineConditionalsCheck (1 line)
this.lines.size() < line ? "EOF" : this.lines.get(line - 1)
),
error,
line
)
);
}

@Override
public Iterator<Directive> iterator() {
return new org.cactoos.iterable.Joined<>(
new Mapped<Iterable<Directive>>(
error -> new Directives()
.xpath("/program/errors")
.add("error")
.attr("line", error.line())
.attr("severity", "critical")
.set(error.getMessage())
.up(),
this.errors
)
).iterator();
}

/**
* How many errors?
* @return Count of errors accumulated
*/
public int size() {
return this.errors.size();
}

}

}
119 changes: 119 additions & 0 deletions eo-parser/src/main/java/org/eolang/parser/ParsingErrors.java
@@ -0,0 +1,119 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2016-2023 Objectionary.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.eolang.parser;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.antlr.v4.runtime.ANTLRErrorListener;
import org.antlr.v4.runtime.BaseErrorListener;
import org.antlr.v4.runtime.RecognitionException;
import org.antlr.v4.runtime.Recognizer;
import org.cactoos.Text;
import org.cactoos.iterable.Mapped;
import org.cactoos.list.ListOf;
import org.xembly.Directive;
import org.xembly.Directives;

/**
* Accumulates all parsing errors.
* @since 0.30.0
*/
final class ParsingErrors extends BaseErrorListener
implements ANTLRErrorListener, Iterable<Directive> {
/**
* Errors accumulated.
*/
private final List<ParsingException> errors;

/**
* The source.
*/
private final List<Text> lines;

/**
* Ctor.
* @param lines The source in lines
*/
ParsingErrors(final Text... lines) {
this(new ListOf<>(lines));
}

/**
* Ctor.
* @param src The source in lines
*/
ParsingErrors(final List<Text> src) {
this.errors = new LinkedList<>();
this.lines = src;
}

// @checkstyle ParameterNumberCheck (10 lines)
@Override
public void syntaxError(
final Recognizer<?, ?> recognizer,
final Object symbol,
final int line,
final int position,
final String msg,
final RecognitionException error
) {
this.errors.add(
new ParsingException(
String.format(
"[%d:%d] %s: \"%s\"",
line, position, msg,
// @checkstyle AvoidInlineConditionalsCheck (1 line)
this.lines.size() < line ? "EOF" : this.lines.get(line - 1)
),
error,
line
)
);
}

@Override
public Iterator<Directive> iterator() {
return new org.cactoos.iterable.Joined<>(
new Mapped<Iterable<Directive>>(
error -> new Directives()
.xpath("/program/errors")
.add("error")
.attr("line", error.line())
.attr("severity", "critical")
.set(error.getMessage())
.up(),
this.errors
)
).iterator();
}

/**
* How many errors?
* @return Count of errors accumulated
*/
public int size() {
return this.errors.size();
}
}
42 changes: 29 additions & 13 deletions eo-parser/src/main/java/org/eolang/parser/PhiSyntax.java
Expand Up @@ -50,6 +50,14 @@ public final class PhiSyntax implements Syntax {
*/
private final Text input;

/**
* Ctor for the tests.
* @param input Input
*/
PhiSyntax(final String input) {
this("test", () -> input);
}

/**
* Ctor.
* @param nme Name of the program
Expand All @@ -63,25 +71,33 @@ public PhiSyntax(final String nme, final Text inpt) {
@Override
public XML parsed() throws IOException {
final XePhiListener xel = new XePhiListener(this.name);
new ParseTreeWalker().walk(
xel,
new PhiParser(
new CommonTokenStream(
new PhiLexer(
CharStreams.fromStream(
new InputStreamOf(this.input)
)
)
)
).program()
final ParsingErrors spy = new ParsingErrors(this.input);
final PhiLexer lexer = new PhiLexer(
CharStreams.fromStream(
new InputStreamOf(this.input)
)
);
lexer.addErrorListener(spy);
final PhiParser parser = new PhiParser(
new CommonTokenStream(lexer)
);
parser.removeErrorListeners();
parser.addErrorListener(spy);
new ParseTreeWalker().walk(xel, parser.program());
final XML dom = new XMLDocument(
new Xembler(
new Directives(xel)
new Directives(xel).append(spy)
).domQuietly()
);
new Schema(dom).check();
Logger.debug(this, "Input of PHI calculus compiled, no errors");
if (spy.size() == 0) {
Logger.debug(this, "Input of PHI calculus compiled, no errors");
} else {
Logger.debug(
this, "Input of PHI calculus failed to compile (%d errors)",
spy.size()
);
}
return dom;
}
}

0 comments on commit 63864e3

Please sign in to comment.