// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

package com.android.tools.r8.rewrite.assertions;

import static com.android.tools.r8.KotlinCompilerTool.KOTLINC;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.AssertionsConfiguration;
import com.android.tools.r8.D8TestBuilder;
import com.android.tools.r8.KotlinTestBase;
import com.android.tools.r8.R8FullTestBuilder;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.ThrowableConsumer;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.ToolHelper.KotlinTargetVersion;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.ThrowingConsumer;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.InstructionSubject;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import com.google.common.collect.ImmutableList;
import java.nio.file.Path;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.junit.Assume;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

@RunWith(Parameterized.class)
public class AssertionConfigurationKotlinTest extends KotlinTestBase implements Opcodes {

  private static class KotlinCompilationKey {
    KotlinTargetVersion targetVersion;
    boolean useJvmAssertions;

    private KotlinCompilationKey(KotlinTargetVersion targetVersion, boolean useJvmAssertions) {
      this.targetVersion = targetVersion;
      this.useJvmAssertions = useJvmAssertions;
    }

    @Override
    public int hashCode() {
      return Objects.hash(targetVersion, useJvmAssertions);
    }

    @Override
    public boolean equals(Object other) {
      if (other == null) {
        return false;
      }
      if (getClass() != other.getClass()) {
        return false;
      }
      KotlinCompilationKey kotlinCompilationKey = (KotlinCompilationKey) other;
      return targetVersion == kotlinCompilationKey.targetVersion
          && useJvmAssertions == kotlinCompilationKey.useJvmAssertions;
    }
  }

  private static final Package pkg = AssertionConfigurationKotlinTest.class.getPackage();
  private static final String kotlintestclasesPackage = pkg.getName() + ".kotlintestclasses";
  private static final String testClassKt = kotlintestclasesPackage + ".TestClassKt";
  private static final String class1 = kotlintestclasesPackage + ".Class1";
  private static final String class2 = kotlintestclasesPackage + ".Class2";

  private static final Map<KotlinCompilationKey, Path> kotlinClasses = new HashMap<>();
  private final TestParameters parameters;
  private final boolean kotlinStdlibAsLibrary;
  private final boolean useJvmAssertions;
  private final KotlinCompilationKey kotlinCompilationKey;

  @Parameterized.Parameters(name = "{0}, {1}, kotlin-stdlib as library: {2}, -Xassertions=jvm: {3}")
  public static Collection<Object[]> data() {
    return buildParameters(
        getTestParameters().withAllRuntimesAndApiLevels().build(),
        KotlinTargetVersion.values(),
        BooleanUtils.values(),
        BooleanUtils.values());
  }

  public AssertionConfigurationKotlinTest(
      TestParameters parameters,
      KotlinTargetVersion targetVersion,
      boolean kotlinStdlibAsClasspath,
      boolean useJvmAssertions) {
    super(targetVersion);
    this.parameters = parameters;
    this.kotlinStdlibAsLibrary = kotlinStdlibAsClasspath;
    this.useJvmAssertions = useJvmAssertions;
    this.kotlinCompilationKey = new KotlinCompilationKey(targetVersion, useJvmAssertions);
  }

  @BeforeClass
  public static void compileKotlin() throws Exception {
    for (KotlinTargetVersion targetVersion : KotlinTargetVersion.values()) {
      for (boolean useJvmAssertions : BooleanUtils.values()) {
        Path ktClasses =
            kotlinc(KOTLINC, targetVersion)
                .addSourceFiles(getKotlinFilesInTestPackage(pkg))
                .setUseJvmAssertions(useJvmAssertions)
                .compile();
        kotlinClasses.put(new KotlinCompilationKey(targetVersion, useJvmAssertions), ktClasses);
      }
    }
  }

  private Path kotlinStdlibLibraryForRuntime() throws Exception {
    Path kotlinStdlibCf = ToolHelper.getKotlinStdlibJar();
    if (parameters.getRuntime().isCf()) {
      return kotlinStdlibCf;
    }

    Path kotlinStdlibDex = temp.newFolder().toPath().resolve("kotlin-stdlib-dex.jar");
    testForD8()
        .addProgramFiles(kotlinStdlibCf)
        .setMinApi(parameters.getApiLevel())
        .compile()
        .writeToZip(kotlinStdlibDex);
    return kotlinStdlibDex;
  }

