Merge branch 'master' into 3160-enable-pmd-in-eo-runtime

This commit is contained in:
Roman Korostinskiy 2024-06-24 12:00:22 +03:00
commit ba2a9e3861
No known key found for this signature in database
34 changed files with 604 additions and 319 deletions

View File

@ -38,7 +38,7 @@ jobs:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: teatimeguest/setup-texlive-action@v3.2.1
- uses: teatimeguest/setup-texlive-action@v3.3.0
with:
update-all-packages: true
packages: scheme-basic geometry xcolor naive-ebnf microtype etoolbox

View File

@ -20,42 +20,29 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
---
name: license
on:
name: copyrights
'on':
push:
pull_request:
jobs:
license:
copyrights:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: yegor256/copyrights-action@0.0.4
with:
fetch-depth: 0
- run: |
set -e
find . -type f \( \
-name "LICENSE.*" \
-o -name "*.sh" \
-o -name "*.yml" \
-o -name "*.yaml" \
-o -name "*.eo" \
-o -name "*.xmir" \
-o -name "*.xml" \
-o -name "*.xsl" \
-o -name "*.xsd" \
-o -name "*.ini" \
-o -name "*.java" \
-o -name "*.g4" \
-o -name "*.properties" \
-o -name "*.groovy" \) > files.txt
header="Copyright (c) 2016-$(date +%Y) Objectionary.com"
failed="false"
while IFS= read -r file; do
if ! grep -q "$header" "$file"; then
failed="true"
echo "No license in: $file"
fi
done < files.txt
if [ "${failed}" == "true" ]; then
exit 1
fi
globs: >-
**/LICENSE.txt
**/*.sh
**/*.yml
**/*.yaml
**/*.eo
**/*.xmir
**/*.xml
**/*.xsl
**/*.xsd
**/*.ini
**/*.java
**/*.g4
**/*.properties
**/*.groovy

View File

@ -30,7 +30,7 @@ jobs:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: teatimeguest/setup-texlive-action@v3.2.1
- uses: teatimeguest/setup-texlive-action@v3.3.0
with:
update-all-packages: true
packages: scheme-basic geometry xcolor naive-ebnf microtype etoolbox

View File

@ -38,7 +38,7 @@ jobs:
- run: |
sudo apt-get update
sudo apt-get -y install ghostscript imagemagick texlive-extra-utils pdf2svg inkscape
- uses: teatimeguest/setup-texlive-action@v3.2.1
- uses: teatimeguest/setup-texlive-action@v3.3.0
with:
update-all-packages: true
packages: scheme-basic geometry xcolor naive-ebnf microtype etoolbox

View File

@ -35,13 +35,13 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: teatimeguest/setup-texlive-action@v3.2.1
- uses: teatimeguest/setup-texlive-action@v3.3.0
with:
update-all-packages: true
packages: scheme-basic geometry xcolor naive-ebnf microtype etoolbox
- uses: actions/setup-java@v4
with:
java-version: 20
java-version: 17
distribution: 'zulu'
- uses: actions/cache@v4
with:

43
.github/workflows/trufflehog-oss.yml vendored Normal file
View File

@ -0,0 +1,43 @@
# The MIT License (MIT)
#
# Copyright (c) 2016-2024 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.
---
name: trufflehog-oss
'on':
push:
branches:
- master
pull_request:
branches:
- master
jobs:
trufflehog:
runs-on: ubuntu-22.04
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Secret Scanning
uses: trufflesecurity/trufflehog@main
with:
extra_args: --only-verified

View File

@ -35,7 +35,7 @@ create a file `pom.xml` with this content (it's just a sample):
<plugin>
<groupId>org.eolang</groupId>
<artifactId>eo-maven-plugin</artifactId>
<version>0.38.1</version>
<version>0.38.4</version>
<executions>
<execution>
<goals>
@ -156,7 +156,7 @@ execution within `eo-maven-plugin/pom.xml`:
...
<plugin>
<artifactId>maven-invoker-plugin</artifactId>
<version>0.38.1</version>
<version>0.38.4</version>
<configuration>
<skipInstallation>true</skipInstallation>
<skipInvocation>true</skipInvocation>

View File

@ -96,25 +96,25 @@ SOFTWARE.
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>3.9.6</version>
<version>3.9.7</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-model</artifactId>
<version>3.9.6</version>
<version>3.9.8</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>
<version>3.9.6</version>
<version>3.9.8</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>3.13.0</version>
<version>3.13.1</version>
<scope>provided</scope>
</dependency>
<dependency>
@ -126,7 +126,7 @@ SOFTWARE.
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-compat</artifactId>
<version>3.9.6</version>
<version>3.9.8</version>
<scope>test</scope>
</dependency>
<dependency>

View File

@ -36,6 +36,7 @@ import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import net.sf.saxon.expr.instruct.TerminationException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
@ -87,6 +88,21 @@ public final class PhiMojo extends SafeMojo {
)
private File phiOutputDir;
/**
* Whether {@link PhiMojo} should fail on critical errors or not.
* @checkstyle MemberNameCheck (10 lines)
*/
@Parameter(property = "eo.phiFailOnCritical", required = true, defaultValue = "true")
@SuppressWarnings({"PMD.ImmutableField", "PMD.LongVariable"})
private boolean phiFailOnCritical = true;
/**
* Whether {@link PhiMojo} should skip XMIRs that failed on critical errors.
* @checkstyle MemberNameCheck (10 lines)
*/
@Parameter(property = "eo.phiSkipFailed", required = true, defaultValue = "false")
private boolean phiSkipFailed;
/**
* Pass XMIR to Optimizations train or not.
* This flag is used for test in order not to optimize XMIR twice:
@ -100,12 +116,7 @@ public final class PhiMojo extends SafeMojo {
@Override
public void exec() {
final Home home = new HmBase(this.phiOutputDir);
final Train<Shift> train;
if (this.phiOptimize) {
train = new ParsingTrain();
} else {
train = new TrDefault<>();
}
final Train<Shift> train = this.train();
final int count = new SumOf(
new Threads<>(
Runtime.getRuntime().availableProcessors(),
@ -127,8 +138,18 @@ public final class PhiMojo extends SafeMojo {
String.format(".%s", PhiMojo.EXT)
)
);
int amount;
try {
home.save(PhiMojo.translated(train, xml), relative);
Logger.info(
this,
"Translated to phi: %[file]s (%[size]s) -> %[file]s (%[size]s)",
processed,
xmir.toFile().length(),
relative,
this.phiOutputDir.toPath().resolve(relative).toFile().length()
);
amount = 1;
} catch (final ImpossibleToPhiTranslationException exception) {
Logger.debug(
this,
@ -139,16 +160,20 @@ public final class PhiMojo extends SafeMojo {
String.format("Couldn't translate %s to phi", processed),
exception
);
} catch (final IllegalArgumentException exception) {
if (exception.getCause() instanceof TerminationException
&& this.phiSkipFailed) {
Logger.info(
this,
"%[file]s failed on critical error, but skipped because phiSkipFailed=true",
processed
);
amount = 0;
} else {
throw exception;
}
}
Logger.info(
this,
"Translated to phi: %[file]s (%[size]s) -> %[file]s (%[size]s)",
processed,
xmir.toFile().length(),
relative,
this.phiOutputDir.toPath().resolve(relative).toFile().length()
);
return 1;
return amount;
},
new Walk(this.phiInputDir.toPath())
)
@ -167,6 +192,36 @@ public final class PhiMojo extends SafeMojo {
}
}
/**
* Build transformations train depends on flags.
* @return Transformations train
*/
private Train<Shift> train() {
final Train<Shift> train;
if (this.phiOptimize) {
train = new ParsingTrain();
} else {
train = new TrDefault<>();
}
final Train.Temporary<Shift> dependent;
if (this.phiFailOnCritical) {
dependent = new TrClasspath<>(
"/org/eolang/parser/fail-on-critical.xsl",
"/org/eolang/maven/phi/to-phi.xsl"
);
} else {
dependent = new TrClasspath<>("/org/eolang/maven/phi/to-phi.xsl");
}
return new TrJoined<>(
train,
new TrClasspath<>(
"/org/eolang/parser/critical-errors/duplicate-names.xsl",
"/org/eolang/maven/phi/incorrect-inners.xsl"
).back(),
dependent.back()
);
}
/**
* Translate given xmir to phi calculus expression.
* @param train Train that optimize and translates given xmir
@ -176,17 +231,7 @@ public final class PhiMojo extends SafeMojo {
*/
private static String translated(final Train<Shift> train, final XML xmir)
throws ImpossibleToPhiTranslationException {
final XML translated = new Xsline(
new TrJoined<>(
train,
new TrClasspath<>(
"/org/eolang/parser/critical-errors/duplicate-names.xsl",
"/org/eolang/maven/phi/incorrect-inners.xsl",
"/org/eolang/parser/fail-on-critical.xsl",
"/org/eolang/maven/phi/to-phi.xsl"
).back()
)
).pass(xmir);
final XML translated = new Xsline(train).pass(xmir);
Logger.debug(PhiMojo.class, "XML after translation to phi:\n%s", translated);
final List<String> phi = translated.xpath("phi/text()");
if (phi.isEmpty()) {

View File

@ -125,8 +125,18 @@ public final class PullMojo extends SafeMojo {
)
);
names.add(name);
tojo.withSource(this.pull(name).toAbsolutePath())
.withHash(new ChNarrow(name.hash()));
try {
tojo.withSource(this.pull(name).toAbsolutePath())
.withHash(new ChNarrow(name.hash()));
} catch (final IOException exception) {
throw new IOException(
String.format(
"Failed to pull object discovered at %s",
tojo.discoveredAt()
),
exception
);
}
}
Logger.info(
this,

View File

@ -25,6 +25,8 @@ package org.eolang.maven;
import com.jcabi.log.Logger;
import com.jcabi.xml.XML;
import com.yegor256.xsline.TrClasspath;
import com.yegor256.xsline.Xsline;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
@ -59,6 +61,17 @@ import org.xembly.Directives;
threadSafe = true
)
public final class UnphiMojo extends SafeMojo {
/**
* Unphi transformations.
*/
private static final Xsline TRANSFORMATIONS = new Xsline(
new TrClasspath<>(
"/org/eolang/maven/unphi/wrap-bytes.xsl",
"/org/eolang/parser/wrap-method-calls.xsl",
"/org/eolang/maven/unphi/atoms-with-bound-attrs.xsl"
).back()
);
/**
* The directory where to take phi files for parsing from.
* @checkstyle MemberNameCheck (10 lines)
@ -106,18 +119,20 @@ public final class UnphiMojo extends SafeMojo {
String.format(".%s", TranspileMojo.EXT)
)
);
final XML parsed = new PhiSyntax(
phi.getFileName().toString().replace(".phi", ""),
new TextOf(phi),
metas
).parsed();
home.save(parsed.toString(), xmir);
final XML result = TRANSFORMATIONS.pass(
new PhiSyntax(
phi.getFileName().toString().replace(".phi", ""),
new TextOf(phi),
metas
).parsed()
);
home.save(result.toString(), xmir);
Logger.info(
this,
"Parsed to xmir: %s -> %s",
phi, this.unphiOutputDir.toPath().resolve(xmir)
);
if (parsed.nodes("//errors[count(error)=0]").isEmpty()) {
if (result.nodes("//errors[count(error)=0]").isEmpty()) {
errors.add(relative);
}
return 1;

View File

@ -37,7 +37,7 @@ import org.eolang.maven.util.Rel;
*
* @since 0.30
*/
@SuppressWarnings("PMD.TooManyMethods")
@SuppressWarnings({"PMD.TooManyMethods", "PMD.GodClass"})
public final class ForeignTojo {
/**
@ -137,6 +137,14 @@ public final class ForeignTojo {
return this.attribute(ForeignTojos.Attribute.PROBED);
}
/**
* The discovered at location.
* @return The discovered at.
*/
public String discoveredAt() {
return this.attribute(ForeignTojos.Attribute.DISCOVERED_AT);
}
/**
* Checks if tojo was not already optimized.
*

View File

@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
The MIT License (MIT)
Copyright (c) 2016-2024 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.
-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" id="atoms-with-bound-attrs" version="2.0">
<!--
Convert such expression in XMIR:
x ↦ ⟦
text ↦ Φ.org.eolang.bytes (Δ ⤍ 48-65-6C-6C-6F-20-77-6F-72-6C-64-0A),
size ↦ Φ.org.eolang.bytes (Δ ⤍ 00-00-00-00-00-00-00-08),
λ ⤍ Lorg_eolang_io_stdout
to this:
x ↦ Φ.org.eolang.io.stdout(
text ↦ Φ.org.eolang.bytes (Δ ⤍ 48-65-6C-6C-6F-20-77-6F-72-6C-64-0A),
size ↦ Φ.org.eolang.bytes (Δ ⤍ 00-00-00-00-00-00-00-08)
)
-->
<xsl:output encoding="UTF-8" method="xml"/>
<xsl:template match="o[@abstract and @atom and starts-with(@atom, 'L') and @name and count(o[@base])&gt;0]">
<xsl:element name="o">
<xsl:attribute name="name" select="@name"/>
<xsl:attribute name="base">
<xsl:for-each select="tokenize(@atom,'_')">
<xsl:choose>
<xsl:when test="position()=1">
<xsl:value-of select="substring(., 2)"/>
</xsl:when>
<xsl:otherwise>
<xsl:text>.</xsl:text>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:attribute>
<xsl:for-each select="o">
<xsl:element name="o">
<xsl:for-each select="@*[name()!='name']">
<xsl:attribute name="{name()}" select="."/>
</xsl:for-each>
<xsl:attribute name="as" select="@name"/>
<xsl:copy-of select="*"/>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:template>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

View File

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
The MIT License (MIT)
Copyright (c) 2016-2024 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.
-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" id="wrap-bytes" version="2.0">
<!--
Convert such expression in XMIR:
x ↦ ⟦ Δ ⤍ 01- ⟧,
to this:
x ↦ Φ.org.eolang.bytes( Δ ⤍ 01- )
-->
<xsl:output encoding="UTF-8" method="xml"/>
<xsl:template match="o[@abstract and @name and count(o)=1 and o[@base='org.eolang.bytes' and @data and text()]]">
<xsl:element name="o">
<xsl:attribute name="base">org.eolang.bytes</xsl:attribute>
<xsl:attribute name="name" select="@name"/>
<xsl:attribute name="data" select="'bytes'"/>
<xsl:value-of select="o[1]/text()"/>
</xsl:element>
</xsl:template>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

View File

@ -239,6 +239,8 @@ public final class FakeMaven {
this.params.putIfAbsent("rewriteBinaries", true);
this.params.putIfAbsent("offline", false);
this.params.putIfAbsent("phiOptimize", false);
this.params.putIfAbsent("phiFailOnCritical", true);
this.params.putIfAbsent("phiSkipFailed", false);
this.params.putIfAbsent(
"eoPortalDir",
new File("../eo-runtime/src/main/rust/eo")

View File

@ -80,6 +80,62 @@ final class PhiMojoTest {
);
}
@Test
void doesNotFailOnCritical(@TempDir final Path temp) {
Assertions.assertDoesNotThrow(
() -> new FakeMaven(temp)
.with("phiFailOnCritical", false)
.withProgram(
"# This is the default 64+ symbols comment in front of named abstract object.",
"[] > with-duplicates",
" true > x",
" false > x"
)
.execute(new FakeMaven.Phi()),
"PhiMojo should not fail on critical errors with 'phiFailsOnCritical' = false"
);
}
@Test
void skipsFailedOnCriticalError(@TempDir final Path temp) {
Assertions.assertDoesNotThrow(
() -> new FakeMaven(temp)
.with("phiFailOnCritical", true)
.with("phiSkipFailed", true)
.withProgram(
"# This is the default 64+ symbols comment in front of named abstract object.",
"[] > with-duplicates",
" true > x",
" false > x"
)
.execute(new FakeMaven.Phi()),
"PhiMojo should not fail on critical errors with 'phiSkipFailed' = true"
);
}
@Test
void doesNotSaveSkippedFile(@TempDir final Path temp) throws IOException {
MatcherAssert.assertThat(
"Skipped file should not be saved after PhiMojo is done",
new FakeMaven(temp)
.with("phiFailOnCritical", true)
.with("phiSkipFailed", true)
.withProgram(
"# This is the default 64+ symbols comment in front of named abstract object.",
"[] > with-duplicates",
" true > x",
" false > x"
)
.execute(new FakeMaven.Phi())
.result(),
Matchers.not(
Matchers.hasKey(
String.format("target/phi/foo/x/main.%s", PhiMojo.EXT)
)
)
);
}
@ParameterizedTest
@ClasspathSource(value = "org/eolang/maven/phi/xmir", glob = "**.xmir")
void convertsXmirsToPhiWithoutErrorsWithOptimizations(

View File

@ -38,6 +38,8 @@ import org.eolang.maven.hash.ChRemote;
import org.eolang.maven.hash.ChText;
import org.eolang.maven.hash.CommitHash;
import org.eolang.maven.hash.CommitHashesMap;
import org.eolang.maven.log.CaptureLogs;
import org.eolang.maven.log.Logs;
import org.eolang.maven.name.ObjectName;
import org.eolang.maven.name.OnVersioned;
import org.eolang.maven.objectionary.Objectionaries;
@ -46,6 +48,7 @@ import org.eolang.maven.objectionary.OyRemote;
import org.eolang.maven.util.HmBase;
import org.hamcrest.MatcherAssert;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.io.TempDir;
@ -294,6 +297,39 @@ final class PullMojoTest {
);
}
@Test
@CaptureLogs
void showsWhereNotFoundWasDiscoveredAt(@TempDir final Path tmp, final Logs out) {
Assertions.assertThrows(
Exception.class,
() -> {
new FakeMaven(tmp)
.withProgram(
"+package com.example\n",
"# This is the default 64+ symbols comment in front of named abstract object.",
"[] > main",
" org.eolang.org > @"
)
.with(
"objectionaries",
new Objectionaries.Fake(
new OyRemote(
new ChRemote("master")
)
)
)
.execute(new FakeMaven.Pull());
},
"Pull mojo should fail, but it does not"
);
Assertions.assertTrue(
out.captured().stream().anyMatch(
line -> line.contains("Failed to pull object discovered at")
),
"Log should contain info where failed to pull object was discovered at, but it does not"
);
}
/**
* Check if the given source file exists in the target directory.
* @param temp Test temporary directory.

View File

@ -21,8 +21,19 @@
# SOFTWARE.
---
tests:
- /program/objects/o[@name='main' and @atom and @abstract]
- /program/objects/o[@name='main' and @atom='Lambda' and @abstract]
- /program/objects/o[@name='outer' and @abstract]
- /program/objects/o[@name='outer' and @abstract]/o[@name='inner' and @atom and @abstract]
phi:
"{⟦main ↦ ⟦λ ⤍ Lambda⟧, outer ↦ ⟦inner ↦ ⟦λ ⤍ Lambda⟧⟧⟧}"
- /program/objects/o[@name='outer' and @abstract]/o[@name='inner' and @atom='Lambda' and @abstract]
phi: |
{
main ↦ ⟦
λ ⤍ Lambda
⟧,
outer ↦ ⟦
inner ↦ ⟦
λ ⤍ Lambda
}

View File

@ -21,29 +21,13 @@
# SOFTWARE.
---
tests:
- /program/objects/o[@base='Q']
- /program/objects/o[@method and @base='.org']
- /program/objects/o[@method and @base='.eolang']
- /program/objects/o[@method and @base='.x']
- /program/objects/o[@method and @base='.x' and @name='xyz']/o[@base='Q']
- /program/objects/o[@method and @base='.x' and @name='xyz']/o[@base='.org' and @method]
- /program/objects/o[@method and @base='.x' and @name='xyz']/o[@base='.eolang' and @method]
- /program/objects/o[@method and @base='.x' and @name='xyz']/o[@base='.y' and @method and @as='attr']
- /program/objects/o[@method and @base='.x' and @name='xyz']/o[@abstract and @as='abs']
- /program/objects/o[@method and @base='.x' and @name='xyz']/o[@abstract and @as='abs']/o[@name='z' and not(@base)]
- /program/objects/o[@method and @base='.x' and @name='xyz']/o[@abstract and @as='abs']/o[@base='Q']
- /program/objects/o[@method and @base='.x' and @name='xyz']/o[@abstract and @as='abs']/o[@base='.org' and @method]
- /program/objects/o[@method and @base='.x' and @name='xyz']/o[@abstract and @as='abs']/o[@base='.eolang' and @method]
- /program/objects/o[@method and @base='.x' and @name='xyz']/o[@abstract and @as='abs']/o[@base='.w' and @method and @name='@']
- /program/objects/o[@method and @base='.x' and @name='xyz']/o[@base='.int' and @method and @as='five']
- /program/objects/o[@method and @base='.x' and @name='xyz']/o[@base='.int' and @method and @as='five']/o[@base='Q']
- /program/objects/o[@method and @base='.x' and @name='xyz']/o[@base='.int' and @method and @as='five']/o[@base='.org' and @method]
- /program/objects/o[@method and @base='.x' and @name='xyz']/o[@base='.int' and @method and @as='five']/o[@base='.eolang' and @method]
- /program/objects/o[@method and @base='.x' and @name='xyz']/o[@base='.int' and @method and @as='five']/o[@base='.bytes' and @method and @as='0']
- /program/objects/o[@method and @base='.x' and @name='xyz']/o[@base='.int' and @method and @as='five']/o[@base='.bytes' and @method and @as='0']/text()
- //o[@base='.x' and @name='xyz']/o[@base='.eolang']/o[@base='.org']/o[@base='Q']
- //o[@base='.x' and @name='xyz']/o[@base='.y' and @as='attr']/o[@base='.eolang']/o[@base='.org']/o[@base='Q']
- //o[@base='.x' and @name='xyz']/o[@abstract and @as='abs']/o[@name='z' and not(@base)]
- //o[@base='.x' and @name='xyz']/o[@abstract and @as='abs']/o[@base='.w' and @name='@']/o[@base='.eolang']/o[@base='.org']/o[@base='Q']
- //o[@base='.x' and @name='xyz']/o[@base='.int' and @as='five']/o[@base='.eolang']/o[@base='.org']/o[@base='Q']
- //o[@base='.x' and @name='xyz']/o[@base='.int' and @as='five']/o[@as='0' and @base='.bytes']/o[@base='.eolang']/o[@base='.org']/o[@base='Q']
- //o[@base='.x' and @name='xyz']/o[@base='.int' and @as='five']/o[@as='0' and @base='.bytes']/o[@base='org.eolang.bytes' and @data and text()!='']
phi: |-
{

View File

@ -0,0 +1,38 @@
# The MIT License (MIT)
#
# Copyright (c) 2016-2024 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.
---
tests:
- //o[not(@abstract) and @name='x' and @base='org.eolang.bytes' and @data and text()='01']
phi: |
{
org ↦ ⟦
eolang ↦ ⟦
x ↦ ⟦
Δ ⤍ 01-
⟧,
λ ⤍ Package
⟧,
λ ⤍ Package
}

View File

@ -21,9 +21,6 @@
# SOFTWARE.
---
tests:
- /program/objects/o[@base='Q']
- /program/objects/o[@base='.org' and @method]
- /program/objects/o[@base='.eolang' and @method]
- /program/objects/o[@base='.bytes' and @method and @name='empty']
- /program/objects/o[@base='.bytes' and @method and @name='empty' and o[@base='org.eolang.bytes' and not(text())]]
- /program/objects/o[@base='.bytes' and @name='empty']/o[@base='.eolang']/o[@base='.org']/o[@base='Q']
- /program/objects/o[@base='.bytes' and @name='empty']/o[@base='org.eolang.bytes' and @data]
phi: "{⟦empty ↦ Φ.org.eolang.bytes(Δ ⤍ --)⟧}"

View File

@ -0,0 +1,47 @@
# The MIT License (MIT)
#
# Copyright (c) 2016-2024 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.
---
tests:
- //o[@base='org.eolang.io.stdout' and not(@abstract) and @name='x']
- //o[@base='org.eolang.io.stdout' and not(@abstract) and @name='x']/o[@as='text' and @base='.bytes']
- //o[@base='org.eolang.io.stdout' and not(@abstract) and @name='x']/o[@as='size' and @base='.int']
phi: |
{
org ↦ ⟦
eolang ↦ ⟦
io ↦ ⟦
x ↦ ⟦
text ↦ Φ.org.eolang.bytes (Δ ⤍ 48-65-6C-6C-6F-20-77-6F-72-6C-64-0A),
size ↦ Φ.org.eolang.int(
as-bytes ↦ Φ.org.eolang.bytes (Δ ⤍ 48-65-6C-6C-6F-20-77-6F-72-6C-64-0A)
),
λ ⤍ Lorg_eolang_io_stdout
⟧,
λ ⤍ Package
⟧,
λ ⤍ Package
⟧,
λ ⤍ Package
}

View File

@ -21,8 +21,6 @@
# SOFTWARE.
---
tests:
- /program/objects/o[@base='Q']
- /program/objects/o[@base='.org' and @method]
- /program/objects/o[@base='.eolang' and @method]
- /program/objects/o[@base='.bytes' and @method and @name='bts' and o[@base='org.eolang.bytes' and text()='A2']]
- /program/objects/o[@base='.bytes' and @name='bts']/o[@base='.eolang']/o[@base='.org']/o[@base='Q']
- /program/objects/o[@base='.bytes' and @name='bts']/o[@base='org.eolang.bytes' and text()='A2']
phi: "{⟦bts ↦ Φ.org.eolang.bytes(Δ ⤍ A2-)⟧}"

View File

@ -22,9 +22,5 @@
---
tests:
- /program/metas/meta[head[text()='package'] and tail[text()='foo.bar.baz'] and part[text()='foo.bar.baz']]
- /program/objects/o[@abstract and @name='main']
- /program/objects/o[@abstract and @name='main']/o[@base='Q']
- /program/objects/o[@abstract and @name='main']/o[@base='.org' and @method]
- /program/objects/o[@abstract and @name='main']/o[@base='.eolang' and @method]
- /program/objects/o[@abstract and @name='main']/o[@base='.stdout' and @method and @name='@']
- //o[@abstract and @name='main']/o[@base='.stdout']/o[@base='.eolang']/o[@base='.org']/o[@base='Q']
phi: "{⟦foo ↦ ⟦bar ↦ ⟦baz ↦ ⟦main ↦ ⟦φ ↦ Φ.org.eolang.stdout⟧, λ ⤍ Package⟧, λ ⤍ Package⟧, λ ⤍ Package⟧⟧}"

View File

@ -22,11 +22,9 @@
---
tests:
- /program/objects/o[@name='main']
- /program/objects/o[@name='main']/o[@base='$']/following-sibling::o[@base='.^' and @method]/following-sibling::o[@base='.x' and @method and @name='x']
- /program/objects/o[@name='main']/o[@base='$']/following-sibling::o[@base='.a' and @method and @name='a']
- /program/objects/o[@name='main']/o[@base='$']/following-sibling::o[@base='.@' and @method]/following-sibling::o[@base='.@' and @method and @name='phi']
- /program/objects/o[@abstract and @name='main']/o[@base='.x' and @name='x']/o[@base='.^']/o[@base='$']
- /program/objects/o[@abstract and @name='main']/o[@base='.a' and @name='a']/o[@base='.^']/o[@base='$']
- /program/objects/o[@abstract and @name='main']/o[@base='.@' and @name='phi']/o[@base='.@']/o[@base='$']
eo: |
[] > main
^.x > x

View File

@ -0,0 +1,36 @@
# The MIT License (MIT)
#
# Copyright (c) 2016-2024 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.
---
tests:
- //o[@base='org.eolang.error' and @name='x']/o[@base='org.eolang.string']/o[@base='org.eolang.bytes' and @data and text()!='']
phi: |
{
org ↦ ⟦
eolang ↦ ⟦
x ↦ ⊥,
λ ⤍ Package
⟧,
λ ⤍ Package
}

View File

@ -21,9 +21,8 @@
# SOFTWARE.
---
tests:
- //o[@name='test' and count(o)=2]
- //o[@name='test']/o[position()=1 and @abstract and not(@name)]
- //o[@name='test']/o[last() and @base='.plus' and @method]
- //o[@name='test' and @abstract]/o[@base='.plus' and @name='s']/o[position()=1 and @abstract and not(@name)]
- //o[@name='test' and @abstract]/o[@base='.plus' and @name='s']/o[position()>1 and @as='0' and @base='.int']/o[@base='.eolang']/o[@base='.org']/o[@base='Q']
phi: |-
{

View File

@ -21,12 +21,6 @@
# SOFTWARE.
---
tests:
- /program/objects/o[@base='Q']
- /program/objects/o[@base='.org' and @method]
- /program/objects/o[@base='.eolang' and @method]
- /program/objects/o[@base='.int' and @method and @name='five']
- /program/objects/o[@base='.int' and @method and @name='five']/o[@base='Q']
- /program/objects/o[@base='.int' and @method and @name='five']/o[@base='.org' and @method]
- /program/objects/o[@base='.int' and @method and @name='five']/o[@base='.eolang' and @method]
- /program/objects/o[@base='.int' and @method and @name='five']/o[@base='.bytes' and @method and @as='0' and o[@base='org.eolang.bytes' and text()='00 00 00 00 00 00 00 05']]
- //o[@name='five' and @base='.int']/o[@base='.eolang']
- //o[@name='five' and @base='.int']/o[@base='.bytes' and @as='0']
phi: "{⟦five ↦ Φ.org.eolang.int(α0 ↦ Φ.org.eolang.bytes(Δ ⤍ 00-00-00-00-00-00-00-05))⟧}"

View File

@ -316,7 +316,7 @@ public final class XePhiListener implements PhiListener, Iterable<Directive> {
@Override
public void enterLambdaBinding(final PhiParser.LambdaBindingContext ctx) {
if (!XePhiListener.LAMBDA_PACKAGE.equals(ctx.FUNCTION().getText())) {
this.objects().prop("atom");
this.objects().prop("atom", ctx.FUNCTION().getText());
}
}
@ -363,7 +363,17 @@ public final class XePhiListener implements PhiListener, Iterable<Directive> {
@Override
public void enterTermination(final PhiParser.TerminationContext ctx) {
// Nothing here
this.objects()
.prop("base", "org.eolang.error")
.start()
.prop("base", "org.eolang.string")
.start()
.prop("base", "org.eolang.bytes")
.prop("data", "bytes")
.data("55 6E 6B 6E 6F 77 6E 20 65 72 72 6F 72")
.leave()
.leave()
.leave();
}
@Override

View File

@ -28,4 +28,21 @@
# The object, when being dataized, dataizes all provided
# "steps" (except the last one) and returns the last one.
[steps] > seq /?
[steps] > seq
if. > @
steps.length.eq 0
true
loop 0
steps.length.minus 1 > max-len!
[index] > loop
if. > @
and.
index.lt ^.max-len
or.
(dataized (steps.at index)).as-bool
true
^.loop
index.plus 1
steps.at index

View File

@ -1,91 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2016-2024 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.
*/
/*
* @checkstyle PackageNameCheck (4 lines)
*/
package EOorg.EOeolang;
import org.eolang.AtVoid;
import org.eolang.Atom;
import org.eolang.Data;
import org.eolang.Dataized;
import org.eolang.PhDefault;
import org.eolang.PhMethod;
import org.eolang.Phi;
import org.eolang.Versionized;
import org.eolang.XmirObject;
/**
* SEQ.
* @since 1.0
* @checkstyle TypeNameCheck (5 lines)
*/
@Versionized
@XmirObject(oname = "seq")
public final class EOseq extends PhDefault implements Atom {
/**
* Ctor.
*/
public EOseq() {
this.add("steps", new AtVoid("steps"));
}
@Override
public Phi lambda() {
final Phi steps = this.take("steps");
final Phi[] items = EOseq.eoTupleAsArray(steps);
for (int ind = 0; ind < items.length - 1; ++ind) {
new Dataized(items[ind]).take();
}
final Phi ret;
if (items.length > 0) {
ret = new PhMethod(steps, "tail");
} else {
ret = new Data.ToPhi(false);
}
return ret;
}
/**
* Converts eo tuple to java array.
* @param args Eo tuple.
* @return Java array.
*/
private static Phi[] eoTupleAsArray(final Phi args) {
final int length = Math.toIntExact(
new Dataized(
args.take("length")
).take(Long.class)
);
final Phi[] res = new Phi[length];
Phi external = args;
for (int ind = length - 1; ind >= 0; --ind) {
res[ind] = new PhMethod(external, "tail");
external = external.take("head");
}
return res;
}
}

View File

@ -174,3 +174,21 @@
m.put (m.as-int.plus 1)
m
1
# Test.
[] > seq-calculates-and-returns
eq. > @
1
seq
*
0
1
# Test.
[] > seq-calculates-and-returns-object
eq. > @
"Hello!"
seq
*
0
"Hello!"

View File

@ -1,87 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2016-2024 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.
*/
/*
* @checkstyle PackageNameCheck (10 lines)
*/
package EOorg.EOeolang;
import org.eolang.AtCompositeTest;
import org.eolang.Data;
import org.eolang.Dataized;
import org.eolang.PhWith;
import org.eolang.Phi;
import org.hamcrest.MatcherAssert;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Test;
/**
* Test case for {@link EOseq}.
*
* @since 0.16
*/
public final class EOseqTest {
@Test
public void calculatesAndReturns() {
MatcherAssert.assertThat(
AtCompositeTest.TO_ADD_MESSAGE,
new Dataized(
new PhWith(
new EOseq(),
0,
new PhWith(
new PhWith(
new EOtuple$EOempty().take("with").copy(),
0, new Data.ToPhi(0L)
).take("with").copy(),
0, new Data.ToPhi(1L)
)
)
).take(Long.class),
Matchers.equalTo(1L)
);
}
@Test
public void calculatesAndReturnsObject() {
MatcherAssert.assertThat(
AtCompositeTest.TO_ADD_MESSAGE,
new Dataized(
new PhWith(
new EOseq(),
0,
new PhWith(
new PhWith(
new EOtuple$EOempty().take("with").copy(),
0, new Data.ToPhi(0L)
).take("with").copy(),
0, new Data.ToPhi("Hello!")
)
)
).take(String.class),
Matchers.startsWith("Hello")
);
}
}

View File

@ -300,7 +300,7 @@ SOFTWARE.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.4.1</version>
<version>3.5.0</version>
<executions>
<execution>
<id>enforce-java</id>