From 41d5420e5cb11c6043e703d3579341a16f62d379 Mon Sep 17 00:00:00 2001 From: volodya-lombrozo Date: Mon, 9 Sep 2024 17:20:31 +0300 Subject: [PATCH] feat(#636): fix all the code offences --- .../bytecode/BytecodeClass.java | 194 ++++++++---------- .../bytecode/BytecodeMethod.java | 2 +- .../bytecode/BytecodeMethodBuilder.java | 39 ++++ .../bytecode/BytecodeProgram.java | 7 +- .../jeo/representation/xmir/XmlAttribute.java | 7 +- .../jeo/representation/xmir/XmlClass.java | 3 +- .../jeo/representation/xmir/XmlMethod.java | 3 +- .../XmirRepresentationTest.java | 8 +- .../bytecode/BytecodeClassTest.java | 2 +- .../bytecode/BytecodeMethodTest.java | 3 +- .../DirectivesClassVisitorTest.java | 7 +- .../jeo/representation/xmir/XmlClassTest.java | 5 +- .../representation/xmir/XmlProgramTest.java | 37 ---- 13 files changed, 156 insertions(+), 161 deletions(-) diff --git a/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeClass.java b/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeClass.java index 63f5243b5..0aa3bffd5 100644 --- a/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeClass.java +++ b/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeClass.java @@ -28,7 +28,6 @@ import lombok.EqualsAndHashCode; import lombok.ToString; import org.eolang.jeo.representation.ClassName; -import org.eolang.jeo.representation.xmir.XmlAnnotations; import org.objectweb.asm.Opcodes; /** @@ -157,53 +156,8 @@ public BytecodeClass( this.props = props; } - /** - * Constructor. - * @return Class name. - */ - public String name() { - return this.name; - } - - /** - * Constructor. - * @param visitor Writer. - */ - void writeTo(final CustomClassWriter visitor, final String pckg) { - try { - visitor.visit( - this.props.version(), - this.props.access(), - new ClassName(pckg, this.name).full(), - this.props.signature(), - this.props.supername(), - this.props.interfaces() - ); - this.annotations.forEach(annotation -> annotation.write(visitor)); - this.fields.forEach(field -> field.write(visitor)); - this.methods.forEach(method -> method.write(visitor)); - this.attributes.forEach(attr -> attr.write(visitor)); - visitor.visitEnd(); - } catch (final IllegalArgumentException exception) { - throw new IllegalArgumentException( - String.format("Can't create bytecode for the class '%s' ", this.name), - exception - ); - } catch (final IllegalStateException exception) { - throw new IllegalStateException( - String.format( - "Bytecode creation for the '%s' class is not possible due to unmet preconditions. To reproduce the problem, you can write the following test: %n%s%n", - this.name, - this.testCode() - ), - exception - ); - } - } - /** * Add constructor. - * * @param modifiers Constructor modifiers. * @return This object. */ @@ -213,7 +167,6 @@ public BytecodeMethodBuilder withConstructor(final int... modifiers) { /** * Add method. - * * @param properties Method properties. * @return This object. */ @@ -223,20 +176,18 @@ public BytecodeMethodBuilder withMethod(final BytecodeMethodProperties propertie /** * Add method. - * - * @param props Method properties. + * @param properties Method properties. * @param maxs Method maxs. * @return This object. */ public BytecodeMethodBuilder withMethod( - final BytecodeMethodProperties props, final BytecodeMaxs maxs + final BytecodeMethodProperties properties, final BytecodeMaxs maxs ) { - return this.withMethod(new BytecodeMethod(props, maxs)); + return this.withMethod(new BytecodeMethod(properties, maxs)); } /** * Add constructor. - * * @param descriptor Constructor descriptor. * @param modifiers Constructor modifiers. * @return This object. @@ -245,33 +196,8 @@ public BytecodeMethodBuilder withConstructor(final String descriptor, final int. return this.withMethod("", descriptor, modifiers); } - /** - * Add method. - * - * @param mname Method name. - * @param descriptor Method descriptor. - * @param modifiers Access modifiers. - * @return This object. - */ - public BytecodeMethodBuilder withMethod( - final String mname, final String descriptor, final int... modifiers - ) { - return this.withMethod(new BytecodeMethod(mname, descriptor, modifiers)); - } - - /** - * Add method. - * @param method Method. - * @return This object. - */ - private BytecodeMethodBuilder withMethod(final BytecodeMethod method) { - this.methods.add(method); - return new BytecodeMethodBuilder(this, method); - } - /** * Add field. - * * @param fname Field name. * @return This object. */ @@ -287,40 +213,26 @@ public BytecodeClass withField(final String fname) { } /** - * Add attribute. - * @param attribute Attribute. + * Add method. + * @param mname Method name. + * @param descriptor Method descriptor. + * @param modifiers Access modifiers. * @return This object. */ - public BytecodeClass withAttribute(final BytecodeAttribute attribute) { - this.attributes.add(attribute); - return this; + public BytecodeMethodBuilder withMethod( + final String mname, final String descriptor, final int... modifiers + ) { + return this.withMethod(new BytecodeMethod(mname, descriptor, modifiers)); } /** - * Add field. - * - * @param fname Field name. - * @param descriptor Field descriptor. - * @param signature Field signature. - * @param value Field value. - * @param modifiers Access modifiers. + * Add attribute. + * @param attribute Attribute. * @return This object. - * @checkstyle ParameterNumberCheck (5 lines) */ - private BytecodeField withField( - final String fname, - final String descriptor, - final String signature, - final Object value, - final int... modifiers - ) { - int access = 0; - for (final int modifier : modifiers) { - access |= modifier; - } - final BytecodeField field = new BytecodeField(fname, descriptor, signature, value, access); - this.fields.add(field); - return field; + public BytecodeClass withAttribute(final BytecodeAttribute attribute) { + this.attributes.add(attribute); + return this; } @Override @@ -378,4 +290,78 @@ public BytecodeClass withoutMethods() { this.methods.clear(); return this; } + + /** + * Constructor. + * @param visitor Writer. + * @param pckg Package. + */ + void writeTo(final CustomClassWriter visitor, final String pckg) { + try { + visitor.visit( + this.props.version(), + this.props.access(), + new ClassName(pckg, this.name).full(), + this.props.signature(), + this.props.supername(), + this.props.interfaces() + ); + this.annotations.forEach(annotation -> annotation.write(visitor)); + this.fields.forEach(field -> field.write(visitor)); + this.methods.forEach(method -> method.write(visitor)); + this.attributes.forEach(attr -> attr.write(visitor)); + visitor.visitEnd(); + } catch (final IllegalArgumentException exception) { + throw new IllegalArgumentException( + String.format("Can't create bytecode for the class '%s' ", this.name), + exception + ); + } catch (final IllegalStateException exception) { + throw new IllegalStateException( + String.format( + "Bytecode creation for the '%s' class is not possible due to unmet preconditions. To reproduce the problem, you can write the following test: %n%s%n", + this.name, + this.testCode() + ), + exception + ); + } + } + + /** + * Add method. + * @param method Method. + * @return This object. + */ + private BytecodeMethodBuilder withMethod(final BytecodeMethod method) { + this.methods.add(method); + return new BytecodeMethodBuilder(this, method); + } + + /** + * Add field. + * + * @param fname Field name. + * @param descriptor Field descriptor. + * @param signature Field signature. + * @param value Field value. + * @param modifiers Access modifiers. + * @return This object. + * @checkstyle ParameterNumberCheck (5 lines) + */ + private BytecodeField withField( + final String fname, + final String descriptor, + final String signature, + final Object value, + final int... modifiers + ) { + int access = 0; + for (final int modifier : modifiers) { + access |= modifier; + } + final BytecodeField field = new BytecodeField(fname, descriptor, signature, value, access); + this.fields.add(field); + return field; + } } 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 3a7ceff7a..ebe0225a5 100644 --- a/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeMethod.java +++ b/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeMethod.java @@ -28,7 +28,6 @@ import lombok.EqualsAndHashCode; import lombok.ToString; import org.eolang.jeo.representation.xmir.AllLabels; -import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.Label; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; @@ -242,6 +241,7 @@ public String testCode() { /** * Generate bytecode. + * @param visitor Visitor. */ @SuppressWarnings("PMD.AvoidCatchingGenericException") void write(final CustomClassWriter visitor) { diff --git a/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeMethodBuilder.java b/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeMethodBuilder.java index 42520bbe9..5c6844f8c 100644 --- a/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeMethodBuilder.java +++ b/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeMethodBuilder.java @@ -1,12 +1,51 @@ +/* + * 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.jeo.representation.bytecode; import org.objectweb.asm.Label; +/** + * Bytecode method builder. + * @since 0.6 + */ public final class BytecodeMethodBuilder { + /** + * Class for the method. + */ private final BytecodeClass clazz; + + /** + * Bytecode method. + */ private final BytecodeMethod method; + /** + * Constructor. + * @param clazz Class. + * @param method Method. + */ public BytecodeMethodBuilder(final BytecodeClass clazz, final BytecodeMethod method) { this.clazz = clazz; this.method = method; diff --git a/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeProgram.java b/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeProgram.java index e27ccef1a..a2fc722ae 100644 --- a/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeProgram.java +++ b/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeProgram.java @@ -94,7 +94,7 @@ public BytecodeProgram(final String pckg, final List classes) { * @return XML representation of bytecode. */ public XML xml() { - return new BytecodeRepresentation(this.bytecode(true)).toEO(); + return new BytecodeRepresentation(this.bytecode()).toEO(); } /** @@ -116,6 +116,7 @@ public Bytecode bytecode() { /** * Traverse XML and build bytecode class. + * @param verify Verify bytecode. * @return Bytecode. */ public Bytecode bytecode(final boolean verify) { @@ -124,6 +125,10 @@ public Bytecode bytecode(final boolean verify) { return writer.bytecode(); } + /** + * Get top class. + * @return Top class. + */ public BytecodeClass top() { return this.classes.get(0); } diff --git a/src/main/java/org/eolang/jeo/representation/xmir/XmlAttribute.java b/src/main/java/org/eolang/jeo/representation/xmir/XmlAttribute.java index 7e3ab3b3e..9acdc68ae 100644 --- a/src/main/java/org/eolang/jeo/representation/xmir/XmlAttribute.java +++ b/src/main/java/org/eolang/jeo/representation/xmir/XmlAttribute.java @@ -63,8 +63,9 @@ public Optional attribute() { String.format("Attribute base is missing in XML node %s", this.node) ) ); + final Optional result; if ("inner-class".equals(base)) { - return Optional.of( + result = Optional.of( new BytecodeAttribute.InnerClass( Optional.ofNullable(this.node.children().collect(Collectors.toList()).get(0)) .map(XmlOperand::new) @@ -90,8 +91,10 @@ public Optional attribute() { .map(Integer.class::cast) .orElse(0) )); + } else { + result = Optional.empty(); } - return Optional.empty(); + return result; } /** diff --git a/src/main/java/org/eolang/jeo/representation/xmir/XmlClass.java b/src/main/java/org/eolang/jeo/representation/xmir/XmlClass.java index 75c2fa85f..c8ccf00b0 100644 --- a/src/main/java/org/eolang/jeo/representation/xmir/XmlClass.java +++ b/src/main/java/org/eolang/jeo/representation/xmir/XmlClass.java @@ -35,6 +35,7 @@ import org.eolang.jeo.representation.bytecode.BytecodeClass; import org.eolang.jeo.representation.directives.DirectivesClass; import org.eolang.jeo.representation.directives.DirectivesClassProperties; +import org.objectweb.asm.Opcodes; import org.w3c.dom.Node; import org.xembly.Transformers; import org.xembly.Xembler; @@ -186,7 +187,7 @@ private Optional attributes() { * @return Class node. */ private static Node empty(final String classname) { - return XmlClass.withProps(classname, new DirectivesClassProperties(0)); + return XmlClass.withProps(classname, new DirectivesClassProperties(Opcodes.ACC_PUBLIC)); } /** 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 0ad4706b4..6d23cea99 100644 --- a/src/main/java/org/eolang/jeo/representation/xmir/XmlMethod.java +++ b/src/main/java/org/eolang/jeo/representation/xmir/XmlMethod.java @@ -37,7 +37,6 @@ import org.eolang.jeo.representation.Signature; import org.eolang.jeo.representation.bytecode.BytecodeAnnotation; import org.eolang.jeo.representation.bytecode.BytecodeAnnotations; -import org.eolang.jeo.representation.bytecode.BytecodeClass; import org.eolang.jeo.representation.bytecode.BytecodeMaxs; import org.eolang.jeo.representation.bytecode.BytecodeMethod; import org.eolang.jeo.representation.bytecode.BytecodeMethodProperties; @@ -53,7 +52,7 @@ * * @since 0.1 */ -@SuppressWarnings("PMD.AvoidDuplicateLiterals") +@SuppressWarnings({"PMD.AvoidDuplicateLiterals", "PMD.TooManyMethods"}) @ToString @EqualsAndHashCode public final class XmlMethod { diff --git a/src/test/java/org/eolang/jeo/representation/XmirRepresentationTest.java b/src/test/java/org/eolang/jeo/representation/XmirRepresentationTest.java index 93da87210..75b980091 100644 --- a/src/test/java/org/eolang/jeo/representation/XmirRepresentationTest.java +++ b/src/test/java/org/eolang/jeo/representation/XmirRepresentationTest.java @@ -96,8 +96,7 @@ void returnsBytecodeRepresentationOfEo() { void returnsBytecodeRepresentationOfEoObjectWithFields() { final Bytecode expected = new BytecodeProgram(new BytecodeClass("Fields") .withField("foo") - ) - .bytecode(); + ).bytecode(); final Bytecode actual = new XmirRepresentation( new BytecodeRepresentation(expected).toEO() ).toBytecode(); @@ -110,10 +109,9 @@ void returnsBytecodeRepresentationOfEoObjectWithFields() { @Test void convertsHelloWordEoRepresentationIntoBytecode() { - final Bytecode expected =new BytecodeProgram( new BytecodeClass("Application") + final Bytecode expected = new BytecodeProgram(new BytecodeClass("Application") .helloWorldMethod() - ) - .bytecode(); + ).bytecode(); final Bytecode actual = new XmirRepresentation( new BytecodeRepresentation(expected).toEO() ).toBytecode(); diff --git a/src/test/java/org/eolang/jeo/representation/bytecode/BytecodeClassTest.java b/src/test/java/org/eolang/jeo/representation/bytecode/BytecodeClassTest.java index 201bd8ae2..f062c3ed7 100644 --- a/src/test/java/org/eolang/jeo/representation/bytecode/BytecodeClassTest.java +++ b/src/test/java/org/eolang/jeo/representation/bytecode/BytecodeClassTest.java @@ -37,7 +37,7 @@ * Test case for {@link org.eolang.jeo.representation.bytecode.BytecodeClass}. * @since 0.1 */ -@SuppressWarnings("PMD.ExcessiveMethodLength") +@SuppressWarnings({"PMD.ExcessiveMethodLength", "PMD.TooManyMethods"}) final class BytecodeClassTest { @Test diff --git a/src/test/java/org/eolang/jeo/representation/bytecode/BytecodeMethodTest.java b/src/test/java/org/eolang/jeo/representation/bytecode/BytecodeMethodTest.java index bc6683c9a..833c521de 100644 --- a/src/test/java/org/eolang/jeo/representation/bytecode/BytecodeMethodTest.java +++ b/src/test/java/org/eolang/jeo/representation/bytecode/BytecodeMethodTest.java @@ -41,5 +41,4 @@ void clearsMaxs() { Matchers.equalTo(new BytecodeMethod("foo")) ); } - -} \ No newline at end of file +} diff --git a/src/test/java/org/eolang/jeo/representation/directives/DirectivesClassVisitorTest.java b/src/test/java/org/eolang/jeo/representation/directives/DirectivesClassVisitorTest.java index 1e19c1433..fdf7c2b0a 100644 --- a/src/test/java/org/eolang/jeo/representation/directives/DirectivesClassVisitorTest.java +++ b/src/test/java/org/eolang/jeo/representation/directives/DirectivesClassVisitorTest.java @@ -41,8 +41,9 @@ final class DirectivesClassVisitorTest { @Test void parsesSimpleClassWithoutConstructor() throws ImpossibleModificationException { final DirectivesClassVisitor directives = new DirectivesClassVisitor(); - new ClassReader(new BytecodeProgram(new BytecodeClass()).bytecode().asBytes()).accept( - directives, 0); + new ClassReader( + new BytecodeProgram(new BytecodeClass()).bytecode().asBytes() + ).accept(directives, 0); MatcherAssert.assertThat( "Can't parse simple class without constructor", new Xembler(directives).xml(), @@ -57,7 +58,7 @@ void parsesSimpleClassWithMethod() throws ImpossibleModificationException { new ClassReader( new BytecodeProgram( new BytecodeClass(clazz) - .helloWorldMethod() + .helloWorldMethod() ).bytecode().asBytes() ).accept(directives, 0); final String xml = new Xembler(directives).xml(); diff --git a/src/test/java/org/eolang/jeo/representation/xmir/XmlClassTest.java b/src/test/java/org/eolang/jeo/representation/xmir/XmlClassTest.java index a69157980..5d3c7a99e 100644 --- a/src/test/java/org/eolang/jeo/representation/xmir/XmlClassTest.java +++ b/src/test/java/org/eolang/jeo/representation/xmir/XmlClassTest.java @@ -23,6 +23,7 @@ */ package org.eolang.jeo.representation.xmir; +import org.eolang.jeo.representation.bytecode.BytecodeClass; import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; @@ -44,8 +45,8 @@ void createsByName() { klass, expected ), - klass.bytecode().name(), - Matchers.equalTo(expected) + klass.bytecode(), + Matchers.equalTo(new BytecodeClass(expected)) ); } } diff --git a/src/test/java/org/eolang/jeo/representation/xmir/XmlProgramTest.java b/src/test/java/org/eolang/jeo/representation/xmir/XmlProgramTest.java index 554d8b944..a25d7f444 100644 --- a/src/test/java/org/eolang/jeo/representation/xmir/XmlProgramTest.java +++ b/src/test/java/org/eolang/jeo/representation/xmir/XmlProgramTest.java @@ -23,7 +23,6 @@ */ package org.eolang.jeo.representation.xmir; -import org.eolang.jeo.matchers.SameXml; import org.eolang.jeo.representation.ClassName; import org.eolang.jeo.representation.bytecode.BytecodeClass; import org.eolang.jeo.representation.bytecode.BytecodeProgram; @@ -38,40 +37,6 @@ */ final class XmlProgramTest { -// @Test -// void retrievesTopClass() { -// final String bar = "Bar"; -// final XmlProgram program = new XmlProgram(new ClassName(bar)); -// final XmlClass actual = program.top(); -// final XmlClass expected = new XmlClass(bar); -// MatcherAssert.assertThat( -// String.format( -// "Can't retrieve top-level class from program %s. Expected %s%n Actual %s%n", -// program, -// expected, -// actual -// ), -// actual.toXml().toString(), -// new SameXml(expected.toXml()) -// ); -// } -// -// @Test -// void retrievesPackage() { -// final String expected = "com.matrix.foobar"; -// final String actual = new XmlProgram(new ClassName(expected, "FooBar")).pckg(); -// MatcherAssert.assertThat( -// String.format( -// "Can't retrieve package from program %s. Expected %s%n Actual %s%n", -// expected, -// expected, -// actual -// ), -// actual, -// Matchers.equalTo(expected) -// ); -// } - @Test void convertsToBytecode() { final String pckg = "com.matrix.foobar"; @@ -86,7 +51,5 @@ void convertsToBytecode() { ) ) ); - } } -