Skip to content

Commit

Permalink
feat(objectionary#636): hide most of the XmlMethod methods
Browse files Browse the repository at this point in the history
  • Loading branch information
volodya-lombrozo committed Sep 9, 2024
1 parent 4f2e23d commit fd11451
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 220 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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() {
Expand Down
139 changes: 3 additions & 136 deletions src/main/java/org/eolang/jeo/representation/xmir/XmlMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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.
*
Expand Down Expand Up @@ -176,7 +158,7 @@ public String name() {
* @return Instructions.
*/
@SafeVarargs
public final List<XmlBytecodeEntry> instructions(
private final List<XmlBytecodeEntry> instructions(
final Predicate<XmlBytecodeEntry>... predicates
) {
return this.node.child("base", "seq")
Expand All @@ -188,24 +170,12 @@ public final List<XmlBytecodeEntry> instructions(
.collect(Collectors.toList());
}

/**
* All the method instructions.
*
* @return Instructions.
*/
public List<XmlNode> nodes() {
return this.node.child("base", "seq")
.child("base", "tuple")
.children()
.collect(Collectors.toList());
}

/**
* Method max stack and locals.
*
* @return Maxs.
*/
Optional<XmlMaxs> maxs() {
private Optional<XmlMaxs> maxs() {
return this.node.optchild("name", "maxs").map(XmlMaxs::new);
}

Expand All @@ -214,7 +184,7 @@ Optional<XmlMaxs> maxs() {
*
* @return Properties.
*/
BytecodeMethodProperties properties() {
private BytecodeMethodProperties properties() {
return new BytecodeMethodProperties(
this.access(),
this.name(),
Expand All @@ -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.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<XmlNode> nodes = new XmlMethod().withInstructions(
new XmlInstruction(Opcodes.LDC, "first").toNode(),
new XmlInstruction(Opcodes.LDC, "second").toNode(),
new XmlNode("<o/>")
).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<XmlMaxs> 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)))
);
}
}

0 comments on commit fd11451

Please sign in to comment.