  private void runD8Test(
      ThrowableConsumer<D8TestBuilder> builderConsumer,
      ThrowingConsumer<CodeInspector, RuntimeException> inspector,
      List<String> outputLines)
      throws Exception {
    if (kotlinStdlibAsLibrary) {
      testForD8()
          .addClasspathFiles(ToolHelper.getKotlinStdlibJar())
          .addProgramFiles(kotlinClasses.get(kotlinCompilationKey))
          .setMinApi(parameters.getApiLevel())
          .apply(builderConsumer)
          .addRunClasspathFiles(kotlinStdlibLibraryForRuntime())
          .run(
              parameters.getRuntime(),
              getClass().getPackage().getName() + ".kotlintestclasses.TestClassKt")
          .inspect(inspector)
          .assertSuccessWithOutputLines(outputLines);
    } else {
      testForD8()
          .addProgramFiles(ToolHelper.getKotlinStdlibJar())
          .addProgramFiles(kotlinClasses.get(kotlinCompilationKey))
          .setMinApi(parameters.getApiLevel())
          .apply(builderConsumer)
          .run(
              parameters.getRuntime(),
              getClass().getPackage().getName() + ".kotlintestclasses.TestClassKt")
          .inspect(inspector)
          .assertSuccessWithOutputLines(outputLines);
    }
  }

  public void runR8Test(
      ThrowableConsumer<R8FullTestBuilder> builderConsumer,
      ThrowingConsumer<CodeInspector, RuntimeException> inspector,
      List<String> outputLines)
      throws Exception {
    runR8Test(builderConsumer, inspector, outputLines, false);
  }

  public void runR8Test(
      ThrowableConsumer<R8FullTestBuilder> builderConsumer,
      ThrowingConsumer<CodeInspector, RuntimeException> inspector,
      List<String> outputLines,
      boolean enableJvmAssertions)
      throws Exception {

    if (kotlinStdlibAsLibrary) {
      testForR8(parameters.getBackend())
          .addClasspathFiles(ToolHelper.getKotlinStdlibJar())
          .addProgramFiles(kotlinClasses.get(kotlinCompilationKey))
          .addKeepMainRule(testClassKt)
          .addKeepClassAndMembersRules(class1, class2)
          .setMinApi(parameters.getApiLevel())
          .apply(builderConsumer)
          .noMinification()
          .addRunClasspathFiles(kotlinStdlibLibraryForRuntime())
          .compile()
          .enableRuntimeAssertions(enableJvmAssertions)
          .run(parameters.getRuntime(), testClassKt)
          .inspect(inspector)
          .assertSuccessWithOutputLines(outputLines);
    } else {
      testForR8(parameters.getBackend())
          .addProgramFiles(ToolHelper.getKotlinStdlibJar())
          .addProgramFiles(kotlinClasses.get(kotlinCompilationKey))
          .addKeepMainRule(testClassKt)
          .addKeepClassAndMembersRules(class1, class2)
          .setMinApi(parameters.getApiLevel())
          .apply(builderConsumer)
          .noMinification()
          .allowDiagnosticWarningMessages()
          .compile()
          .assertAllWarningMessagesMatch(equalTo("Resource 'META-INF/MANIFEST.MF' already exists."))
          .enableRuntimeAssertions(enableJvmAssertions)
          .run(parameters.getRuntime(), testClassKt)
          .inspect(inspector)
          .assertSuccessWithOutputLines(outputLines);
    }
  }

  private List<String> allAssertionsExpectedLines() {
    return ImmutableList.of("AssertionError in Class1", "AssertionError in Class2", "DONE");
  }

  private List<String> noAllAssertionsExpectedLines() {
    return ImmutableList.of("DONE");
  }

  private void checkAssertionCodeRemoved(ClassSubject subject, boolean isR8) {
    assertThat(subject, isPresent());
    if (subject.getOriginalName().equals("kotlin._Assertions")) {
      assert !kotlinStdlibAsLibrary;
      // With R8 the static-put of the kotlin._Assertions.INSTANCE field is removed as well,
      // as is not used.
      assertEquals(
          (isR8 ? 0 : 1),
          subject
              .uniqueMethodWithName("<clinit>")
              .streamInstructions()
              .filter(InstructionSubject::isStaticPut)
              .count());
      assertFalse(
          subject
              .uniqueMethodWithName("<clinit>")
              .streamInstructions()
              .anyMatch(InstructionSubject::isConstNumber));
    } else {
      // The value of kotlin._Assertions.ENABLED is propagated from the assertions configuration
      // for the class kotlin._Assertions.
      assertFalse(
          subject
              .uniqueMethodWithName("m")
              .streamInstructions()
              .anyMatch(InstructionSubject::isThrow));
    }
  }

