diff --git a/pom.xml b/pom.xml
index 0e0185fd..26d10dda 100644
--- a/pom.xml
+++ b/pom.xml
@@ -337,7 +337,7 @@ SOFTWARE.
CLASSMISSEDCOUNT
- 7
+ 8
diff --git a/src/main/java/org/eolang/opeo/SelectiveDecompiler.java b/src/main/java/org/eolang/opeo/SelectiveDecompiler.java
index 8f3d1400..7f9dbebc 100644
--- a/src/main/java/org/eolang/opeo/SelectiveDecompiler.java
+++ b/src/main/java/org/eolang/opeo/SelectiveDecompiler.java
@@ -31,7 +31,7 @@
import java.util.stream.Collectors;
import org.eolang.opeo.decompilation.Decompiler;
import org.eolang.opeo.decompilation.WithoutAliases;
-import org.eolang.opeo.decompilation.handlers.RouterHandler;
+import org.eolang.opeo.decompilation.agents.AllAgents;
import org.eolang.opeo.jeo.JeoDecompiler;
import org.eolang.opeo.storage.FileStorage;
import org.eolang.opeo.storage.Storage;
@@ -41,7 +41,7 @@
* Selective decompiler.
* Decompiler that decompiles ONLY fully understandable methods.
* These methods contain only instructions that are
- * supported by {@link org.eolang.opeo.decompilation.handlers.RouterHandler}.
+ * supported by {@link AllAgents}.
*
* @since 0.1
*/
@@ -69,7 +69,7 @@ public final class SelectiveDecompiler implements Decompiler {
* @param modified Folder where to save the modified XMIRs.
*/
public SelectiveDecompiler(final Path input, final Path output, final Path modified) {
- this(input, output, modified, new RouterHandler(false).supportedOpcodes());
+ this(input, output, modified, new AllAgents(false).supportedOpcodes());
}
/**
@@ -97,7 +97,7 @@ public SelectiveDecompiler(
public SelectiveDecompiler(
final Storage storage, final Storage modified
) {
- this(storage, modified, new RouterHandler(false).supportedOpcodes());
+ this(storage, modified, new AllAgents(false).supportedOpcodes());
}
/**
diff --git a/src/main/java/org/eolang/opeo/ast/Add.java b/src/main/java/org/eolang/opeo/ast/Addition.java
similarity index 94%
rename from src/main/java/org/eolang/opeo/ast/Add.java
rename to src/main/java/org/eolang/opeo/ast/Addition.java
index 906c97c1..8b1783d6 100644
--- a/src/main/java/org/eolang/opeo/ast/Add.java
+++ b/src/main/java/org/eolang/opeo/ast/Addition.java
@@ -41,7 +41,7 @@
*/
@EqualsAndHashCode
@ToString
-public final class Add implements AstNode, Typed {
+public final class Addition implements AstNode, Typed {
/**
* Left operand.
@@ -58,7 +58,7 @@ public final class Add implements AstNode, Typed {
* @param node XML node
* @param parser Parser
*/
- public Add(final XmlNode node, final Function parser) {
+ public Addition(final XmlNode node, final Function parser) {
this(
parser.apply(node.children().collect(Collectors.toList()).get(0)),
parser.apply(node.children().collect(Collectors.toList()).get(1))
@@ -70,7 +70,7 @@ public Add(final XmlNode node, final Function parser) {
* @param left Left operand
* @param right Right operand
*/
- public Add(final AstNode left, final AstNode right) {
+ public Addition(final AstNode left, final AstNode right) {
this.left = left;
this.right = right;
}
diff --git a/src/main/java/org/eolang/opeo/ast/Labeled.java b/src/main/java/org/eolang/opeo/ast/Labeled.java
index 7e039e66..cb7bc593 100644
--- a/src/main/java/org/eolang/opeo/ast/Labeled.java
+++ b/src/main/java/org/eolang/opeo/ast/Labeled.java
@@ -30,6 +30,7 @@
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eolang.jeo.representation.xmir.XmlNode;
+import org.eolang.opeo.decompilation.agents.InvokespecialAgent;
import org.objectweb.asm.Type;
import org.xembly.Directive;
import org.xembly.Directives;
@@ -39,7 +40,7 @@
* This class needed to avoid considering labels as separate nodes.
* Maybe it's wrong to do so, but it's easier to implement this way, at least for now.
* Pay attention, that {@link Labeled} class violates class hierarchy.
- * It is the most visible within {@link org.eolang.opeo.decompilation.handlers.InvokespecialHandler}
+ * It is the most visible within {@link InvokespecialAgent}
* implementation.
* @since 0.2
*/
diff --git a/src/main/java/org/eolang/opeo/ast/Opcode.java b/src/main/java/org/eolang/opeo/ast/Opcode.java
index 334fec66..6609eb6c 100644
--- a/src/main/java/org/eolang/opeo/ast/Opcode.java
+++ b/src/main/java/org/eolang/opeo/ast/Opcode.java
@@ -35,6 +35,7 @@
import org.eolang.jeo.representation.xmir.XmlInstruction;
import org.eolang.jeo.representation.xmir.XmlNode;
import org.eolang.jeo.representation.xmir.XmlOperand;
+import org.eolang.opeo.Instruction;
import org.xembly.Directive;
/**
@@ -119,6 +120,10 @@ public Opcode(final XmlInstruction instruction) {
);
}
+ public Opcode(final Instruction instruction) {
+ this(instruction.opcode(), instruction.operands());
+ }
+
/**
* Constructor.
* @param bytecode Bytecode
@@ -141,6 +146,40 @@ public List opcodes() {
return Arrays.asList(this);
}
+ /**
+ * Opcode number.
+ * @return Opcode number.
+ */
+ public int opcode() {
+ return this.bytecode;
+ }
+
+ /**
+ * Opcode operands.
+ * @return Opcode operands.
+ */
+ public List
* @since 0.2
*/
-public final class InvokeinterfaceHandler implements InstructionHandler {
+public final class InvokeinterfaceAgent implements DecompilationAgent {
@Override
public void handle(final DecompilerState state) {
- final String owner = (String) state.operand(0);
- final String method = (String) state.operand(1);
- final String descriptor = (String) state.operand(2);
- final boolean interfaced = (Boolean) state.operand(3);
- final List args = state.stack().pop(
- Type.getArgumentCount(descriptor)
- );
- Collections.reverse(args);
- final AstNode source = state.stack().pop();
- state.stack().push(
- new InterfaceInvocation(
- source,
- new Attributes()
- .name(method)
- .descriptor(descriptor)
- .interfaced(interfaced)
- .owner(owner),
- args
- )
- );
+ if (state.instruction().opcode() == Opcodes.INVOKEINTERFACE) {
+ final String owner = (String) state.operand(0);
+ final String method = (String) state.operand(1);
+ final String descriptor = (String) state.operand(2);
+ final boolean interfaced = (Boolean) state.operand(3);
+ final List args = state.stack().pop(
+ Type.getArgumentCount(descriptor)
+ );
+ Collections.reverse(args);
+ final AstNode source = state.stack().pop();
+ state.stack().push(
+ new InterfaceInvocation(
+ source,
+ new Attributes()
+ .name(method)
+ .descriptor(descriptor)
+ .interfaced(interfaced)
+ .owner(owner),
+ args
+ )
+ );
+ state.popInstruction();
+ }
}
}
diff --git a/src/main/java/org/eolang/opeo/decompilation/handlers/InvokespecialHandler.java b/src/main/java/org/eolang/opeo/decompilation/agents/InvokespecialAgent.java
similarity index 72%
rename from src/main/java/org/eolang/opeo/decompilation/handlers/InvokespecialHandler.java
rename to src/main/java/org/eolang/opeo/decompilation/agents/InvokespecialAgent.java
index d85e423e..71be3aee 100644
--- a/src/main/java/org/eolang/opeo/decompilation/handlers/InvokespecialHandler.java
+++ b/src/main/java/org/eolang/opeo/decompilation/agents/InvokespecialAgent.java
@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-package org.eolang.opeo.decompilation.handlers;
+package org.eolang.opeo.decompilation.agents;
import java.util.Collections;
import java.util.List;
@@ -33,8 +33,9 @@
import org.eolang.opeo.ast.NewAddress;
import org.eolang.opeo.ast.Super;
import org.eolang.opeo.ast.This;
+import org.eolang.opeo.decompilation.DecompilationAgent;
import org.eolang.opeo.decompilation.DecompilerState;
-import org.eolang.opeo.decompilation.InstructionHandler;
+import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
/**
@@ -42,14 +43,14 @@
*
* @since 0.1
* @todo #229:90min Is Labeled Class an Abstraction Failure?
- * As you can see in {@link InvokespecialHandler} we use many 'instanceof' checks.
+ * As you can see in {@link InvokespecialAgent} we use many 'instanceof' checks.
* This is a clear sign that the class hierarchy is not well designed.
* The original problem lies in the {@link Labeled} class.
* We need to find more elegant solutions to handle labels in AST.
* @checkstyle NoJavadocForOverriddenMethodsCheck (500 lines)
* @checkstyle MultilineJavadocTagsCheck (500 lines)
*/
-public final class InvokespecialHandler implements InstructionHandler {
+public final class InvokespecialAgent implements DecompilationAgent {
/**
* Handle invokespecial instruction.
@@ -75,31 +76,34 @@ public final class InvokespecialHandler implements InstructionHandler {
@Override
@SuppressWarnings("PMD.UnusedLocalVariable")
public void handle(final DecompilerState state) {
- final String type = (String) state.operand(0);
- final String name = (String) state.operand(1);
- final String descriptor = (String) state.operand(2);
- final boolean interfaced = (boolean) state.operand(3);
- final List args = state.stack().pop(
- Type.getArgumentCount(descriptor)
- );
- Collections.reverse(args);
- final AstNode target = state.stack().pop();
- if (InvokespecialHandler.isThis(target)) {
- state.stack().push(
- new Super(target, args, descriptor, type, name)
- );
- } else if (this.isNewAddress(target)) {
- state.stack().push(
- new Constructor(
- target,
- new Attributes().descriptor(descriptor).interfaced(interfaced),
- args
- )
- );
- } else {
- state.stack().push(
- new Super(target, args, descriptor, type, name)
+ if (state.instruction().opcode() == Opcodes.INVOKESPECIAL) {
+ final String type = (String) state.operand(0);
+ final String name = (String) state.operand(1);
+ final String descriptor = (String) state.operand(2);
+ final boolean interfaced = (boolean) state.operand(3);
+ final List args = state.stack().pop(
+ Type.getArgumentCount(descriptor)
);
+ Collections.reverse(args);
+ final AstNode target = state.stack().pop();
+ if (InvokespecialAgent.isThis(target)) {
+ state.stack().push(
+ new Super(target, args, descriptor, type, name)
+ );
+ } else if (this.isNewAddress(target)) {
+ state.stack().push(
+ new Constructor(
+ target,
+ new Attributes().descriptor(descriptor).interfaced(interfaced),
+ args
+ )
+ );
+ } else {
+ state.stack().push(
+ new Super(target, args, descriptor, type, name)
+ );
+ }
+ state.popInstruction();
}
}
@@ -135,9 +139,9 @@ private static boolean isThis(final AstNode candidate) {
if (candidate instanceof This) {
result = true;
} else if (candidate instanceof Labeled) {
- result = InvokespecialHandler.isThis(((Labeled) candidate).origin());
+ result = InvokespecialAgent.isThis(((Labeled) candidate).origin());
} else if (candidate instanceof Duplicate) {
- result = InvokespecialHandler.isThis(((Duplicate) candidate).origin());
+ result = InvokespecialAgent.isThis(((Duplicate) candidate).origin());
} else {
result = false;
}
diff --git a/src/main/java/org/eolang/opeo/decompilation/handlers/InvokestaticHander.java b/src/main/java/org/eolang/opeo/decompilation/agents/InvokestaticAgent.java
similarity index 59%
rename from src/main/java/org/eolang/opeo/decompilation/handlers/InvokestaticHander.java
rename to src/main/java/org/eolang/opeo/decompilation/agents/InvokestaticAgent.java
index 00a8ced5..63230793 100644
--- a/src/main/java/org/eolang/opeo/decompilation/handlers/InvokestaticHander.java
+++ b/src/main/java/org/eolang/opeo/decompilation/agents/InvokestaticAgent.java
@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-package org.eolang.opeo.decompilation.handlers;
+package org.eolang.opeo.decompilation.agents;
import java.util.Collections;
import java.util.List;
@@ -29,34 +29,38 @@
import org.eolang.opeo.ast.Attributes;
import org.eolang.opeo.ast.Owner;
import org.eolang.opeo.ast.StaticInvocation;
+import org.eolang.opeo.decompilation.DecompilationAgent;
import org.eolang.opeo.decompilation.DecompilerState;
-import org.eolang.opeo.decompilation.InstructionHandler;
+import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
/**
* Invokestatic instruction handler.
* @since 0.1
*/
-public final class InvokestaticHander implements InstructionHandler {
+public final class InvokestaticAgent implements DecompilationAgent {
@Override
public void handle(final DecompilerState state) {
- final String owner = (String) state.operand(0);
- final String method = (String) state.operand(1);
- final String descriptor = (String) state.operand(2);
- final boolean interfaced = (boolean) state.operand(3);
- final List args = state.stack().pop(Type.getArgumentCount(descriptor));
- Collections.reverse(args);
- state.stack().push(
- new StaticInvocation(
- new Attributes()
- .name(method)
- .descriptor(descriptor)
- .owner(owner)
- .interfaced(interfaced),
- new Owner(owner),
- args
- )
- );
+ if (state.instruction().opcode() == Opcodes.INVOKESTATIC) {
+ final String owner = (String) state.operand(0);
+ final String method = (String) state.operand(1);
+ final String descriptor = (String) state.operand(2);
+ final boolean interfaced = (boolean) state.operand(3);
+ final List args = state.stack().pop(Type.getArgumentCount(descriptor));
+ Collections.reverse(args);
+ state.stack().push(
+ new StaticInvocation(
+ new Attributes()
+ .name(method)
+ .descriptor(descriptor)
+ .owner(owner)
+ .interfaced(interfaced),
+ new Owner(owner),
+ args
+ )
+ );
+ state.popInstruction();
+ }
}
}
diff --git a/src/main/java/org/eolang/opeo/decompilation/handlers/InvokevirtualHandler.java b/src/main/java/org/eolang/opeo/decompilation/agents/InvokevirtualAgent.java
similarity index 62%
rename from src/main/java/org/eolang/opeo/decompilation/handlers/InvokevirtualHandler.java
rename to src/main/java/org/eolang/opeo/decompilation/agents/InvokevirtualAgent.java
index 31fa25fa..f1d8758d 100644
--- a/src/main/java/org/eolang/opeo/decompilation/handlers/InvokevirtualHandler.java
+++ b/src/main/java/org/eolang/opeo/decompilation/agents/InvokevirtualAgent.java
@@ -21,15 +21,16 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-package org.eolang.opeo.decompilation.handlers;
+package org.eolang.opeo.decompilation.agents;
import java.util.Collections;
import java.util.List;
import org.eolang.opeo.ast.AstNode;
import org.eolang.opeo.ast.Attributes;
import org.eolang.opeo.ast.Invocation;
+import org.eolang.opeo.decompilation.DecompilationAgent;
import org.eolang.opeo.decompilation.DecompilerState;
-import org.eolang.opeo.decompilation.InstructionHandler;
+import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
/**
@@ -47,29 +48,32 @@
*
* @since 0.1
*/
-public final class InvokevirtualHandler implements InstructionHandler {
+public final class InvokevirtualAgent implements DecompilationAgent {
@Override
public void handle(final DecompilerState state) {
- final String owner = (String) state.operand(0);
- final String method = (String) state.operand(1);
- final String descriptor = (String) state.operand(2);
- final boolean interfaced = (Boolean) state.operand(3);
- final List args = state.stack().pop(
- Type.getArgumentCount(descriptor)
- );
- Collections.reverse(args);
- final AstNode source = state.stack().pop();
- state.stack().push(
- new Invocation(
- source,
- new Attributes()
- .name(method)
- .descriptor(descriptor)
- .owner(owner)
- .interfaced(interfaced),
- args
- )
- );
+ if (state.instruction().opcode() == Opcodes.INVOKEVIRTUAL) {
+ final String owner = (String) state.operand(0);
+ final String method = (String) state.operand(1);
+ final String descriptor = (String) state.operand(2);
+ final boolean interfaced = (Boolean) state.operand(3);
+ final List args = state.stack().pop(
+ Type.getArgumentCount(descriptor)
+ );
+ Collections.reverse(args);
+ final AstNode source = state.stack().pop();
+ state.stack().push(
+ new Invocation(
+ source,
+ new Attributes()
+ .name(method)
+ .descriptor(descriptor)
+ .owner(owner)
+ .interfaced(interfaced),
+ args
+ )
+ );
+ state.popInstruction();
+ }
}
}
diff --git a/src/main/java/org/eolang/opeo/decompilation/handlers/LabelHandler.java b/src/main/java/org/eolang/opeo/decompilation/agents/LabelAgent.java
similarity index 72%
rename from src/main/java/org/eolang/opeo/decompilation/handlers/LabelHandler.java
rename to src/main/java/org/eolang/opeo/decompilation/agents/LabelAgent.java
index 5be17b5a..f38ce3a8 100644
--- a/src/main/java/org/eolang/opeo/decompilation/handlers/LabelHandler.java
+++ b/src/main/java/org/eolang/opeo/decompilation/agents/LabelAgent.java
@@ -21,25 +21,29 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-package org.eolang.opeo.decompilation.handlers;
+package org.eolang.opeo.decompilation.agents;
+import org.eolang.opeo.LabelInstruction;
import org.eolang.opeo.ast.AstNode;
import org.eolang.opeo.ast.Label;
import org.eolang.opeo.ast.Labeled;
+import org.eolang.opeo.decompilation.DecompilationAgent;
import org.eolang.opeo.decompilation.DecompilerState;
-import org.eolang.opeo.decompilation.InstructionHandler;
/**
* Label instruction handler.
* @since 0.1
*/
-public final class LabelHandler implements InstructionHandler {
+public final class LabelAgent implements DecompilationAgent {
@Override
public void handle(final DecompilerState state) {
- final Labeled node = new Labeled(
- state.stack().first().orElse(new AstNode.Empty()),
- new Label(String.class.cast(state.operand(0)))
- );
- state.stack().push(node);
+ if (state.instruction().opcode() == LabelInstruction.LABEL_OPCODE) {
+ final Labeled node = new Labeled(
+ state.stack().first().orElse(new AstNode.Empty()),
+ new Label(String.class.cast(state.operand(0)))
+ );
+ state.stack().push(node);
+ state.popInstruction();
+ }
}
}
diff --git a/src/main/java/org/eolang/opeo/decompilation/handlers/LdcHandler.java b/src/main/java/org/eolang/opeo/decompilation/agents/LdcAgent.java
similarity index 77%
rename from src/main/java/org/eolang/opeo/decompilation/handlers/LdcHandler.java
rename to src/main/java/org/eolang/opeo/decompilation/agents/LdcAgent.java
index 479e2a06..dbc5fb42 100644
--- a/src/main/java/org/eolang/opeo/decompilation/handlers/LdcHandler.java
+++ b/src/main/java/org/eolang/opeo/decompilation/agents/LdcAgent.java
@@ -21,22 +21,26 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-package org.eolang.opeo.decompilation.handlers;
+package org.eolang.opeo.decompilation.agents;
import org.eolang.opeo.ast.Constant;
+import org.eolang.opeo.decompilation.DecompilationAgent;
import org.eolang.opeo.decompilation.DecompilerState;
-import org.eolang.opeo.decompilation.InstructionHandler;
+import org.objectweb.asm.Opcodes;
/**
* Ldc instruction handler.
* @since 0.1
*/
-public final class LdcHandler implements InstructionHandler {
+public final class LdcAgent implements DecompilationAgent {
@Override
public void handle(final DecompilerState state) {
- final Object operand = state.operand(0);
- state.stack().push(new Constant(operand));
+ if (state.instruction().opcode() == Opcodes.LDC) {
+ final Object operand = state.operand(0);
+ state.stack().push(new Constant(operand));
+ state.popInstruction();
+ }
}
}
diff --git a/src/main/java/org/eolang/opeo/decompilation/agents/LoadAgent.java b/src/main/java/org/eolang/opeo/decompilation/agents/LoadAgent.java
new file mode 100644
index 00000000..43a4c376
--- /dev/null
+++ b/src/main/java/org/eolang/opeo/decompilation/agents/LoadAgent.java
@@ -0,0 +1,99 @@
+/*
+ * 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.opeo.decompilation.agents;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import org.eolang.opeo.decompilation.DecompilationAgent;
+import org.eolang.opeo.decompilation.DecompilerState;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+/**
+ * Instruction handler.
+ * This handler might understand the following instructions:
+ * aload: 1: index | → objectref | load a reference onto the stack from a local variable #index
+ * aload_0: → objectref | load a reference onto the stack from local variable 0
+ * ...
+ * @since 0.1
+ */
+public final class LoadAgent implements DecompilationAgent {
+
+ /**
+ * Supported opcodes.
+ */
+ private static final Set SUPPORTED = new HashSet<>(
+ Arrays.asList(
+ Opcodes.ILOAD,
+ Opcodes.LLOAD,
+ Opcodes.FLOAD,
+ Opcodes.DLOAD,
+ Opcodes.ALOAD
+ )
+ );
+
+ @Override
+ public void handle(final DecompilerState state) {
+ final int opcode = state.instruction().opcode();
+ if (LoadAgent.SUPPORTED.contains(opcode)) {
+ final Integer index = (Integer) state.operand(0);
+ state.stack().push(
+ state.variable(index, LoadAgent.type(opcode))
+ );
+ state.popInstruction();
+ }
+ }
+
+ /**
+ * Infer type from opcode.
+ * @param opcode Opcode
+ * @return Type
+ */
+ private static Type type(final int opcode) {
+ final Type result;
+ switch (opcode) {
+ case Opcodes.ILOAD:
+ result = Type.INT_TYPE;
+ break;
+ case Opcodes.LLOAD:
+ result = Type.LONG_TYPE;
+ break;
+ case Opcodes.FLOAD:
+ result = Type.FLOAT_TYPE;
+ break;
+ case Opcodes.DLOAD:
+ result = Type.DOUBLE_TYPE;
+ break;
+ case Opcodes.ALOAD:
+ result = Type.getType(Object.class);
+ break;
+ default:
+ throw new IllegalArgumentException(
+ String.format("Unsupported opcode: %d", opcode)
+ );
+ }
+ return result;
+ }
+}
diff --git a/src/main/java/org/eolang/opeo/decompilation/handlers/MulHandler.java b/src/main/java/org/eolang/opeo/decompilation/agents/MulAgent.java
similarity index 68%
rename from src/main/java/org/eolang/opeo/decompilation/handlers/MulHandler.java
rename to src/main/java/org/eolang/opeo/decompilation/agents/MulAgent.java
index 280bb6f4..c1814c4a 100644
--- a/src/main/java/org/eolang/opeo/decompilation/handlers/MulHandler.java
+++ b/src/main/java/org/eolang/opeo/decompilation/agents/MulAgent.java
@@ -21,48 +21,42 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-package org.eolang.opeo.decompilation.handlers;
+package org.eolang.opeo.decompilation.agents;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
import org.eolang.opeo.ast.AstNode;
import org.eolang.opeo.ast.Multiplication;
-import org.eolang.opeo.ast.Opcode;
+import org.eolang.opeo.decompilation.DecompilationAgent;
import org.eolang.opeo.decompilation.DecompilerState;
-import org.eolang.opeo.decompilation.InstructionHandler;
import org.objectweb.asm.Opcodes;
/**
* Mul instruction handler.
* @since 0.1
*/
-public final class MulHandler implements InstructionHandler {
+public final class MulAgent implements DecompilationAgent {
/**
- * Do we put numbers to opcodes?
+ * Supported opcodes.
*/
- private final boolean counting;
-
- /**
- * Constructor.
- * @param counting Do we put numbers to opcodes?
- */
- MulHandler(final boolean counting) {
- this.counting = counting;
- }
+ private static final Set SUPPORTED = new HashSet<>(
+ Arrays.asList(
+ Opcodes.IMUL,
+ Opcodes.LMUL,
+ Opcodes.FMUL,
+ Opcodes.DMUL
+ )
+ );
@Override
public void handle(final DecompilerState state) {
- if (state.instruction().opcode() == Opcodes.IMUL) {
+ if (MulAgent.SUPPORTED.contains(state.instruction().opcode())) {
final AstNode right = state.stack().pop();
final AstNode left = state.stack().pop();
state.stack().push(new Multiplication(left, right));
- } else {
- state.stack().push(
- new Opcode(
- state.instruction().opcode(),
- state.instruction().operands(),
- this.counting
- )
- );
+ state.popInstruction();
}
}
diff --git a/src/main/java/org/eolang/opeo/decompilation/handlers/NewHandler.java b/src/main/java/org/eolang/opeo/decompilation/agents/NewAgent.java
similarity index 68%
rename from src/main/java/org/eolang/opeo/decompilation/handlers/NewHandler.java
rename to src/main/java/org/eolang/opeo/decompilation/agents/NewAgent.java
index 9cf78c66..4c8242ad 100644
--- a/src/main/java/org/eolang/opeo/decompilation/handlers/NewHandler.java
+++ b/src/main/java/org/eolang/opeo/decompilation/agents/NewAgent.java
@@ -21,21 +21,37 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-package org.eolang.opeo.decompilation.handlers;
+package org.eolang.opeo.decompilation.agents;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
import org.eolang.opeo.ast.NewAddress;
+import org.eolang.opeo.decompilation.DecompilationAgent;
import org.eolang.opeo.decompilation.DecompilerState;
-import org.eolang.opeo.decompilation.InstructionHandler;
+import org.objectweb.asm.Opcodes;
/**
* New instruction handler.
* @since 0.1
*/
-public final class NewHandler implements InstructionHandler {
+public final class NewAgent implements DecompilationAgent {
+
+ /**
+ * Supported opcodes.
+ */
+ private static final Set SUPPORTED = new HashSet<>(
+ Arrays.asList(
+ Opcodes.NEW
+ )
+ );
@Override
public void handle(final DecompilerState state) {
- state.stack().push(new NewAddress(state.operand(0).toString()));
+ if (NewAgent.SUPPORTED.contains(state.instruction().opcode())) {
+ state.stack().push(new NewAddress(state.operand(0).toString()));
+ state.popInstruction();
+ }
}
}
diff --git a/src/main/java/org/eolang/opeo/decompilation/handlers/NewArrayHandler.java b/src/main/java/org/eolang/opeo/decompilation/agents/NewArrayAgent.java
similarity index 65%
rename from src/main/java/org/eolang/opeo/decompilation/handlers/NewArrayHandler.java
rename to src/main/java/org/eolang/opeo/decompilation/agents/NewArrayAgent.java
index e6d5ab31..4825c7eb 100644
--- a/src/main/java/org/eolang/opeo/decompilation/handlers/NewArrayHandler.java
+++ b/src/main/java/org/eolang/opeo/decompilation/agents/NewArrayAgent.java
@@ -21,27 +21,42 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-package org.eolang.opeo.decompilation.handlers;
+package org.eolang.opeo.decompilation.agents;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
import org.eolang.opeo.ast.ArrayConstructor;
import org.eolang.opeo.ast.AstNode;
import org.eolang.opeo.ast.Reference;
+import org.eolang.opeo.decompilation.DecompilationAgent;
import org.eolang.opeo.decompilation.DecompilerState;
-import org.eolang.opeo.decompilation.InstructionHandler;
import org.eolang.opeo.decompilation.OperandStack;
+import org.objectweb.asm.Opcodes;
/**
* New array instruction handler.
* @since 0.1
*/
-public final class NewArrayHandler implements InstructionHandler {
+public final class NewArrayAgent implements DecompilationAgent {
+
+ /**
+ * Supported opcodes.
+ */
+ private static final Set SUPPORTED = new HashSet<>(
+ Arrays.asList(
+ Opcodes.ANEWARRAY
+ )
+ );
@Override
public void handle(final DecompilerState state) {
- final String type = (String) state.operand(0);
- final OperandStack stack = state.stack();
- final AstNode size = stack.pop();
- stack.push(new Reference(new ArrayConstructor(size, type)));
+ if (NewArrayAgent.SUPPORTED.contains(state.instruction().opcode())) {
+ final String type = (String) state.operand(0);
+ final OperandStack stack = state.stack();
+ final AstNode size = stack.pop();
+ stack.push(new Reference(new ArrayConstructor(size, type)));
+ state.popInstruction();
+ }
}
-
}
diff --git a/src/main/java/org/eolang/opeo/decompilation/handlers/PopHandler.java b/src/main/java/org/eolang/opeo/decompilation/agents/PopAgent.java
similarity index 77%
rename from src/main/java/org/eolang/opeo/decompilation/handlers/PopHandler.java
rename to src/main/java/org/eolang/opeo/decompilation/agents/PopAgent.java
index cb114de5..3ae38915 100644
--- a/src/main/java/org/eolang/opeo/decompilation/handlers/PopHandler.java
+++ b/src/main/java/org/eolang/opeo/decompilation/agents/PopAgent.java
@@ -21,23 +21,27 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-package org.eolang.opeo.decompilation.handlers;
+package org.eolang.opeo.decompilation.agents;
import org.eolang.opeo.ast.Popped;
+import org.eolang.opeo.decompilation.DecompilationAgent;
import org.eolang.opeo.decompilation.DecompilerState;
-import org.eolang.opeo.decompilation.InstructionHandler;
import org.eolang.opeo.decompilation.OperandStack;
+import org.objectweb.asm.Opcodes;
/**
* Pop instruction handler.
* @since 0.1
*/
-public final class PopHandler implements InstructionHandler {
+public final class PopAgent implements DecompilationAgent {
@Override
public void handle(final DecompilerState state) {
- final OperandStack stack = state.stack();
- stack.push(new Popped(stack.pop()));
+ if (state.instruction().opcode() == Opcodes.POP) {
+ final OperandStack stack = state.stack();
+ stack.push(new Popped(stack.pop()));
+ state.popInstruction();
+ }
}
}
diff --git a/src/main/java/org/eolang/opeo/decompilation/agents/PutFieldAgent.java b/src/main/java/org/eolang/opeo/decompilation/agents/PutFieldAgent.java
new file mode 100644
index 00000000..49674109
--- /dev/null
+++ b/src/main/java/org/eolang/opeo/decompilation/agents/PutFieldAgent.java
@@ -0,0 +1,63 @@
+/*
+ * 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.opeo.decompilation.agents;
+
+import org.eolang.opeo.ast.AstNode;
+import org.eolang.opeo.ast.Attributes;
+import org.eolang.opeo.ast.Field;
+import org.eolang.opeo.ast.FieldAssignment;
+import org.eolang.opeo.decompilation.DecompilationAgent;
+import org.eolang.opeo.decompilation.DecompilerState;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * Putfield instruction handler.
+ * Stack [before]->[after]: "objectref, value →"
+ * @since 0.1
+ */
+public final class PutFieldAgent implements DecompilationAgent {
+
+ @Override
+ public void handle(final DecompilerState state) {
+ if (state.instruction().opcode() == Opcodes.PUTFIELD) {
+ final AstNode value = state.stack().pop();
+ final String name = (String) state.operand(1);
+ final String owner = (String) state.operand(0);
+ final String descriptor = (String) state.operand(2);
+ state.stack().push(
+ new FieldAssignment(
+ new Field(
+ state.stack().pop(),
+ new Attributes()
+ .name(name)
+ .owner(owner)
+ .descriptor(descriptor)
+ ),
+ value
+ )
+ );
+ state.popInstruction();
+ }
+ }
+}
diff --git a/src/main/java/org/eolang/opeo/decompilation/handlers/ReturnHandler.java b/src/main/java/org/eolang/opeo/decompilation/agents/ReturnAgent.java
similarity index 51%
rename from src/main/java/org/eolang/opeo/decompilation/handlers/ReturnHandler.java
rename to src/main/java/org/eolang/opeo/decompilation/agents/ReturnAgent.java
index fa3d7f00..7d6a2a9f 100644
--- a/src/main/java/org/eolang/opeo/decompilation/handlers/ReturnHandler.java
+++ b/src/main/java/org/eolang/opeo/decompilation/agents/ReturnAgent.java
@@ -21,11 +21,14 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-package org.eolang.opeo.decompilation.handlers;
+package org.eolang.opeo.decompilation.agents;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
import org.eolang.opeo.ast.Return;
+import org.eolang.opeo.decompilation.DecompilationAgent;
import org.eolang.opeo.decompilation.DecompilerState;
-import org.eolang.opeo.decompilation.InstructionHandler;
import org.eolang.opeo.decompilation.OperandStack;
import org.objectweb.asm.Opcodes;
@@ -34,28 +37,45 @@
* @since 0.1
* @checkstyle ClassFanOutComplexityCheck (500 lines)
*/
-public final class ReturnHandler implements InstructionHandler {
+public final class ReturnAgent implements DecompilationAgent {
+
+ /**
+ * Supported opcodes.
+ */
+ private static final Set SUPPORTED = new HashSet<>(
+ Arrays.asList(
+ Opcodes.RETURN,
+ Opcodes.IRETURN,
+ Opcodes.LRETURN,
+ Opcodes.FRETURN,
+ Opcodes.DRETURN,
+ Opcodes.ARETURN
+ )
+ );
@Override
public void handle(final DecompilerState state) {
final int opcode = state.instruction().opcode();
- final OperandStack stack = state.stack();
- if (opcode == Opcodes.RETURN) {
- stack.push(new Return());
- } else if (opcode == Opcodes.IRETURN) {
- stack.push(new Return(stack.pop()));
- } else if (opcode == Opcodes.LRETURN) {
- stack.push(new Return(stack.pop()));
- } else if (opcode == Opcodes.FRETURN) {
- stack.push(new Return(stack.pop()));
- } else if (opcode == Opcodes.DRETURN) {
- stack.push(new Return(stack.pop()));
- } else if (opcode == Opcodes.ARETURN) {
- stack.push(new Return(stack.pop()));
- } else {
- throw new IllegalStateException(
- String.format("Unexpected opcode: %d", opcode)
- );
+ if (ReturnAgent.SUPPORTED.contains(opcode)) {
+ final OperandStack stack = state.stack();
+ if (opcode == Opcodes.RETURN) {
+ stack.push(new Return());
+ } else if (opcode == Opcodes.IRETURN) {
+ stack.push(new Return(stack.pop()));
+ } else if (opcode == Opcodes.LRETURN) {
+ stack.push(new Return(stack.pop()));
+ } else if (opcode == Opcodes.FRETURN) {
+ stack.push(new Return(stack.pop()));
+ } else if (opcode == Opcodes.DRETURN) {
+ stack.push(new Return(stack.pop()));
+ } else if (opcode == Opcodes.ARETURN) {
+ stack.push(new Return(stack.pop()));
+ } else {
+ throw new IllegalStateException(
+ String.format("Unexpected opcode: %d", opcode)
+ );
+ }
+ state.popInstruction();
}
}
}
diff --git a/src/main/java/org/eolang/opeo/decompilation/agents/StoreAgent.java b/src/main/java/org/eolang/opeo/decompilation/agents/StoreAgent.java
new file mode 100644
index 00000000..031ff32e
--- /dev/null
+++ b/src/main/java/org/eolang/opeo/decompilation/agents/StoreAgent.java
@@ -0,0 +1,122 @@
+/*
+ * 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.opeo.decompilation.agents;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import org.eolang.opeo.ast.AstNode;
+import org.eolang.opeo.ast.LocalVariable;
+import org.eolang.opeo.ast.Typed;
+import org.eolang.opeo.ast.VariableAssignment;
+import org.eolang.opeo.decompilation.DecompilationAgent;
+import org.eolang.opeo.decompilation.DecompilerState;
+import org.eolang.opeo.decompilation.OperandStack;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+/**
+ * Store instruction handler.
+ * @since 0.1
+ */
+public final class StoreAgent implements DecompilationAgent {
+
+ /**
+ * Supported opcodes.
+ */
+ private static final Set SUPPORTED = new HashSet<>(
+ Arrays.asList(
+ Opcodes.ISTORE,
+ Opcodes.LSTORE,
+ Opcodes.FSTORE,
+ Opcodes.DSTORE,
+ Opcodes.ASTORE
+ )
+ );
+
+ @Override
+ public void handle(final DecompilerState state) {
+ final int opcode = state.instruction().opcode();
+ if (StoreAgent.SUPPORTED.contains(opcode)) {
+ final OperandStack stack = state.stack();
+ final AstNode value = stack.pop();
+ stack.push(
+ new VariableAssignment(
+ (LocalVariable) state.variable(
+ (Integer) state.operand(0), StoreAgent.infer(value, opcode)
+ ),
+ value
+ )
+ );
+ state.popInstruction();
+ }
+ }
+
+ /**
+ * Infer type of the variable.
+ * @param value Value to infer type from.
+ * @param opcode Opcode.
+ * @return Inferred type.
+ */
+ private static Type infer(final AstNode value, final int opcode) {
+ final Type result;
+ if (value instanceof Typed) {
+ result = ((Typed) value).type();
+ } else {
+ result = StoreAgent.type(opcode);
+ }
+ return result;
+ }
+
+ /**
+ * Infer type from opcode.
+ * @param opcode Opcode.
+ * @return Inferred type.
+ */
+ private static Type type(final int opcode) {
+ final Type result;
+ switch (opcode) {
+ case Opcodes.ISTORE:
+ result = Type.INT_TYPE;
+ break;
+ case Opcodes.LSTORE:
+ result = Type.LONG_TYPE;
+ break;
+ case Opcodes.FSTORE:
+ result = Type.FLOAT_TYPE;
+ break;
+ case Opcodes.DSTORE:
+ result = Type.DOUBLE_TYPE;
+ break;
+ case Opcodes.ASTORE:
+ result = Type.getType(Object.class);
+ break;
+ default:
+ throw new IllegalArgumentException(
+ String.format("Unsupported opcode: %d", opcode)
+ );
+ }
+ return result;
+ }
+}
diff --git a/src/main/java/org/eolang/opeo/decompilation/handlers/StoreToArrayHandler.java b/src/main/java/org/eolang/opeo/decompilation/agents/StoreToArrayAgent.java
similarity index 71%
rename from src/main/java/org/eolang/opeo/decompilation/handlers/StoreToArrayHandler.java
rename to src/main/java/org/eolang/opeo/decompilation/agents/StoreToArrayAgent.java
index ec13b8d9..b94fa92f 100644
--- a/src/main/java/org/eolang/opeo/decompilation/handlers/StoreToArrayHandler.java
+++ b/src/main/java/org/eolang/opeo/decompilation/agents/StoreToArrayAgent.java
@@ -21,16 +21,19 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-package org.eolang.opeo.decompilation.handlers;
+package org.eolang.opeo.decompilation.agents;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
import org.eolang.opeo.ast.AstNode;
import org.eolang.opeo.ast.Duplicate;
import org.eolang.opeo.ast.FieldRetrieval;
import org.eolang.opeo.ast.Labeled;
import org.eolang.opeo.ast.Reference;
import org.eolang.opeo.ast.StoreArray;
+import org.eolang.opeo.decompilation.DecompilationAgent;
import org.eolang.opeo.decompilation.DecompilerState;
-import org.eolang.opeo.decompilation.InstructionHandler;
/**
* Store to array instruction handler.
@@ -38,24 +41,36 @@
* Opcodes: aastore
* Stack [before]->[after]: "arrayref, index, value →"
* @since 0.1
- * @todo #329:90min Avoid using 'instance of' in {@link StoreToArrayHandler#findRef(AstNode)}.
+ * @todo #329:90min Avoid using 'instance of' in {@link StoreToArrayAgent#findRef(AstNode)}.
* Here we use 'instance of' statement to find a Reference.
* The solution related to Reference looks incorrect, in general.
* We should invent a proper solution without the use of this statement.
*/
-public final class StoreToArrayHandler implements InstructionHandler {
+public final class StoreToArrayAgent implements DecompilationAgent {
+
+ /**
+ * Supported opcodes.
+ */
+ private static final Set SUPPORTED = new HashSet<>(
+ Arrays.asList(
+ org.objectweb.asm.Opcodes.AASTORE
+ )
+ );
@Override
public void handle(final DecompilerState state) {
- final AstNode value = state.stack().pop();
- final AstNode index = state.stack().pop();
- final AstNode array = state.stack().pop();
- try {
- final Reference ref = this.findRef(array);
- ref.link(new StoreArray(ref.object(), index, value));
- state.stack().push(ref);
- } catch (final IllegalStateException exception) {
- state.stack().push(new StoreArray(array, index, value));
+ if (StoreToArrayAgent.SUPPORTED.contains(state.instruction().opcode())) {
+ final AstNode value = state.stack().pop();
+ final AstNode index = state.stack().pop();
+ final AstNode array = state.stack().pop();
+ try {
+ final Reference ref = this.findRef(array);
+ ref.link(new StoreArray(ref.object(), index, value));
+ state.stack().push(ref);
+ } catch (final IllegalStateException exception) {
+ state.stack().push(new StoreArray(array, index, value));
+ }
+ state.popInstruction();
}
}
diff --git a/src/main/java/org/eolang/opeo/decompilation/handlers/SubstractionHandler.java b/src/main/java/org/eolang/opeo/decompilation/agents/SubstractionAgent.java
similarity index 62%
rename from src/main/java/org/eolang/opeo/decompilation/handlers/SubstractionHandler.java
rename to src/main/java/org/eolang/opeo/decompilation/agents/SubstractionAgent.java
index f5b66c0d..b17c1402 100644
--- a/src/main/java/org/eolang/opeo/decompilation/handlers/SubstractionHandler.java
+++ b/src/main/java/org/eolang/opeo/decompilation/agents/SubstractionAgent.java
@@ -21,23 +21,43 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-package org.eolang.opeo.decompilation.handlers;
+package org.eolang.opeo.decompilation.agents;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
import org.eolang.opeo.ast.AstNode;
import org.eolang.opeo.ast.Substraction;
+import org.eolang.opeo.decompilation.DecompilationAgent;
import org.eolang.opeo.decompilation.DecompilerState;
-import org.eolang.opeo.decompilation.InstructionHandler;
+import org.objectweb.asm.Opcodes;
/**
* Substraction instruction handler.
* @since 0.1
*/
-public final class SubstractionHandler implements InstructionHandler {
+public final class SubstractionAgent implements DecompilationAgent {
+
+ /**
+ * Supported opcodes.
+ */
+ private static final Set SUPPORTED = new HashSet<>(
+ Arrays.asList(
+ Opcodes.ISUB,
+ Opcodes.LSUB,
+ Opcodes.FSUB,
+ Opcodes.DSUB
+ )
+ );
@Override
public void handle(final DecompilerState state) {
- final AstNode right = state.stack().pop();
- final AstNode left = state.stack().pop();
- state.stack().push(new Substraction(left, right));
+ final int opcode = state.instruction().opcode();
+ if (SubstractionAgent.SUPPORTED.contains(opcode)) {
+ final AstNode right = state.stack().pop();
+ final AstNode left = state.stack().pop();
+ state.stack().push(new Substraction(left, right));
+ state.popInstruction();
+ }
}
}
diff --git a/src/main/java/org/eolang/opeo/decompilation/handlers/package-info.java b/src/main/java/org/eolang/opeo/decompilation/agents/package-info.java
similarity index 96%
rename from src/main/java/org/eolang/opeo/decompilation/handlers/package-info.java
rename to src/main/java/org/eolang/opeo/decompilation/agents/package-info.java
index a520f234..0eaf15e0 100644
--- a/src/main/java/org/eolang/opeo/decompilation/handlers/package-info.java
+++ b/src/main/java/org/eolang/opeo/decompilation/agents/package-info.java
@@ -29,4 +29,4 @@
* It would also be good to generalize some of the handlers. For example, AddHandler might
* handle all the types, not only Integer and Long.
*/
-package org.eolang.opeo.decompilation.handlers;
+package org.eolang.opeo.decompilation.agents;
diff --git a/src/main/java/org/eolang/opeo/decompilation/handlers/CastHandler.java b/src/main/java/org/eolang/opeo/decompilation/handlers/CastHandler.java
deleted file mode 100644
index d151c433..00000000
--- a/src/main/java/org/eolang/opeo/decompilation/handlers/CastHandler.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.opeo.decompilation.handlers;
-
-import org.eolang.opeo.ast.Cast;
-import org.eolang.opeo.decompilation.DecompilerState;
-import org.eolang.opeo.decompilation.InstructionHandler;
-import org.objectweb.asm.Type;
-
-/**
- * Cast instruction handler.
- * @since 0.2
- */
-public final class CastHandler implements InstructionHandler {
-
- /**
- * Target type.
- */
- private final Type target;
-
- /**
- * Constructor.
- * @param target Target type
- */
- CastHandler(final Type target) {
- this.target = target;
- }
-
- @Override
- public void handle(final DecompilerState state) {
- state.stack().push(
- new Cast(
- this.target,
- state.stack().pop()
- )
- );
- }
-}
diff --git a/src/main/java/org/eolang/opeo/decompilation/handlers/GetFieldHandler.java b/src/main/java/org/eolang/opeo/decompilation/handlers/GetFieldHandler.java
deleted file mode 100644
index 3f2544f2..00000000
--- a/src/main/java/org/eolang/opeo/decompilation/handlers/GetFieldHandler.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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.opeo.decompilation.handlers;
-
-import org.eolang.opeo.ast.Attributes;
-import org.eolang.opeo.ast.FieldRetrieval;
-import org.eolang.opeo.decompilation.DecompilerState;
-import org.eolang.opeo.decompilation.InstructionHandler;
-
-/**
- * Getfield instruction handler.
- * @since 0.1
- */
-public final class GetFieldHandler implements InstructionHandler {
-
- @Override
- public void handle(final DecompilerState state) {
- final String owner = (String) state.operand(0);
- final String name = (String) state.operand(1);
- final String descriptor = (String) state.operand(2);
- state.stack().push(
- new FieldRetrieval(
- state.stack().pop(),
- new Attributes()
- .name(name)
- .descriptor(descriptor)
- .owner(owner)
- .type("field")
- )
- );
- }
-
-}
diff --git a/src/main/java/org/eolang/opeo/decompilation/handlers/LoadHandler.java b/src/main/java/org/eolang/opeo/decompilation/handlers/LoadHandler.java
deleted file mode 100644
index 1703958c..00000000
--- a/src/main/java/org/eolang/opeo/decompilation/handlers/LoadHandler.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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.opeo.decompilation.handlers;
-
-import org.eolang.opeo.decompilation.DecompilerState;
-import org.eolang.opeo.decompilation.InstructionHandler;
-import org.objectweb.asm.Type;
-
-/**
- * Instruction handler.
- * This handler might understand the following instructions:
- * aload: 1: index | → objectref | load a reference onto the stack from a local variable #index
- * aload_0: → objectref | load a reference onto the stack from local variable 0
- * ...
- * @since 0.1
- */
-public final class LoadHandler implements InstructionHandler {
-
- /**
- * Type of the variable.
- */
- private final Type type;
-
- /**
- * Constructor.
- * @param type Type of the variable.
- */
- public LoadHandler(final Type type) {
- this.type = type;
- }
-
- @Override
- public void handle(final DecompilerState state) {
- final Integer index = (Integer) state.operand(0);
- state.stack().push(
- state.variable(index, this.type)
- );
- }
-}
diff --git a/src/main/java/org/eolang/opeo/decompilation/handlers/RouterHandler.java b/src/main/java/org/eolang/opeo/decompilation/handlers/RouterHandler.java
deleted file mode 100644
index 81e031a1..00000000
--- a/src/main/java/org/eolang/opeo/decompilation/handlers/RouterHandler.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * 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.opeo.decompilation.handlers;
-
-import java.util.Map;
-import org.cactoos.map.MapEntry;
-import org.cactoos.map.MapOf;
-import org.eolang.opeo.LabelInstruction;
-import org.eolang.opeo.ast.Opcode;
-import org.eolang.opeo.ast.OpcodeName;
-import org.eolang.opeo.decompilation.DecompilerState;
-import org.eolang.opeo.decompilation.InstructionHandler;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-
-/**
- * General Instruction Handler.
- * This handler redirects handling of instructions depending on an incoming instruction.
- * @since 0.2
- * @checkstyle ClassFanOutComplexityCheck (500 lines)
- */
-public final class RouterHandler implements InstructionHandler {
-
- /**
- * Index of unimplemented handler.
- */
- private static final int UNIMPLEMENTED = -1;
-
- /**
- * ALl instruction handlers.
- */
- private final Map handlers;
-
- /**
- * Constructor.
- * @param counting Do we put numbers to opcodes?
- */
- public RouterHandler(final boolean counting) {
- this(
- new MapOf(
- new MapEntry<>(Opcodes.ICONST_M1, new ConstHandler(Type.INT_TYPE)),
- new MapEntry<>(Opcodes.ICONST_0, new ConstHandler(Type.INT_TYPE)),
- new MapEntry<>(Opcodes.ICONST_1, new ConstHandler(Type.INT_TYPE)),
- new MapEntry<>(Opcodes.ICONST_2, new ConstHandler(Type.INT_TYPE)),
- new MapEntry<>(Opcodes.ICONST_3, new ConstHandler(Type.INT_TYPE)),
- new MapEntry<>(Opcodes.ICONST_4, new ConstHandler(Type.INT_TYPE)),
- new MapEntry<>(Opcodes.ICONST_5, new ConstHandler(Type.INT_TYPE)),
- new MapEntry<>(Opcodes.LCONST_0, new ConstHandler(Type.LONG_TYPE)),
- new MapEntry<>(Opcodes.LCONST_1, new ConstHandler(Type.LONG_TYPE)),
- new MapEntry<>(Opcodes.FCONST_0, new ConstHandler(Type.FLOAT_TYPE)),
- new MapEntry<>(Opcodes.FCONST_1, new ConstHandler(Type.FLOAT_TYPE)),
- new MapEntry<>(Opcodes.FCONST_2, new ConstHandler(Type.FLOAT_TYPE)),
- new MapEntry<>(Opcodes.DCONST_0, new ConstHandler(Type.DOUBLE_TYPE)),
- new MapEntry<>(Opcodes.DCONST_1, new ConstHandler(Type.DOUBLE_TYPE)),
- new MapEntry<>(Opcodes.IADD, new AddHandler()),
- new MapEntry<>(Opcodes.LADD, new AddHandler()),
- new MapEntry<>(Opcodes.FADD, new AddHandler()),
- new MapEntry<>(Opcodes.DADD, new AddHandler()),
- new MapEntry<>(Opcodes.ISUB, new SubstractionHandler()),
- new MapEntry<>(Opcodes.LSUB, new SubstractionHandler()),
- new MapEntry<>(Opcodes.FSUB, new SubstractionHandler()),
- new MapEntry<>(Opcodes.DSUB, new SubstractionHandler()),
- new MapEntry<>(Opcodes.IMUL, new MulHandler(counting)),
- new MapEntry<>(Opcodes.IF_ICMPGT, new IfHandler()),
- new MapEntry<>(Opcodes.I2B, new CastHandler(Type.BYTE_TYPE)),
- new MapEntry<>(Opcodes.I2C, new CastHandler(Type.CHAR_TYPE)),
- new MapEntry<>(Opcodes.I2S, new CastHandler(Type.SHORT_TYPE)),
- new MapEntry<>(Opcodes.I2L, new CastHandler(Type.LONG_TYPE)),
- new MapEntry<>(Opcodes.I2F, new CastHandler(Type.FLOAT_TYPE)),
- new MapEntry<>(Opcodes.I2D, new CastHandler(Type.DOUBLE_TYPE)),
- new MapEntry<>(Opcodes.L2I, new CastHandler(Type.INT_TYPE)),
- new MapEntry<>(Opcodes.L2F, new CastHandler(Type.FLOAT_TYPE)),
- new MapEntry<>(Opcodes.L2D, new CastHandler(Type.DOUBLE_TYPE)),
- new MapEntry<>(Opcodes.F2I, new CastHandler(Type.INT_TYPE)),
- new MapEntry<>(Opcodes.F2L, new CastHandler(Type.LONG_TYPE)),
- new MapEntry<>(Opcodes.F2D, new CastHandler(Type.DOUBLE_TYPE)),
- new MapEntry<>(Opcodes.D2I, new CastHandler(Type.INT_TYPE)),
- new MapEntry<>(Opcodes.D2L, new CastHandler(Type.LONG_TYPE)),
- new MapEntry<>(Opcodes.D2F, new CastHandler(Type.FLOAT_TYPE)),
- new MapEntry<>(Opcodes.ILOAD, new LoadHandler(Type.INT_TYPE)),
- new MapEntry<>(Opcodes.LLOAD, new LoadHandler(Type.LONG_TYPE)),
- new MapEntry<>(Opcodes.FLOAD, new LoadHandler(Type.FLOAT_TYPE)),
- new MapEntry<>(Opcodes.DLOAD, new LoadHandler(Type.DOUBLE_TYPE)),
- new MapEntry<>(Opcodes.ALOAD, new LoadHandler(Type.getType(Object.class))),
- new MapEntry<>(Opcodes.ISTORE, new StoreHandler(Type.INT_TYPE)),
- new MapEntry<>(Opcodes.LSTORE, new StoreHandler(Type.LONG_TYPE)),
- new MapEntry<>(Opcodes.FSTORE, new StoreHandler(Type.FLOAT_TYPE)),
- new MapEntry<>(Opcodes.DSTORE, new StoreHandler(Type.DOUBLE_TYPE)),
- new MapEntry<>(Opcodes.ASTORE, new StoreHandler(Type.getType(Object.class))),
- new MapEntry<>(Opcodes.AASTORE, new StoreToArrayHandler()),
- new MapEntry<>(Opcodes.ANEWARRAY, new NewArrayHandler()),
- new MapEntry<>(Opcodes.CHECKCAST, new CheckCastHandler()),
- new MapEntry<>(Opcodes.NEW, new NewHandler()),
- new MapEntry<>(Opcodes.DUP, new DupHandler()),
- new MapEntry<>(Opcodes.BIPUSH, new BipushHandler()),
- new MapEntry<>(Opcodes.INVOKESPECIAL, new InvokespecialHandler()),
- new MapEntry<>(Opcodes.INVOKEVIRTUAL, new InvokevirtualHandler()),
- new MapEntry<>(Opcodes.INVOKESTATIC, new InvokestaticHander()),
- new MapEntry<>(Opcodes.INVOKEINTERFACE, new InvokeinterfaceHandler()),
- new MapEntry<>(Opcodes.INVOKEDYNAMIC, new InvokedynamicHandler()),
- new MapEntry<>(Opcodes.GETFIELD, new GetFieldHandler()),
- new MapEntry<>(Opcodes.PUTFIELD, new PutFieldHnadler()),
- new MapEntry<>(Opcodes.GETSTATIC, new GetStaticHnadler()),
- new MapEntry<>(Opcodes.LDC, new LdcHandler()),
- new MapEntry<>(Opcodes.POP, new PopHandler()),
- new MapEntry<>(Opcodes.RETURN, new ReturnHandler()),
- new MapEntry<>(Opcodes.IRETURN, new ReturnHandler()),
- new MapEntry<>(Opcodes.ARETURN, new ReturnHandler()),
- new MapEntry<>(LabelInstruction.LABEL_OPCODE, new LabelHandler()),
- new MapEntry<>(RouterHandler.UNIMPLEMENTED, new UnimplementedHandler(counting))
- )
- );
- }
-
- /**
- * Constructor.
- * @param handlers All handlers that will try to handle incoming instructions.
- */
- private RouterHandler(final Map handlers) {
- this.handlers = handlers;
- }
-
- @Override
- public void handle(final DecompilerState state) {
- this.handler(state.instruction().opcode()).handle(state);
- }
-
- /**
- * Get supported opcodes.
- * @return Supported opcodes.
- */
- public String[] supportedOpcodes() {
- return this.handlers.keySet()
- .stream()
- .map(OpcodeName::new)
- .map(OpcodeName::simplified)
- .toArray(String[]::new);
- }
-
- /**
- * Get instruction handler.
- * @param opcode Instruction opcode.
- * @return Instruction handler.
- */
- private InstructionHandler handler(final int opcode) {
- return this.handlers.getOrDefault(opcode, this.handlers.get(RouterHandler.UNIMPLEMENTED));
- }
-
- /**
- * Unimplemented instruction handler.
- * @since 0.1
- */
- private static final class UnimplementedHandler implements InstructionHandler {
-
- /**
- * Do we put numbers to opcodes?
- */
- private final boolean counting;
-
- /**
- * Constructor.
- * @param counting Flag which decides if we need to count opcodes.
- */
- private UnimplementedHandler(final boolean counting) {
- this.counting = counting;
- }
-
- @Override
- public void handle(final DecompilerState state) {
- state.stack().push(
- new Opcode(
- state.instruction().opcode(),
- state.instruction().operands(),
- this.counting
- )
- );
- }
- }
-}
diff --git a/src/main/java/org/eolang/opeo/decompilation/handlers/StoreHandler.java b/src/main/java/org/eolang/opeo/decompilation/handlers/StoreHandler.java
deleted file mode 100644
index 59cd86bc..00000000
--- a/src/main/java/org/eolang/opeo/decompilation/handlers/StoreHandler.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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.opeo.decompilation.handlers;
-
-import org.eolang.opeo.ast.AstNode;
-import org.eolang.opeo.ast.LocalVariable;
-import org.eolang.opeo.ast.Typed;
-import org.eolang.opeo.ast.VariableAssignment;
-import org.eolang.opeo.decompilation.DecompilerState;
-import org.eolang.opeo.decompilation.InstructionHandler;
-import org.eolang.opeo.decompilation.OperandStack;
-import org.objectweb.asm.Type;
-
-/**
- * Store instruction handler.
- * @since 0.1
- */
-public final class StoreHandler implements InstructionHandler {
-
- /**
- * Type of the variable.
- */
- private final Type type;
-
- /**
- * Constructor.
- * @param type Type of the variable.
- */
- public StoreHandler(final Type type) {
- this.type = type;
- }
-
- @Override
- public void handle(final DecompilerState state) {
- final OperandStack stack = state.stack();
- final AstNode value = stack.pop();
- stack.push(
- new VariableAssignment(
- (LocalVariable) state.variable((Integer) state.operand(0), this.infer(value)),
- value
- )
- );
- }
-
- /**
- * Infer type of the variable.
- * @param value Value to infer type from.
- * @return Inferred type.
- */
- private Type infer(final AstNode value) {
- final Type result;
- if (value instanceof Typed) {
- result = ((Typed) value).type();
- } else {
- result = this.type;
- }
- return result;
- }
-
-}
diff --git a/src/test/java/org/eolang/opeo/ast/AddTest.java b/src/test/java/org/eolang/opeo/ast/AdditionTest.java
similarity index 86%
rename from src/test/java/org/eolang/opeo/ast/AddTest.java
rename to src/test/java/org/eolang/opeo/ast/AdditionTest.java
index 94aca802..cca090a9 100644
--- a/src/test/java/org/eolang/opeo/ast/AddTest.java
+++ b/src/test/java/org/eolang/opeo/ast/AdditionTest.java
@@ -34,14 +34,14 @@
import org.xembly.Xembler;
/**
- * Test case for {@link Add}.
+ * Test case for {@link Addition}.
* @since 0.1
*/
-final class AddTest {
+final class AdditionTest {
@Test
void convertsToXmir() throws ImpossibleModificationException {
- final String res = new Xembler(new Add(new Literal(1), new Literal(2)).toXmir()).xml();
+ final String res = new Xembler(new Addition(new Literal(1), new Literal(2)).toXmir()).xml();
MatcherAssert.assertThat(
String.format(
"Can't convert to correct XMIR, result is : %n%s%n",
@@ -60,42 +60,42 @@ void convertsToXmir() throws ImpossibleModificationException {
void determinesPrimitiveTypesCorrectly() {
MatcherAssert.assertThat(
"Can't determine the type of Add with two integer literals",
- new Add(new Literal(1), new Literal(2)).type(),
+ new Addition(new Literal(1), new Literal(2)).type(),
Matchers.equalTo(Type.INT_TYPE)
);
MatcherAssert.assertThat(
"Can't determine the type of Add with two long literals",
- new Add(new Literal(1L), new Literal(2L)).type(),
+ new Addition(new Literal(1L), new Literal(2L)).type(),
Matchers.equalTo(Type.LONG_TYPE)
);
MatcherAssert.assertThat(
"Can't determine the type of Add with two float literals",
- new Add(new Literal(1.0f), new Literal(2.0f)).type(),
+ new Addition(new Literal(1.0f), new Literal(2.0f)).type(),
Matchers.equalTo(Type.FLOAT_TYPE)
);
MatcherAssert.assertThat(
"Can't determine the type of Add with two double literals",
- new Add(new Literal(1.0), new Literal(2.0)).type(),
+ new Addition(new Literal(1.0), new Literal(2.0)).type(),
Matchers.equalTo(Type.DOUBLE_TYPE)
);
MatcherAssert.assertThat(
"Can't determine the type of Add with two integer and long literals",
- new Add(new Literal(1), new Literal(2L)).type(),
+ new Addition(new Literal(1), new Literal(2L)).type(),
Matchers.equalTo(Type.LONG_TYPE)
);
MatcherAssert.assertThat(
"Can't determine the type of Add with two integer and float literals",
- new Add(new Literal(1), new Literal(2.0f)).type(),
+ new Addition(new Literal(1), new Literal(2.0f)).type(),
Matchers.equalTo(Type.FLOAT_TYPE)
);
MatcherAssert.assertThat(
"Can't determine the type of Add with two integer and double literals",
- new Add(new Literal(1), new Literal(2.0)).type(),
+ new Addition(new Literal(1), new Literal(2.0)).type(),
Matchers.equalTo(Type.DOUBLE_TYPE)
);
MatcherAssert.assertThat(
"Can't determine the type of Add with two long and float literals",
- new Add(new Literal(1L), new Literal(2.0f)).type(),
+ new Addition(new Literal(1L), new Literal(2.0f)).type(),
Matchers.equalTo(Type.FLOAT_TYPE)
);
}
@@ -105,7 +105,7 @@ void retrievesOpcodesWithLeftAndRightNodesWithTheSameType() {
MatcherAssert.assertThat(
"Can't retrieve opcodes from Add with two literals",
new OpcodeNodes(
- new Add(
+ new Addition(
new Literal(1),
new Literal(2)
)
@@ -123,7 +123,7 @@ void retrievesOpcodesWithLeftAndRightNodesWithDifferentTypes() {
MatcherAssert.assertThat(
"Can't retrieve opcodes from Add with two literals of different types",
new OpcodeNodes(
- new Add(
+ new Addition(
new Literal(1L),
new Literal(1)
)
@@ -141,7 +141,7 @@ void retrievesOpcodesWithLeftAndRightNodesWithDoubleType() {
MatcherAssert.assertThat(
"Can't retrieve opcodes from Add with where one of the operands is double",
new OpcodeNodes(
- new Add(
+ new Addition(
new Literal(1.0),
new Literal(1)
)
diff --git a/src/test/java/org/eolang/opeo/ast/ArrayConstructorTest.java b/src/test/java/org/eolang/opeo/ast/ArrayConstructorTest.java
index c9f39145..eaf6bae8 100644
--- a/src/test/java/org/eolang/opeo/ast/ArrayConstructorTest.java
+++ b/src/test/java/org/eolang/opeo/ast/ArrayConstructorTest.java
@@ -59,10 +59,16 @@ void createsArrayConstructorFromXmir() {
"Can't create array constructor from XMIR",
new ArrayConstructor(
new XmlNode(ArrayConstructorTest.XMIR),
- node -> new Add(new Literal(1), new Literal(2))
+ node -> new Addition(new Literal(1), new Literal(2))
),
Matchers.equalTo(
- new ArrayConstructor(new Add(new Literal(1), new Literal(2)), "java/lang/Integer")
+ new ArrayConstructor(
+ new Addition(
+ new Literal(1),
+ new Literal(2)
+ ),
+ "java/lang/Integer"
+ )
)
);
}
@@ -90,7 +96,7 @@ void compilesArrayWithComplexLength() {
"Can't compile array constructor with complex undefined length",
new OpcodeNodes(
new ArrayConstructor(
- new Add(new Literal(1), new Literal(2)),
+ new Addition(new Literal(1), new Literal(2)),
type
)
).opcodes(),
@@ -109,7 +115,7 @@ void convertsToXmir() throws ImpossibleModificationException {
final String type = "java/lang/Integer";
final String xmir = new Xembler(
new ArrayConstructor(
- new Add(new Literal(1), new Literal(2)),
+ new Addition(new Literal(1), new Literal(2)),
type
).toXmir()
).xml();
diff --git a/src/test/java/org/eolang/opeo/compilation/XmirParserTest.java b/src/test/java/org/eolang/opeo/compilation/XmirParserTest.java
index db8f67d3..9d46d8e3 100644
--- a/src/test/java/org/eolang/opeo/compilation/XmirParserTest.java
+++ b/src/test/java/org/eolang/opeo/compilation/XmirParserTest.java
@@ -27,7 +27,7 @@
import java.util.List;
import org.eolang.jeo.matchers.SameXml;
import org.eolang.jeo.representation.xmir.XmlNode;
-import org.eolang.opeo.ast.Add;
+import org.eolang.opeo.ast.Addition;
import org.eolang.opeo.ast.Attributes;
import org.eolang.opeo.ast.Field;
import org.eolang.opeo.ast.FieldAssignment;
@@ -70,7 +70,7 @@ void convertsOpcodesAsIs() {
@Test
void convertsAddition() {
final List nodes = new XmirParser(
- new Add(new Literal(1), new Literal(2))
+ new Addition(new Literal(1), new Literal(2))
).toJeoNodes();
MatcherAssert.assertThat(
String.format(
@@ -96,12 +96,12 @@ void convertsDeepAddition() {
MatcherAssert.assertThat(
"We expect to retrieve 7 opcodes, but got something else instead",
new XmirParser(
- new Add(
- new Add(
+ new Addition(
+ new Addition(
new Literal(1),
new Literal(2)
),
- new Add(
+ new Addition(
new Literal(3),
new Literal(4)
)
diff --git a/src/test/java/org/eolang/opeo/decompilation/DecompilerMachineTest.java b/src/test/java/org/eolang/opeo/decompilation/DecompilerMachineTest.java
index e24ffeb7..1db3a020 100644
--- a/src/test/java/org/eolang/opeo/decompilation/DecompilerMachineTest.java
+++ b/src/test/java/org/eolang/opeo/decompilation/DecompilerMachineTest.java
@@ -29,7 +29,7 @@
import org.eolang.jeo.representation.xmir.AllLabels;
import org.eolang.opeo.LabelInstruction;
import org.eolang.opeo.OpcodeInstruction;
-import org.eolang.opeo.ast.Add;
+import org.eolang.opeo.ast.Addition;
import org.eolang.opeo.ast.ArrayConstructor;
import org.eolang.opeo.ast.AstNode;
import org.eolang.opeo.ast.Attributes;
@@ -243,22 +243,23 @@ void decompilesInvokeVirtual() {
@Test
void decompilesArrayCreation() throws ImpossibleModificationException {
final String type = "java/lang/Object";
+ final String xml = new Xembler(
+ new DecompilerMachine()
+ .decompile(
+ new OpcodeInstruction(Opcodes.ICONST_2),
+ new OpcodeInstruction(Opcodes.ICONST_3),
+ new OpcodeInstruction(Opcodes.IADD),
+ new OpcodeInstruction(Opcodes.ANEWARRAY, type)
+ )
+ ).xml();
MatcherAssert.assertThat(
"Can't decompile array creation",
- new Xembler(
- new DecompilerMachine()
- .decompile(
- new OpcodeInstruction(Opcodes.ICONST_2),
- new OpcodeInstruction(Opcodes.ICONST_3),
- new OpcodeInstruction(Opcodes.IADD),
- new OpcodeInstruction(Opcodes.ANEWARRAY, type)
- )
- ).xml(),
+ xml,
new SameXml(
new Xembler(
new Root(
new ArrayConstructor(
- new Add(new Literal(2), new Literal(3)),
+ new Addition(new Literal(2), new Literal(3)),
type
)
).toXmir()
@@ -317,7 +318,7 @@ void decompilesVariableAssignment() {
),
new VariableAssignment(
new LocalVariable(2, Type.INT_TYPE),
- new Add(
+ new Addition(
new LocalVariable(2, Type.INT_TYPE),
new Literal(2)
)
diff --git a/src/test/java/org/eolang/opeo/decompilation/SelectiveDecompilerTest.java b/src/test/java/org/eolang/opeo/decompilation/SelectiveDecompilerTest.java
index d00db47b..bb9753da 100644
--- a/src/test/java/org/eolang/opeo/decompilation/SelectiveDecompilerTest.java
+++ b/src/test/java/org/eolang/opeo/decompilation/SelectiveDecompilerTest.java
@@ -26,7 +26,7 @@
import java.util.stream.Collectors;
import org.cactoos.io.ResourceOf;
import org.eolang.opeo.SelectiveDecompiler;
-import org.eolang.opeo.decompilation.handlers.RouterHandler;
+import org.eolang.opeo.decompilation.agents.AllAgents;
import org.eolang.opeo.storage.InMemoryStorage;
import org.eolang.opeo.storage.XmirEntry;
import org.hamcrest.MatcherAssert;
@@ -161,7 +161,7 @@ void avoidsDecompileLargeFileWithUnknownDependencies() {
void identifiesUnsupportedOpcodes() {
MatcherAssert.assertThat(
"We expect that the supported opcodes won't contain the 'GOTO' opcode since we don't support it yet.",
- new RouterHandler(false).supportedOpcodes(),
+ new AllAgents(false).supportedOpcodes(),
Matchers.not(Matchers.arrayContaining("GOTO"))
);
}