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.turbine
18 
19 import com.android.tools.metalava.model.ClassItem
20 import com.android.tools.metalava.reporter.FileLocation
21 import com.google.turbine.tree.Tree
22 import java.nio.file.Path
23 
24 /**
25  * A [FileLocation] that stores the [position] of the declaration in the [TurbineSourceFile] and
26  * uses that to generate the [path] and [line] as needed.
27  */
28 internal class TurbineFileLocation(
29     /**
30      * The [TurbineSourceFile] that contains the information needed to map the [position] to a line
31      * number.
32      */
33     private val sourceFile: TurbineSourceFile,
34     /** The position within the [sourceFile]. */
35     private val position: Int
36 ) : FileLocation() {
37 
38     override val path
39         get() = sourceFile.path
40 
41     override val line
42         get() = sourceFile.lineForPosition(position)
43 
44     companion object {
45         /** Get the [Path] for the [TurbineSourceFile]. */
46         private val TurbineSourceFile.path: Path
47             get() = Path.of(compUnit.source().path())
48 
49         /** Create a [FileLocation] for the [sourceFile]. */
forTreenull50         fun forTree(sourceFile: TurbineSourceFile?): FileLocation {
51             sourceFile ?: return UNKNOWN
52             return createLocation(sourceFile.path)
53         }
54 
55         /** Create a [FileLocation] for the position of [tree] inside the [sourceFile]. */
forTreenull56         fun forTree(sourceFile: TurbineSourceFile, tree: Tree?): FileLocation {
57             tree ?: return forTree(sourceFile)
58             return TurbineFileLocation(sourceFile, tree.position())
59         }
60 
61         /**
62          * Create a [FileLocation] for the position of [tree] inside the nested [classItem]'s
63          * [TurbineSourceFile].
64          */
forTreenull65         fun forTree(classItem: ClassItem, tree: Tree?): FileLocation {
66             val sourceFile = classItem.sourceFile() as? TurbineSourceFile ?: return UNKNOWN
67             return forTree(sourceFile, tree)
68         }
69     }
70 }
71