  private void checkAssertionCodeRemoved(CodeInspector inspector, String clazz, boolean isR8) {
    checkAssertionCodeRemoved(inspector.clazz(clazz), isR8);
  }

  private void checkAssertionCodeEnabled(ClassSubject subject, boolean isR8) {
    assertThat(subject, isPresent());
    if (subject.getOriginalName().equals("kotlin._Assertions")) {
      assert !kotlinStdlibAsLibrary;
      // With R8 the static-put of the kotlin._Assertions.INSTANCE field is removed as is not used.
      assertEquals(
          isR8 ? 1 : 2,
          subject
              .uniqueMethodWithName("<clinit>")
              .streamInstructions()
              .filter(InstructionSubject::isStaticPut)
              .count());
      assertTrue(
          subject
              .uniqueMethodWithName("<clinit>")
              .streamInstructions()
              .anyMatch(instruction -> instruction.isConstNumber(1)));
    } else {
      assertTrue(
          subject
              .uniqueMethodWithName("m")
              .streamInstructions()
              .anyMatch(InstructionSubject::isThrow));
    }
  }

  private void checkAssertionCodeEnabled(CodeInspector inspector, String clazz, boolean isR8) {

    checkAssertionCodeEnabled(inspector.clazz(clazz), isR8);
  }

  private void checkAssertionCodeLeft(CodeInspector inspector, String clazz, boolean isR8) {
    ClassSubject subject = inspector.clazz(clazz);
    if (clazz.equals("kotlin._Assertions")) {
      assert !kotlinStdlibAsLibrary;
      if (isR8 && useJvmAssertions) {
        // When JVM assertions are used the class kotlin._Assertions is unused.
        assertThat(subject, not(isPresent()));
        return;
      }
      assertThat(subject, isPresent());
      // With R8 the static-put of the kotlin._Assertions.INSTANCE field is removed as is not used.
      assertEquals(
          isR8 ? 1 : 2,
          subject
              .uniqueMethodWithName("<clinit>")
              .streamInstructions()
              .filter(InstructionSubject::isStaticPut)
              .count());
      assertFalse(
          subject
              .uniqueMethodWithName("<clinit>")
              .streamInstructions()
              .anyMatch(InstructionSubject::isConstNumber));
    } else {
      assertThat(subject, isPresent());
      MethodSubject clinit = subject.uniqueMethodWithName("<clinit>");
      if (useJvmAssertions) {
        assertTrue(clinit.streamInstructions().anyMatch(InstructionSubject::isStaticPut));
      } else {
        assertThat(clinit, not(isPresent()));
      }
      assertTrue(
          subject
              .uniqueMethodWithName("m")
              .streamInstructions()
              .anyMatch(InstructionSubject::isThrow));
    }
  }

  private void checkAssertionCodeRemoved(CodeInspector inspector, boolean isR8) {
    if (isR8) {
      assertThat(inspector.clazz("kotlin._Assertions"), not(isPresent()));
    } else if (!kotlinStdlibAsLibrary) {
      checkAssertionCodeRemoved(inspector, "kotlin._Assertions", isR8);
    }
    checkAssertionCodeRemoved(inspector, class1, isR8);
    checkAssertionCodeRemoved(inspector, class2, isR8);
  }

  private void checkAssertionCodeEnabled(CodeInspector inspector, boolean isR8) {
    if (isR8) {
      assertThat(inspector.clazz("kotlin._Assertions"), not(isPresent()));
    } else if (!kotlinStdlibAsLibrary) {
      checkAssertionCodeEnabled(inspector, "kotlin._Assertions", isR8);
    }
    checkAssertionCodeEnabled(inspector, class1, isR8);
    checkAssertionCodeEnabled(inspector, class2, isR8);
  }

