xref: /aosp_15_r20/tools/metalava/metalava-model/src/main/java/com/android/tools/metalava/model/CallableBody.kt (revision 115816f9299ab6ddd6b9673b81f34e707f6bacab)
1 /*
2  * Copyright (C) 2024 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 
17 package com.android.tools.metalava.model
18 
19 import com.android.tools.metalava.model.item.DefaultCodebase
20 import com.android.tools.metalava.reporter.FileLocation
21 
22 /**
23  * A lamda that given a [CallableItem] will create a [CallableBody] for it.
24  *
25  * This is called from within the constructor of the [CallableItem] and should not access any
26  * properties of [CallableItem] as they may not have been initialized. This should just store a
27  * reference for later use.
28  */
29 typealias CallableBodyFactory = (CallableItem) -> CallableBody
30 
31 /** Represents the body of a [CallableItem]. */
32 interface CallableBody {
33 
34     /**
35      * Return a duplicate of this instance to use by [callableItem] which will be in the same type
36      * of [Codebase] as this.
37      */
duplicatenull38     fun duplicate(callableItem: CallableItem): CallableBody
39 
40     /**
41      * Take a snapshot of this suitable for use by [callableItem] which will be in a
42      * [DefaultCodebase].
43      *
44      * At the moment this simply delegates to [duplicate] as there is no easy way to take a snapshot
45      * of the state.
46      */
47     fun snapshot(callableItem: CallableItem) = duplicate(callableItem)
48 
49     /**
50      * Finds uncaught exceptions actually thrown inside this body (as opposed to ones declared in
51      * the signature)
52      */
53     fun findThrownExceptions(): Set<ClassItem>
54 
55     /**
56      * Finds the locations within this where a `synchronized` statement may be visible because it
57      * locks either the instance on which the method is called or its class. e.g. `synchronized
58      * (this) {...}` or `synchronized (Class.class)`.
59      */
60     fun findVisiblySynchronizedLocations(): List<FileLocation>
61 
62     /**
63      * Called on a method whose return value is annotated with [typeDefAnnotation] of class
64      * [typeDefClass].
65      *
66      * This scans the body of the method, finds `return` statements and checks to make sure that if
67      * they use a constant that it is one of the constants in the type def, reporting any which are
68      * not.
69      */
70     fun verifyReturnedConstants(typeDefAnnotation: AnnotationItem, typeDefClass: ClassItem)
71 
72     companion object {
73         /** Indicates that the model does not provide [CallableBody] instances. */
74         val UNAVAILABLE =
75             object : CallableBody {
76                 override fun duplicate(callableItem: CallableItem) = this
77 
78                 override fun findThrownExceptions() = error("method body is unavailable")
79 
80                 /** Return an empty list as the method body is unavailable. */
81                 override fun findVisiblySynchronizedLocations() = emptyList<FileLocation>()
82 
83                 /** Do nothing. */
84                 override fun verifyReturnedConstants(
85                     typeDefAnnotation: AnnotationItem,
86                     typeDefClass: ClassItem
87                 ) {}
88             }
89 
90         /**
91          * A special [CallableBodyFactory] that returns [UNAVAILABLE].
92          *
93          * Used where there is no available body, e.g. text/turbine model, implicit default
94          * constructor, etc..
95          */
96         val UNAVAILABLE_FACTORY: CallableBodyFactory = { UNAVAILABLE }
97     }
98 }
99