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

feat(#3639): xmir to phi #3640

Merged
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
85 changes: 27 additions & 58 deletions eo-maven-plugin/src/main/java/org/eolang/maven/PhiMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,9 @@
import com.jcabi.log.Logger;
import com.jcabi.xml.XML;
import com.jcabi.xml.XMLDocument;
import com.yegor256.xsline.Shift;
import com.yegor256.xsline.StClasspath;
import com.yegor256.xsline.TrDefault;
import com.yegor256.xsline.TrJoined;
import com.yegor256.xsline.Train;
import com.yegor256.xsline.Xsline;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
Expand All @@ -44,8 +37,7 @@
import org.eolang.maven.footprint.Saved;
import org.eolang.maven.util.Threaded;
import org.eolang.maven.util.Walk;
import org.eolang.parser.StUnhex;
import org.eolang.parser.TrParsing;
import org.eolang.parser.Xmir;

/**
* Read XMIR files and translate them to the phi-calculus expression.
Expand All @@ -62,16 +54,6 @@ public final class PhiMojo extends SafeMojo {
*/
public static final String EXT = "phi";

/**
* Train of mandatory transformations.
*/
private static final Train<Shift> TRANSFORMATIONS = new TrDefault<>(
new StClasspath("/org/eolang/maven/phi/incorrect-inners.xsl"),
new StUnhex(),
new StClasspath("/org/eolang/maven/phi/wrap-default-package.xsl"),
new StClasspath("/org/eolang/maven/phi/to-phi.xsl")
);

/**
* The directory where to take xmir files for translation from.
* @checkstyle MemberNameCheck (10 lines)
Expand All @@ -95,26 +77,23 @@ public final class PhiMojo extends SafeMojo {
private File phiOutputDir;

/**
* Pass XMIR to Optimizations train or not.
* This flag is used for test in order not to optimize XMIR twice:
* in {@link OptimizeMojo} and here.
* @checkstyle MemberNameCheck (5 lines)
* Convert to PHI without syntax sugar.
* @checkstyle MemberNameCheck (10 lines)
*/
@Parameter(property = "eo.phiOptimize", required = true, defaultValue = "true")
@Parameter(property = "eo.phiNoSugar", required = true, defaultValue = "false")
@SuppressWarnings("PMD.ImmutableField")
private boolean phiOptimize = true;
private boolean phiNoSugar;

@Override
public void exec() {
final AtomicInteger passed = new AtomicInteger();
final Walk walk = new Walk(this.phiInputDir.toPath());
final int total = walk.size();
final Xsline xsline = new Xsline(this.train());
final int count = new Threaded<>(
walk,
xmir -> {
final int position = passed.addAndGet(1);
return this.translate(xmir, xsline, position, total);
return this.translate(xmir, position, total);
}
).total();
if (count > 0) {
Expand All @@ -133,31 +112,30 @@ public void exec() {
/**
* Translate one XMIR file to .phi file.
* @param xmir The XMIR file
* @param xsline Chain of XSL transformations
* @param position Its position in the entire pack
* @param total How many files are there
* @return How many files translated (either 1 or 0)
* @throws Exception If fails
* @checkstyle ParameterNumberCheck (5 lines)
*/
private int translate(final Path xmir, final Xsline xsline, final int position, final int total)
private int translate(final Path xmir, final int position, final int total)
throws Exception {
final long start = System.currentTimeMillis();
Logger.debug(
this,
"Processing XMIR (#%d/%d): %[file]s (%[size]s)...",
position, total, xmir, xmir.toFile().length()
);
final XML xml = new XMLDocument(new TextOf(xmir).asString());
final Path relative = Paths.get(
this.phiInputDir.toPath().relativize(xmir).toString().replace(
String.format(".%s", AssembleMojo.XMIR),
String.format(".%s", PhiMojo.EXT)
)
);
final Path target = this.phiOutputDir.toPath().resolve(relative);
final XML xml = new XMLDocument(new TextOf(xmir).asString());
try {
new Saved(PhiMojo.translated(xsline, xml), target).value();
new Saved(this.translated(xml), target).value();
Logger.info(
this,
"Translated to phi (#%d/%d): %[file]s (%[size]s) -> %[file]s (%[size]s) in %[ms]s",
Expand All @@ -176,38 +154,28 @@ private int translate(final Path xmir, final Xsline xsline, final int position,
return 1;
}

/**
* Build transformations train depends on flags.
* @return Transformations train
*/
private Train<Shift> train() {
final Train<Shift> train;
if (this.phiOptimize) {
train = new TrParsing();
} else {
train = new TrDefault<>();
}
return this.measured(new TrJoined<>(train, PhiMojo.TRANSFORMATIONS));
}

/**
* Translate given xmir to phi calculus expression.
* @param xsline Chain of XSL optimizations and transformations
* @param xmir Text of xmir
* @param xml Text of xmir
* @return Translated xmir
* @throws ImpossibleToPhiTranslationException If fails to translate given XMIR to phi
*/
private static String translated(final Xsline xsline, final XML xmir)
throws ImpossibleToPhiTranslationException {
final XML translated = xsline.pass(xmir);
Logger.debug(PhiMojo.class, "XML after translation to phi:\n%s", translated);
final List<String> phi = translated.xpath("program/phi/text()");
if (phi.isEmpty()) {
private String translated(final XML xml) throws ImpossibleToPhiTranslationException {
final Xmir xmir = new Xmir(xml);
final String phi;
try {
if (this.phiNoSugar) {
phi = xmir.toPhiNoSugar();
} else {
phi = xmir.toPhi();
}
} catch (final IndexOutOfBoundsException exception) {
throw new ImpossibleToPhiTranslationException(
"Xpath 'phi/text()' is not found in the translated XMIR"
String.format("Xpath 'phi/text()' is not found in the translated XMIR: \n%s", xmir),
exception
);
}
return phi.get(0);
return phi;
}

/**
Expand All @@ -217,10 +185,11 @@ private static String translated(final Xsline xsline, final XML xmir)
private static class ImpossibleToPhiTranslationException extends Exception {
/**
* Ctor.
* @param cause Cause of the exception.
* @param message Exception message
* @param cause Previous exception
*/
ImpossibleToPhiTranslationException(final String cause) {
super(cause);
ImpossibleToPhiTranslationException(final String message, final Exception cause) {
super(message, cause);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ void exec() throws IOException {
final XML xml = new XMLDocument(new TextOf(source).asString());
final String program;
if (this.printReversed) {
program = new Xmir(xml).toReversed();
program = new Xmir(xml).toReversedEO();
} else {
program = new Xmir(xml).toEO();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ public <T extends AbstractMojo> FakeMaven execute(final Class<T> mojo) throws IO
this.params.putIfAbsent("objectionaries", new Objectionaries.Fake());
this.params.putIfAbsent("rewriteBinaries", true);
this.params.putIfAbsent("offline", false);
this.params.putIfAbsent("phiOptimize", false);
this.params.putIfAbsent("phiNoSugar", false);
this.params.putIfAbsent("phiSkipFailed", false);
this.params.putIfAbsent(
"eoPortalDir",
Expand Down
67 changes: 25 additions & 42 deletions eo-maven-plugin/src/test/java/org/eolang/maven/PhiMojoTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,10 @@
import com.yegor256.MktmpResolver;
import com.yegor256.WeAreOnline;
import com.yegor256.farea.Farea;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.cactoos.text.TextOf;
import org.eolang.jucs.ClasspathSource;
import org.eolang.maven.util.HmBase;
import org.eolang.xax.XtSticky;
import org.eolang.xax.XtYaml;
import org.eolang.xax.Xtory;
Expand Down Expand Up @@ -135,12 +131,7 @@ void convertsObjectWithSystemType(@Mktmp final Path temp) throws Exception {
MatcherAssert.assertThat(
"the .xmir file is generated",
XhtmlMatchers.xhtml(
new String(
Files.readAllBytes(
temp.resolve("target/eo/2-optimize/org/eolang/bytes.xmir")
),
StandardCharsets.UTF_8
)
Files.readString(temp.resolve("target/eo/2-optimize/org/eolang/bytes.xmir"))
),
XhtmlMatchers.hasXPaths(
"/program/objects/o[@name='bytes']",
Expand Down Expand Up @@ -180,34 +171,6 @@ void createsFiles(@Mktmp final Path temp) throws Exception {
);
}

@ParameterizedTest
@ClasspathSource(value = "org/eolang/maven/phi/xmir", glob = "**.xmir")
void convertsXmirsToPhiWithoutCriticalErrorsWithoutOptimizations(
final String xmir,
@Mktmp final Path temp
) throws IOException {
final FakeMaven maven = new FakeMaven(temp);
new HmBase(temp).save(xmir, Paths.get("target/2-optimize/test.xmir"));
Assertions.assertDoesNotThrow(
() -> maven.execute(PhiMojo.class),
BinarizeParseTest.TO_ADD_MESSAGE
);
}

@ParameterizedTest
@ClasspathSource(value = "org/eolang/maven/phi/xmir", glob = "**.xmir")
void convertsXmirsToPhiWithoutCriticalErrorsWithOptimizations(
final String xmir,
@Mktmp final Path temp
) throws IOException {
final FakeMaven maven = new FakeMaven(temp);
new HmBase(temp).save(xmir, Paths.get("target/2-optimize/test.xmir"));
Assertions.assertDoesNotThrow(
() -> maven.execute(PhiMojo.class),
BinarizeParseTest.TO_ADD_MESSAGE
);
}

@Test
void doesNotFailOnError(@Mktmp final Path temp) {
Assertions.assertDoesNotThrow(
Expand All @@ -223,20 +186,40 @@ void doesNotFailOnError(@Mktmp final Path temp) {
}

@ParameterizedTest
@ClasspathSource(value = "org/eolang/maven/phi/yaml", glob = "**.yaml")
void checksPhiPacks(final String pack, @Mktmp final Path temp) throws Exception {
@ClasspathSource(value = "org/eolang/maven/phi-packs", glob = "**.yaml")
void checksPhiPacksWithSugar(final String pack, @Mktmp final Path temp) throws Exception {
final Xtory xtory = new XtSticky(new XtYaml(pack));
Assumptions.assumeTrue(xtory.map().get("skip") == null);
MatcherAssert.assertThat(
"must convert to exactly the expression we need with syntax sugar",
new TextOf(
new FakeMaven(temp)
.withProgram(xtory.map().get("input").toString())
.with("phiNoSugar", false)
.execute(new FakeMaven.Phi())
.result()
.get("target/phi/foo/x/main.phi")
).asString(),
Matchers.equalTo(xtory.map().get("with-sugar").toString())
);
}

@ParameterizedTest
@ClasspathSource(value = "org/eolang/maven/phi-packs", glob = "**.yaml")
void checksPhiPacksNoSugar(final String pack, @Mktmp final Path temp) throws Exception {
final Xtory xtory = new XtSticky(new XtYaml(pack));
Assumptions.assumeTrue(xtory.map().get("skip") == null);
MatcherAssert.assertThat(
"must convert to exactly the expression we need",
"must convert to exactly the expression we need without syntax sugar",
new TextOf(
new FakeMaven(temp)
.withProgram(xtory.map().get("input").toString())
.with("phiNoSugar", true)
.execute(new FakeMaven.Phi())
.result()
.get("target/phi/foo/x/main.phi")
).asString(),
Matchers.equalTo(xtory.map().get("phi").toString())
Matchers.equalTo(xtory.map().get("no-sugar").toString())
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,11 @@ void printsSimpleObject(@Mktmp final Path temp) throws Exception {
@Test
void printsSuccessfully(@Mktmp final Path temp) throws Exception {
final Home home = new HmBase(temp);
final Path resources = new File("src/test/resources/org/eolang/maven/print/xmir")
.toPath();
final Path resources = new File(
"../eo-parser/src/test/resources/org/eolang/parser/print-packs/xmir"
).toPath();
final Collection<Path> walk = new Walk(resources);
Assumptions.assumeTrue(!walk.isEmpty());
for (final Path source : walk) {
home.save(new TextOf(source), source);
}
Expand All @@ -114,7 +116,7 @@ void printsSuccessfully(@Mktmp final Path temp) throws Exception {
}

@ParameterizedTest
@ClasspathSource(value = "org/eolang/maven/print/samples/", glob = "**.yaml")
@ClasspathSource(value = "org/eolang/maven/print-packs", glob = "**.yaml")
void printsInStraightNotation(final String pack, @Mktmp final Path temp) throws Exception {
final Xtory xtory = new XtSticky(new XtYaml(pack));
Assumptions.assumeTrue(xtory.map().get("skip") == null);
Expand All @@ -126,7 +128,7 @@ void printsInStraightNotation(final String pack, @Mktmp final Path temp) throws
}

@ParameterizedTest
@ClasspathSource(value = "org/eolang/maven/print/samples/", glob = "**.yaml")
@ClasspathSource(value = "org/eolang/maven/print-packs", glob = "**.yaml")
void printsInReversedNotation(final String pack, @Mktmp final Path temp) throws Exception {
final Xtory xtory = new XtSticky(new XtYaml(pack));
Assumptions.assumeTrue(xtory.map().get("skip") == null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,11 +228,11 @@ void checksUnphiPacks(final String pack, @Mktmp final Path temp) throws Exceptio
}

@ParameterizedTest
@ClasspathSource(value = "org/eolang/maven/phi", glob = "**.yaml")
@ClasspathSource(value = "org/eolang/maven/phi-packs", glob = "**.yaml")
void convertsToXmirAndBack(final String pack, @Mktmp final Path temp) throws Exception {
final Xtory xtory = new XtSticky(new XtYaml(pack));
Assumptions.assumeTrue(xtory.map().get("skip") == null);
final String phi = xtory.map().get("phi").toString();
final String phi = xtory.map().get("with-sugar").toString();
final String main = "target/phi/main.phi";
final Path path = Paths.get(main);
new HmBase(temp).save(phi, path);
Expand Down
Loading
Loading