  private void checkAssertionCodeLeft(CodeInspector inspector, boolean isR8) {
    if (!kotlinStdlibAsLibrary) {
      checkAssertionCodeLeft(inspector, "kotlin._Assertions", isR8);
    }
    checkAssertionCodeLeft(inspector, class1, isR8);
    checkAssertionCodeLeft(inspector, class2, isR8);
  }

  @Test
  public void testAssertionsForDex() throws Exception {
    Assume.assumeTrue(parameters.isDexRuntime());
    // Leaving assertions in or disabling them on Dalvik/Art means no assertions.
    runD8Test(
        builder ->
            builder.addAssertionsConfiguration(
                AssertionsConfiguration.Builder::passthroughAllAssertions),
        inspector -> checkAssertionCodeLeft(inspector, false),
        noAllAssertionsExpectedLines());
    runR8Test(
        builder ->
            builder.addAssertionsConfiguration(
                AssertionsConfiguration.Builder::passthroughAllAssertions),
        inspector -> checkAssertionCodeLeft(inspector, true),
        noAllAssertionsExpectedLines());
    runD8Test(
        builder ->
            builder.addAssertionsConfiguration(
                AssertionsConfiguration.Builder::disableAllAssertions),
        inspector -> checkAssertionCodeRemoved(inspector, false),
        noAllAssertionsExpectedLines());
    runR8Test(
        builder ->
            builder.addAssertionsConfiguration(
                AssertionsConfiguration.Builder::disableAllAssertions),
        inspector -> checkAssertionCodeRemoved(inspector, true),
        noAllAssertionsExpectedLines());
    // Compile time enabling assertions gives assertions on Dalvik/Art.
    runD8Test(
        builder ->
            builder.addAssertionsConfiguration(
                AssertionsConfiguration.Builder::enableAllAssertions),
        inspector -> checkAssertionCodeEnabled(inspector, false),
        allAssertionsExpectedLines());
    runR8Test(
        builder ->
            builder.addAssertionsConfiguration(
                AssertionsConfiguration.Builder::enableAllAssertions),
        inspector -> checkAssertionCodeEnabled(inspector, true),
        allAssertionsExpectedLines());
    if (useJvmAssertions) {
      // Enabling for the kotlin generated Java classes should enable all.
      runD8Test(
          builder ->
              builder
                  .addAssertionsConfiguration(b -> b.setEnable().setScopeClass(class1).build())
                  .addAssertionsConfiguration(b -> b.setEnable().setScopeClass(class2).build()),
          inspector -> {
            // The default is applied to kotlin._Assertions (which for DEX is remove).
            if (!kotlinStdlibAsLibrary) {
              checkAssertionCodeRemoved(inspector, "kotlin._Assertions", false);
            }
            checkAssertionCodeEnabled(inspector, class1, false);
            checkAssertionCodeEnabled(inspector, class2, false);
          },
          allAssertionsExpectedLines());
    } else {
      // Enabling for the class kotlin._Assertions should enable all.
      runD8Test(
          builder ->
              builder.addAssertionsConfiguration(
                  b -> b.setEnable().setScopeClass("kotlin._Assertions").build()),
          inspector -> checkAssertionCodeEnabled(inspector, false),
          allAssertionsExpectedLines());
    }
    if (useJvmAssertions) {
      // Enabling for the kotlin generated Java classes should enable all.
      runR8Test(
          builder ->
              builder
                  .addAssertionsConfiguration(b -> b.setEnable().setScopeClass(class1).build())
                  .addAssertionsConfiguration(b -> b.setEnable().setScopeClass(class2).build()),
          inspector -> checkAssertionCodeEnabled(inspector, true),
          allAssertionsExpectedLines());
    } else {
      // Enabling for the class kotlin._Assertions should enable all.
      runR8Test(
          builder ->
              builder.addAssertionsConfiguration(
                  b -> b.setEnable().setScopeClass("kotlin._Assertions").build()),
          inspector -> checkAssertionCodeEnabled(inspector, true),
          allAssertionsExpectedLines());
    }
    if (useJvmAssertions) {
      // Enabling for the Java package for the kotlin test classes package should enable all.
      runD8Test(
          builder ->
              builder.addAssertionsConfiguration(
                  b -> b.setEnable().setScopePackage(kotlintestclasesPackage).build()),
          inspector -> {
            // The default is applied to kotlin._Assertions (which for DEX is remove).
            if (!kotlinStdlibAsLibrary) {
              checkAssertionCodeRemoved(inspector, "kotlin._Assertions", false);
            }
            checkAssertionCodeEnabled(inspector, class1, false);
            checkAssertionCodeEnabled(inspector, class2, false);
          },
          allAssertionsExpectedLines());
    } else {
      // Enabling for the kotlin package (containing kotlin._Assertions) should enable all.
      runD8Test(
          builder ->
              builder.addAssertionsConfiguration(
                  b -> b.setEnable().setScopePackage("kotlin").build()),
          inspector -> checkAssertionCodeEnabled(inspector, false),
          allAssertionsExpectedLines());
    }
    if (useJvmAssertions) {
      // Enabling for the Java package for the kotlin test classes package should enable all.
      runR8Test(
          builder ->
              builder.addAssertionsConfiguration(
                  b -> b.setEnable().setScopePackage(kotlintestclasesPackage).build()),
          inspector -> checkAssertionCodeEnabled(inspector, true),
          allAssertionsExpectedLines());
    } else {
      // Enabling for the kotlin package (containing kotlin._Assertions) should enable all.
      runR8Test(
          builder ->
              builder.addAssertionsConfiguration(
                  b -> b.setEnable().setScopePackage("kotlin").build()),
          inspector -> checkAssertionCodeEnabled(inspector, true),
          allAssertionsExpectedLines());
    }
  }

