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.android.hoststubgen.asm.clearVisibility
21 import com.android.hoststubgen.asm.getVisibility
22 import com.android.hoststubgen.asm.isStatic
23
24 const val NOT_COMPATIBLE: Int = -1
25
26 /**
27 * Make sure substitution from and to methods have matching definition.
28 * (static-ness, etc)
29 *
30 * If the methods are compatible, return the "merged" [access] of the new method.
31 *
32 * If they are not compatible, returns [NOT_COMPATIBLE]
33 */
checkSubstitutionMethodCompatibilitynull34 fun checkSubstitutionMethodCompatibility(
35 classes: ClassNodes,
36 className: String,
37 fromMethodName: String, // the one with the annotation
38 toMethodName: String, // the one with either a "_host" or "$ravenwood" prefix. (typically)
39 descriptor: String,
40 errors: HostStubGenErrors,
41 ): Int {
42 val from = classes.findMethod(className, fromMethodName, descriptor)
43 if (from == null) {
44 errors.onErrorFound(
45 "Substitution-from method not found: $className.$fromMethodName$descriptor"
46 )
47 return NOT_COMPATIBLE
48 }
49 val to = classes.findMethod(className, toMethodName, descriptor)
50 if (to == null) {
51 // This shouldn't happen, because the visitor visited this method...
52 errors.onErrorFound(
53 "Substitution-to method not found: $className.$toMethodName$descriptor"
54 )
55 return NOT_COMPATIBLE
56 }
57
58 if (from.isStatic() != to.isStatic()) {
59 errors.onErrorFound(
60 "Substitution method must have matching static-ness: " +
61 "$className.$fromMethodName$descriptor"
62 )
63 return NOT_COMPATIBLE
64 }
65
66 // Return the substitution's access flag but with the original method's visibility.
67 return clearVisibility (to.access) or getVisibility(from.access)
68 }
69