1*3a22c0a3SAlix# Copyright 2022 Google LLC. All rights reserved. 2*3a22c0a3SAlix# 3*3a22c0a3SAlix# Licensed under the Apache License, Version 2.0 (the License); 4*3a22c0a3SAlix# you may not use this file except in compliance with the License. 5*3a22c0a3SAlix# You may obtain a copy of the License at 6*3a22c0a3SAlix# 7*3a22c0a3SAlix# http://www.apache.org/licenses/LICENSE-2.0 8*3a22c0a3SAlix# 9*3a22c0a3SAlix# Unless required by applicable law or agreed to in writing, software 10*3a22c0a3SAlix# distributed under the License is distributed on an "AS IS" BASIS, 11*3a22c0a3SAlix# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*3a22c0a3SAlix# See the License for the specific language governing permissions and 13*3a22c0a3SAlix# limitations under the License. 14*3a22c0a3SAlix 15*3a22c0a3SAlix"""kt_analysis""" 16*3a22c0a3SAlix 17*3a22c0a3SAlixload("//:visibility.bzl", "RULES_KOTLIN") 18*3a22c0a3SAlix 19*3a22c0a3SAlixvisibility(RULES_KOTLIN) 20*3a22c0a3SAlix 21*3a22c0a3SAlixdef _get_action(actions, mnemonic): 22*3a22c0a3SAlix """Get a specific action 23*3a22c0a3SAlix 24*3a22c0a3SAlix Args: 25*3a22c0a3SAlix actions: [List[Action]] 26*3a22c0a3SAlix mnemonic: [string] Identify the action whose args to search 27*3a22c0a3SAlix 28*3a22c0a3SAlix Returns: 29*3a22c0a3SAlix [Action|None] The arg value, or None if it couldn't be found 30*3a22c0a3SAlix """ 31*3a22c0a3SAlix menmonic_actions = [a for a in actions if a.mnemonic == mnemonic] 32*3a22c0a3SAlix if len(menmonic_actions) == 0: 33*3a22c0a3SAlix return None 34*3a22c0a3SAlix elif len(menmonic_actions) > 1: 35*3a22c0a3SAlix fail("Expected a single '%s' action" % mnemonic) 36*3a22c0a3SAlix 37*3a22c0a3SAlix return menmonic_actions[0] 38*3a22c0a3SAlix 39*3a22c0a3SAlixdef _get_all_args(action, arg_name, style = "trim"): 40*3a22c0a3SAlix """Gets values for all instances of an arg name from a specific action. 41*3a22c0a3SAlix 42*3a22c0a3SAlix Args: 43*3a22c0a3SAlix action: [Action|None] 44*3a22c0a3SAlix arg_name: [string] 45*3a22c0a3SAlix style: ["trim"|"next"|"list"] The style of commandline arg 46*3a22c0a3SAlix 47*3a22c0a3SAlix Returns: 48*3a22c0a3SAlix [list[string]|list[list[string]]|None] The list of matching arg values 49*3a22c0a3SAlix """ 50*3a22c0a3SAlix if not action: 51*3a22c0a3SAlix return [] 52*3a22c0a3SAlix 53*3a22c0a3SAlix args = action.argv 54*3a22c0a3SAlix matches = [(i, a) for (i, a) in enumerate(args) if a.startswith(arg_name)] 55*3a22c0a3SAlix 56*3a22c0a3SAlix result = [] 57*3a22c0a3SAlix for index, arg in matches: 58*3a22c0a3SAlix if style == "trim": 59*3a22c0a3SAlix result.append(arg[len(arg_name):]) 60*3a22c0a3SAlix elif style == "next": 61*3a22c0a3SAlix result.append(args[index + 1]) 62*3a22c0a3SAlix elif style == "list": 63*3a22c0a3SAlix sub_result = [] 64*3a22c0a3SAlix for i in range(index + 1, len(args)): 65*3a22c0a3SAlix if args[i].startswith("--"): 66*3a22c0a3SAlix break 67*3a22c0a3SAlix sub_result.append(args[i]) 68*3a22c0a3SAlix result.append(sub_result) 69*3a22c0a3SAlix else: 70*3a22c0a3SAlix fail("Unrecognized arg style '%s" % style) 71*3a22c0a3SAlix 72*3a22c0a3SAlix return result 73*3a22c0a3SAlix 74*3a22c0a3SAlixdef _get_arg(action, arg_name, style = "trim"): 75*3a22c0a3SAlix """Gets values for exactly one instance of an arg name from a specific action. 76*3a22c0a3SAlix 77*3a22c0a3SAlix Args: 78*3a22c0a3SAlix action: [Action|None] 79*3a22c0a3SAlix arg_name: [string] 80*3a22c0a3SAlix style: ["trim"|"next"|"list"] The style of commandline arg 81*3a22c0a3SAlix 82*3a22c0a3SAlix Returns: 83*3a22c0a3SAlix [string|list[string]|None] The arg value, or None if it couldn't be found 84*3a22c0a3SAlix """ 85*3a22c0a3SAlix results = _get_all_args(action, arg_name, style) 86*3a22c0a3SAlix 87*3a22c0a3SAlix if len(results) == 0: 88*3a22c0a3SAlix return None 89*3a22c0a3SAlix elif len(results) == 1: 90*3a22c0a3SAlix return results[0] 91*3a22c0a3SAlix else: 92*3a22c0a3SAlix fail("Expected a single '%s' arg" % arg_name) 93*3a22c0a3SAlix 94*3a22c0a3SAlixdef _check_endswith_test(ctx): 95*3a22c0a3SAlix name = ctx.label.name 96*3a22c0a3SAlix for i in range(0, 10): 97*3a22c0a3SAlix # TODO: Remove support for suffix digits 98*3a22c0a3SAlix if name.endswith(str(i)): 99*3a22c0a3SAlix name = name.removesuffix(str(i)) 100*3a22c0a3SAlix break 101*3a22c0a3SAlix if name.endswith("_test"): 102*3a22c0a3SAlix return 103*3a22c0a3SAlix 104*3a22c0a3SAlix fail("Analysis test names must end in '_test'") 105*3a22c0a3SAlix 106*3a22c0a3SAlixkt_analysis = struct( 107*3a22c0a3SAlix # go/keep-sorted start 108*3a22c0a3SAlix DEFAULT_LIST = ["__default__"], 109*3a22c0a3SAlix check_endswith_test = _check_endswith_test, 110*3a22c0a3SAlix get_action = _get_action, 111*3a22c0a3SAlix get_all_args = _get_all_args, 112*3a22c0a3SAlix get_arg = _get_arg, 113*3a22c0a3SAlix # go/keep-sorted end 114*3a22c0a3SAlix) 115