diff --git a/eo-maven-plugin/src/main/java/org/eolang/maven/UnphiMojo.java b/eo-maven-plugin/src/main/java/org/eolang/maven/UnphiMojo.java index 3e5d16660e..93ce623cdc 100644 --- a/eo-maven-plugin/src/main/java/org/eolang/maven/UnphiMojo.java +++ b/eo-maven-plugin/src/main/java/org/eolang/maven/UnphiMojo.java @@ -29,19 +29,29 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; +import java.util.Iterator; import java.util.List; +import java.util.Set; 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.IterableEnvelope; +import org.cactoos.iterable.IterableOf; +import org.cactoos.iterable.Joined; import org.cactoos.iterable.Mapped; import org.cactoos.list.ListOf; import org.cactoos.number.SumOf; +import org.cactoos.set.SetOf; import org.cactoos.text.TextOf; import org.eolang.maven.util.HmBase; import org.eolang.maven.util.Home; import org.eolang.maven.util.Walk; import org.eolang.parser.PhiSyntax; +import org.eolang.parser.XeEoListener; +import org.xembly.Directive; +import org.xembly.Directives; +import org.xembly.Xembler; /** * Read PHI files and parse them to the XMIR. @@ -75,10 +85,18 @@ public final class UnphiMojo extends SafeMojo { ) private File unphiOutputDir; + /** + * Extra metas to add to unphied XMIR. + * @checkstyle MemberNameCheck (10 lines) + */ + @Parameter(property = "eo.unphiMetas") + private Set unphiMetas = new SetOf<>(); + @Override public void exec() { final List errors = new ListOf<>(); final Home home = new HmBase(this.unphiOutputDir); + final Iterable metas = new UnphiMojo.Metas(this.unphiMetas); final int count = new SumOf( new Threads<>( Runtime.getRuntime().availableProcessors(), @@ -93,7 +111,8 @@ public void exec() { ); final XML parsed = new PhiSyntax( phi.getFileName().toString().replace(".phi", ""), - new TextOf(phi) + new TextOf(phi), + metas ).parsed(); home.save(parsed.toString(), xmir); Logger.info( @@ -121,4 +140,53 @@ public void exec() { ); } } + + /** + * Accumulates all metas that should be attached to unphied XMIR. + * +package meta is prohibited since it's converted to special object + * with "λ -> Package" binding. + * @since 0.36.0 + */ + private static class Metas extends IterableEnvelope { + /** + * Package meta. + */ + private static final String PACKAGE = "+package"; + + /** + * Ctor. + * @param metas Metas to append + */ + Metas(final Iterable metas) { + super( + new Joined<>( + new Mapped<>( + meta -> { + final String[] pair = meta.split(" ", 2); + final String head = pair[0].substring(1); + if (head.equals(UnphiMojo.Metas.PACKAGE)) { + throw new IllegalStateException( + "+package meta can't be attached to unphied XMIR" + ); + } + final Directives dirs = new Directives() + .xpath("/program/metas") + .add("head").set(head).up() + .add("tail"); + if (pair.length > 1) { + dirs.set(pair[1].trim()).up(); + for (final String part : pair[1].trim().split(" ")) { + dirs.add("part").set(part).up(); + } + } else { + dirs.up(); + } + return dirs.up(); + }, + metas + ) + ) + ); + } + } } diff --git a/eo-parser/src/main/java/org/eolang/parser/PhiSyntax.java b/eo-parser/src/main/java/org/eolang/parser/PhiSyntax.java index 8311f38ebc..35a2743dd4 100644 --- a/eo-parser/src/main/java/org/eolang/parser/PhiSyntax.java +++ b/eo-parser/src/main/java/org/eolang/parser/PhiSyntax.java @@ -32,6 +32,7 @@ import org.antlr.v4.runtime.tree.ParseTreeWalker; import org.cactoos.Text; import org.cactoos.io.InputStreamOf; +import org.xembly.Directive; import org.xembly.Directives; import org.xembly.Xembler; @@ -50,22 +51,33 @@ public final class PhiSyntax implements Syntax { */ private final Text input; + /** + * Extra directives to append to parsed phi. + */ + private final Iterable extra; + /** * Ctor for the tests. * @param input Input */ PhiSyntax(final String input) { - this("test", () -> input); + this("test", () -> input, new Directives()); } /** * Ctor. * @param nme Name of the program * @param inpt Input + * @param extra Extra directives to append */ - public PhiSyntax(final String nme, final Text inpt) { + public PhiSyntax( + final String nme, + final Text inpt, + final Iterable extra + ) { this.name = nme; this.input = inpt; + this.extra = extra; } @Override @@ -86,7 +98,7 @@ public XML parsed() throws IOException { new ParseTreeWalker().walk(xel, parser.program()); final XML dom = new XMLDocument( new Xembler( - new Directives(xel).append(spy) + new Directives(xel).append(spy).append(extra) ).domQuietly() ); new Schema(dom).check(); diff --git a/eo-parser/src/test/java/org/eolang/parser/PhiSyntaxTest.java b/eo-parser/src/test/java/org/eolang/parser/PhiSyntaxTest.java index 20aec0eae8..c36c7e57a0 100644 --- a/eo-parser/src/test/java/org/eolang/parser/PhiSyntaxTest.java +++ b/eo-parser/src/test/java/org/eolang/parser/PhiSyntaxTest.java @@ -27,6 +27,7 @@ import java.io.IOException; import org.hamcrest.MatcherAssert; import org.junit.jupiter.api.Test; +import org.xembly.Directives; /** * Test cases for {@link PhiSyntax}. @@ -46,4 +47,19 @@ void addsError() throws IOException { ) ); } + + @Test + void addsExtra() throws IOException { + MatcherAssert.assertThat( + "Result XML must contain extra object", + new PhiSyntax( + "test", + () -> "{⟦obj ↦ ⟦⟧⟧}", + new Directives().xpath("/program/objects").add("o").attr("base", "x") + ).parsed(), + XhtmlMatchers.hasXPath( + "//objects/o[@base='x']" + ) + ); + } }