Skip to content

Commit

Permalink
Merge pull request #3640 from maxonfjvipon/feat/#3639/to-phi-without-…
Browse files Browse the repository at this point in the history
…sugar

feat(#3639): xmir to phi
  • Loading branch information
yegor256 authored Dec 11, 2024
2 parents 9412f11 + bc7226f commit 1a696e2
Show file tree
Hide file tree
Showing 208 changed files with 1,188 additions and 4,396 deletions.
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

0 comments on commit 1a696e2

Please sign in to comment.