  @Test
  public void testAssertionsForCf() throws Exception {
    Assume.assumeTrue(parameters.isCfRuntime());
    // Leaving assertion code means assertions are controlled by the -ea flag.
    runR8Test(
        builder ->
            builder.addAssertionsConfiguration(
                AssertionsConfiguration.Builder::passthroughAllAssertions),
        inspector -> checkAssertionCodeLeft(inspector, true),
        noAllAssertionsExpectedLines());
    runR8Test(
        builder ->
            builder.addAssertionsConfiguration(
                AssertionsConfiguration.Builder::passthroughAllAssertions),
        inspector -> checkAssertionCodeLeft(inspector, true),
        allAssertionsExpectedLines(),
        true);
    // Compile time enabling or disabling assertions means the -ea flag has no effect.
    runR8Test(
        builder ->
            builder.addAssertionsConfiguration(
                AssertionsConfiguration.Builder::enableAllAssertions),
        inspector -> checkAssertionCodeEnabled(inspector, true),
        allAssertionsExpectedLines());
    runR8Test(
        builder ->
            builder.addAssertionsConfiguration(
                AssertionsConfiguration.Builder::enableAllAssertions),
        inspector -> checkAssertionCodeEnabled(inspector, true),
        allAssertionsExpectedLines(),
        true);
    runR8Test(
        builder ->
            builder.addAssertionsConfiguration(
                AssertionsConfiguration.Builder::disableAllAssertions),
        inspector -> checkAssertionCodeRemoved(inspector, true),
        noAllAssertionsExpectedLines());
    runR8Test(
        builder ->
            builder.addAssertionsConfiguration(
                AssertionsConfiguration.Builder::disableAllAssertions),
        inspector -> checkAssertionCodeRemoved(inspector, true),
        noAllAssertionsExpectedLines(),
        true);
  }

  @Test
  public void TestWithModifiedKotlinAssertions() throws Exception {
    Assume.assumeTrue(parameters.isDexRuntime());
    testForD8()
        .addProgramClassFileData(dumpModifiedKotlinAssertions())
        .addProgramFiles(kotlinClasses.get(kotlinCompilationKey))
        .setMinApi(parameters.getApiLevel())
        .addAssertionsConfiguration(AssertionsConfiguration.Builder::passthroughAllAssertions)
        .run(
            parameters.getRuntime(),
            getClass().getPackage().getName() + ".kotlintestclasses.TestClassKt")
        .assertSuccessWithOutputLines(noAllAssertionsExpectedLines());
    testForD8()
        .addProgramClassFileData(dumpModifiedKotlinAssertions())
        .addProgramFiles(kotlinClasses.get(kotlinCompilationKey))
        .setMinApi(parameters.getApiLevel())
        .addAssertionsConfiguration(AssertionsConfiguration.Builder::enableAllAssertions)
        .run(
            parameters.getRuntime(),
            getClass().getPackage().getName() + ".kotlintestclasses.TestClassKt")
        .assertSuccessWithOutputLines(allAssertionsExpectedLines());
    testForD8()
        .addProgramClassFileData(dumpModifiedKotlinAssertions())
        .addProgramFiles(kotlinClasses.get(kotlinCompilationKey))
        .setMinApi(parameters.getApiLevel())
        .addAssertionsConfiguration(AssertionsConfiguration.Builder::disableAllAssertions)
        .run(
            parameters.getRuntime(),
            getClass().getPackage().getName() + ".kotlintestclasses.TestClassKt")
        .assertSuccessWithOutputLines(noAllAssertionsExpectedLines());
  }

