diff --git a/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeMethod.java b/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeMethod.java index 57f2bd0b9..4dea68cdf 100644 --- a/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeMethod.java +++ b/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeMethod.java @@ -89,6 +89,15 @@ public BytecodeMethod(final String name) { this(name, new BytecodeClass(), "()V", Opcodes.ACC_PUBLIC); } + /** + * Constructor. + * @param name Method name. + * @param maxs Max stack and locals. + */ + public BytecodeMethod(final String name, final BytecodeMaxs maxs) { + this(new BytecodeMethodProperties(name, "()V", "", 1), new BytecodeClass(), maxs); + } + /** * Constructor. * @param name Method name. @@ -244,6 +253,22 @@ public BytecodeMethod defvalue(final BytecodeDefaultValue defvalue) { return this; } + /** + * Similar method without maxs. + * @return Method without maxs. + */ + public BytecodeMethod withoutMaxs() { + return new BytecodeMethod( + this.clazz, + this.tryblocks, + this.instructions, + this.annotations, + this.properties, + this.defvalues, + new BytecodeMaxs() + ); + } + @Override @SuppressWarnings("PMD.InsufficientStringBufferDeclaration") public String testCode() { diff --git a/src/main/java/org/eolang/jeo/representation/xmir/XmlMethod.java b/src/main/java/org/eolang/jeo/representation/xmir/XmlMethod.java index 6ff91b81f..b75f837a5 100644 --- a/src/main/java/org/eolang/jeo/representation/xmir/XmlMethod.java +++ b/src/main/java/org/eolang/jeo/representation/xmir/XmlMethod.java @@ -45,8 +45,6 @@ import org.eolang.jeo.representation.directives.DirectivesMethod; import org.eolang.jeo.representation.directives.DirectivesMethodProperties; import org.objectweb.asm.Opcodes; -import org.xembly.Directives; -import org.xembly.ImpossibleModificationException; import org.xembly.Transformers; import org.xembly.Xembler; @@ -72,22 +70,6 @@ public final class XmlMethod { @EqualsAndHashCode.Exclude private final AllLabels labels; - /** - * Constructor. - */ - public XmlMethod() { - this("foo"); - } - - /** - * Constructor. - * - * @param name Method name. - */ - public XmlMethod(final String name) { - this(name, Opcodes.ACC_PUBLIC, "()V"); - } - /** * Constructor. * @@ -176,7 +158,7 @@ public String name() { * @return Instructions. */ @SafeVarargs - public final List instructions( + private final List instructions( final Predicate... predicates ) { return this.node.child("base", "seq") @@ -188,24 +170,12 @@ public final List instructions( .collect(Collectors.toList()); } - /** - * All the method instructions. - * - * @return Instructions. - */ - public List nodes() { - return this.node.child("base", "seq") - .child("base", "tuple") - .children() - .collect(Collectors.toList()); - } - /** * Method max stack and locals. * * @return Maxs. */ - Optional maxs() { + private Optional maxs() { return this.node.optchild("name", "maxs").map(XmlMaxs::new); } @@ -214,7 +184,7 @@ Optional maxs() { * * @return Properties. */ - BytecodeMethodProperties properties() { + private BytecodeMethodProperties properties() { return new BytecodeMethodProperties( this.access(), this.name(), @@ -225,109 +195,6 @@ BytecodeMethodProperties properties() { ); } - /** - * Checks if method is a constructor. - * - * @return True if method is a constructor. - */ - boolean isConstructor() { - return this.node.attribute("name").map(s -> s.contains("new")).orElse(false); - } - - /** - * Convert to Directives. - * @return Directives of this method. - */ - Directives toDirectives() { - return new Directives().add("o").append(Directives.copyOf(this.node.node())).up(); - } - - /** - * Clear max stack and max locals. - * - * @return Copy of the method without max stack and max locals. - */ - XmlMethod withoutMaxs() { - try { - return new XmlMethod( - new XmlNode( - new Xembler( - new Directives() - .xpath("./o[@name='maxs']") - .remove() - ).apply(this.node.node()) - ) - ); - } catch (final ImpossibleModificationException exception) { - throw new IllegalStateException( - String.format( - "Failed to remove maxs from a method '%s'", - this.node - ), - exception - ); - } - } - - /** - * Method instructions. - * - * @param entries Instructions to add. - * @return Copy of the method with added instructions. - */ - XmlMethod withInstructions(final XmlNode... entries) { - try { - final Directives directives = new Directives() - .xpath("./o[@base='seq']/o[@base='tuple']"); - for (final XmlNode entry : entries) { - directives.add("o").append(Directives.copyOf(entry.node())).up(); - } - return new XmlMethod( - new XmlNode( - new Xembler(directives).apply( - this.withoutInstructions().node.node() - ) - ) - ); - } catch (final ImpossibleModificationException exception) { - throw new IllegalStateException( - String.format( - "Failed to add instructions '%s' to a method '%s'", - Arrays.toString(entries), - this.node - ), - exception - ); - } - } - - /** - * Clear instructions. - * - * @return Method without instructions. - */ - XmlMethod withoutInstructions() { - try { - return new XmlMethod( - new XmlNode( - new Xembler( - new Directives() - .xpath("./o[@base='seq']/o[@base='tuple']/o") - .remove() - ).apply(this.node.node()) - ) - ); - } catch (final ImpossibleModificationException exception) { - throw new IllegalStateException( - String.format( - "Failed to remove instructions from a method '%s'", - this.node - ), - exception - ); - } - } - /** * Method access modifiers. * diff --git a/src/test/java/org/eolang/jeo/representation/xmir/XmlMethodTest.java b/src/test/java/org/eolang/jeo/representation/xmir/XmlMethodTest.java index 51897d2b8..c269d38cf 100644 --- a/src/test/java/org/eolang/jeo/representation/xmir/XmlMethodTest.java +++ b/src/test/java/org/eolang/jeo/representation/xmir/XmlMethodTest.java @@ -23,8 +23,6 @@ */ package org.eolang.jeo.representation.xmir; -import java.util.List; -import java.util.Optional; import org.eolang.jeo.representation.bytecode.BytecodeClass; import org.eolang.jeo.representation.bytecode.BytecodeMaxs; import org.eolang.jeo.representation.bytecode.BytecodeMethod; @@ -78,96 +76,23 @@ void retrievesMethodProperties() { final XmlMethod method = new XmlMethod(name, access, descriptor, exceptions); MatcherAssert.assertThat( "Method properties are not equal to expected", - method.properties(), + method.bytecode(new BytecodeClass()), Matchers.equalTo( - new BytecodeMethodProperties(access, name, descriptor, "", exceptions) + new BytecodeMethod( + new BytecodeMethodProperties(access, name, descriptor, "", exceptions), + new BytecodeClass(), + new BytecodeMaxs() + ) ) ); } - @Test - void createsMethodWithoutInstructions() { - MatcherAssert.assertThat( - "Method instructions are not empty", - new XmlMethod().instructions(), - Matchers.empty() - ); - } - - @Test - void addsInstructions() { - final XmlInstruction instruction = new XmlInstruction(Opcodes.LDC, "Bye world!"); - MatcherAssert.assertThat( - "Exactly one instruction should be added", - new XmlMethod().withInstructions(instruction.toNode()).instructions(), - Matchers.contains(instruction) - ); - } - - @Test - void replacesInstructions() { - final XmlInstruction first = new XmlInstruction(Opcodes.INVOKESPECIAL, 1); - final XmlInstruction second = new XmlInstruction(Opcodes.INVOKEVIRTUAL, 2); - final XmlMethod method = new XmlMethod().withInstructions( - new XmlInstruction(Opcodes.LDC, "Bye world!").toNode() - ).withInstructions( - first.toNode(), - second.toNode() - ); - MatcherAssert.assertThat( - "Exactly two instructions should be added", - method.instructions(), - Matchers.containsInAnyOrder(first, second) - ); - } - - @Test - void cleansInstructions() { - MatcherAssert.assertThat( - "Instructions should be cleaned", - new XmlMethod() - .withInstructions(new XmlInstruction(Opcodes.POP).toNode()) - .withoutInstructions() - .instructions(), - Matchers.empty() - ); - } - - @Test - void retrievesMethodNodes() { - final List nodes = new XmlMethod().withInstructions( - new XmlInstruction(Opcodes.LDC, "first").toNode(), - new XmlInstruction(Opcodes.LDC, "second").toNode(), - new XmlNode("") - ).nodes(); - MatcherAssert.assertThat( - "Exactly three node should be added. Pay attention, that the last node is custom xml node", - nodes, - Matchers.hasSize(3) - ); - } - @Test void createsMethodWithMaxStackAndMaxLocals() { - final Optional max = new XmlMethod(1, 2).maxs(); - MatcherAssert.assertThat( - "Max stack is not present", - max.isPresent(), - Matchers.is(true) - ); - MatcherAssert.assertThat( - "Max stack is not equal to expected", - max.get(), - Matchers.equalTo(new XmlMaxs(1, 2)) - ); - } - - @Test - void cleansMaxValues() { MatcherAssert.assertThat( - "Max values should be cleaned", - new XmlMethod(2, 1).withoutMaxs().maxs().isPresent(), - Matchers.is(false) + "We expect that max stack and max locals will be correctly parsed", + new XmlMethod(1, 2).bytecode(new BytecodeClass()), + Matchers.equalTo(new BytecodeMethod("foo", new BytecodeMaxs(1, 2))) ); } }