1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.hoststubgen.visitors 17 18 import com.android.hoststubgen.HostStubGenErrors 19 import com.android.hoststubgen.asm.ClassNodes 20 import com.google.common.truth.Truth.assertThat 21 import org.junit.Test 22 import org.objectweb.asm.Opcodes 23 import org.objectweb.asm.tree.ClassNode 24 import org.objectweb.asm.tree.MethodNode 25 26 class HelperTest { 27 @Test testCheckSubstitutionMethodCompatibilitynull28 fun testCheckSubstitutionMethodCompatibility() { 29 val errors = object : HostStubGenErrors() { 30 override fun onErrorFound(message: String) { 31 // Don't throw 32 } 33 } 34 35 val cn = ClassNode().apply { 36 name = "ClassName" 37 methods = ArrayList() 38 } 39 40 val descriptor = "()V" 41 42 val staticPublic = MethodNode().apply { 43 name = "staticPublic" 44 access = Opcodes.ACC_STATIC or Opcodes.ACC_PUBLIC 45 desc = descriptor 46 cn.methods.add(this) 47 } 48 49 val staticPrivate = MethodNode().apply { 50 name = "staticPrivate" 51 access = Opcodes.ACC_STATIC or Opcodes.ACC_PRIVATE 52 desc = descriptor 53 cn.methods.add(this) 54 } 55 56 val nonStaticPublic = MethodNode().apply { 57 name = "nonStaticPublic" 58 access = Opcodes.ACC_PUBLIC 59 desc = descriptor 60 cn.methods.add(this) 61 } 62 63 val nonStaticPProtected = MethodNode().apply { 64 name = "nonStaticPProtected" 65 access = 0 66 desc = descriptor 67 cn.methods.add(this) 68 } 69 70 val classes = ClassNodes().apply { 71 addClass(cn) 72 } 73 74 fun check(from: MethodNode?, to: MethodNode?, expected: Int) { 75 assertThat(checkSubstitutionMethodCompatibility( 76 classes, 77 cn.name, 78 (from?.name ?: "**nonexistentmethodname**"), 79 (to?.name ?: "**nonexistentmethodname**"), 80 descriptor, 81 errors, 82 )).isEqualTo(expected) 83 } 84 85 check(staticPublic, staticPublic, Opcodes.ACC_PUBLIC or Opcodes.ACC_STATIC) 86 check(staticPrivate, staticPrivate, Opcodes.ACC_PRIVATE or Opcodes.ACC_STATIC) 87 check(nonStaticPublic, nonStaticPublic, Opcodes.ACC_PUBLIC) 88 check(nonStaticPProtected, nonStaticPProtected, 0) 89 90 check(staticPublic, null, NOT_COMPATIBLE) 91 check(null, staticPublic, NOT_COMPATIBLE) 92 93 check(staticPublic, nonStaticPublic, NOT_COMPATIBLE) 94 check(nonStaticPublic, staticPublic, NOT_COMPATIBLE) 95 96 check(staticPublic, staticPrivate, Opcodes.ACC_PUBLIC or Opcodes.ACC_STATIC) 97 check(staticPrivate, staticPublic, Opcodes.ACC_PRIVATE or Opcodes.ACC_STATIC) 98 99 check(nonStaticPublic, nonStaticPProtected, Opcodes.ACC_PUBLIC) 100 check(nonStaticPProtected, nonStaticPublic, 0) 101 } 102 }