  // Slightly modified version of kotlin._Assertions to hit all code paths in the assertion
  // rewriter. See "Code added" below.
  public static byte[] dumpModifiedKotlinAssertions() {

    ClassWriter classWriter = new ClassWriter(0);
    FieldVisitor fieldVisitor;
    MethodVisitor methodVisitor;

    classWriter.visit(
        V1_6,
        ACC_PUBLIC | ACC_FINAL | ACC_SUPER,
        "kotlin/_Assertions",
        null,
        "java/lang/Object",
        null);

    {
      fieldVisitor =
          classWriter.visitField(ACC_PUBLIC | ACC_FINAL | ACC_STATIC, "ENABLED", "Z", null, null);
      fieldVisitor.visitEnd();
    }
    {
      fieldVisitor =
          classWriter.visitField(
              ACC_PUBLIC | ACC_FINAL | ACC_STATIC, "INSTANCE", "Lkotlin/_Assertions;", null, null);
      fieldVisitor.visitEnd();
    }
    {
      methodVisitor =
          classWriter.visitMethod(
              ACC_PUBLIC | ACC_STATIC | ACC_SYNTHETIC | ACC_DEPRECATED,
              "ENABLED$annotations",
              "()V",
              null,
              null);
      methodVisitor.visitCode();
      methodVisitor.visitInsn(RETURN);
      methodVisitor.visitMaxs(0, 0);
      methodVisitor.visitEnd();
    }
    {
      methodVisitor = classWriter.visitMethod(ACC_PRIVATE, "<init>", "()V", null, null);
      methodVisitor.visitCode();
      methodVisitor.visitVarInsn(ALOAD, 0);
      methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
      methodVisitor.visitInsn(RETURN);
      methodVisitor.visitMaxs(1, 1);
      methodVisitor.visitEnd();
    }
    {
      methodVisitor = classWriter.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
      methodVisitor.visitCode();
      methodVisitor.visitTypeInsn(NEW, "kotlin/_Assertions");
      methodVisitor.visitInsn(DUP);
      methodVisitor.visitMethodInsn(INVOKESPECIAL, "kotlin/_Assertions", "<init>", "()V", false);
      methodVisitor.visitVarInsn(ASTORE, 0);
      methodVisitor.visitVarInsn(ALOAD, 0);
      methodVisitor.visitFieldInsn(
          PUTSTATIC, "kotlin/_Assertions", "INSTANCE", "Lkotlin/_Assertions;");

      // Code added (added an additional call to getClass().desiredAssertionStatus() which
      // result is not assigned to ENABLED).
      methodVisitor.visitVarInsn(ALOAD, 0);
      methodVisitor.visitMethodInsn(
          INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false);
      methodVisitor.visitMethodInsn(
          INVOKEVIRTUAL, "java/lang/Class", "desiredAssertionStatus", "()Z", false);
      methodVisitor.visitInsn(POP);
      // End code added.

      methodVisitor.visitVarInsn(ALOAD, 0);
      methodVisitor.visitMethodInsn(
          INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false);
      methodVisitor.visitMethodInsn(
          INVOKEVIRTUAL, "java/lang/Class", "desiredAssertionStatus", "()Z", false);
      methodVisitor.visitFieldInsn(PUTSTATIC, "kotlin/_Assertions", "ENABLED", "Z");
      methodVisitor.visitInsn(RETURN);
      methodVisitor.visitMaxs(2, 1);
      methodVisitor.visitEnd();
    }
    classWriter.visitEnd();

    return classWriter.toByteArray();
  }
}
