1#!/usr/bin/env ruby 2# Copyright (c) 2021-2024 Huawei Device Co., Ltd. 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15require 'ostruct' 16require 'set' 17require 'delegate' 18 19module Keywords 20 module_function 21 22 def extensions 23 @extensions 24 end 25 26 def build_tree(keys) 27 tree = Hash.new() 28 offset = 0 29 30 while true 31 has_more = false 32 keys.each do |key| 33 if key.length < offset + 1 34 next 35 end 36 37 has_more = true 38 func_name = key[0..offset]; 39 if tree.has_key?(func_name) 40 tree[func_name].add(key[offset + 1]) 41 else 42 tree[func_name] = Set[key[offset + 1]] 43 end 44 end 45 46 if has_more 47 offset += 1 48 next 49 end 50 break 51 end 52 53 return tree 54 end 55 56 def wrap_data(data) 57 @extensions = Hash.new() 58 59 if !data || !data.extensions || !data.keywords 60 return 61 end 62 63 data.extensions.each do |extension| 64 @extensions[extension.name] = Hash.new() 65 all_words = data.keywords.select do |desc| 66 s_kw = Set.new(desc&.keyword) 67 groups = [s_kw, Set.new(desc&.keyword_like), Set.new(desc&.custom_handler)] 68 groups.combination(2).each { |a,b| raise "Conflicting keyword type" unless (a & b).empty? } 69 70 active = Set.new(); 71 groups.each { |group| active.merge(group) } 72 73 raise "Unknown extension" unless active.subset?(Set.new(data.extensions.map { |ext| ext.name })) 74 active.include? extension.name 75 end 76 77 keywords = data.keywords.select do |desc| 78 desc&.keyword&.include? extension.name or desc&.custom_handler&.include? extension.name 79 end 80 81 @extensions[extension.name]['keywords'] = keywords 82 @extensions[extension.name]['keyword_starts'] = Set.new(keywords.map { |desc| desc.name[0] }) 83 @extensions[extension.name]['all_words'] = all_words 84 @extensions[extension.name]['all_word_starts'] = Set.new(all_words.map { |desc| desc.name[0] }) 85 @extensions[extension.name]['tree'] = build_tree(all_words.map { |desc| desc.name }) 86 end 87 end 88end 89 90def Gen.on_require(data) 91 Keywords.wrap_data(data) 92end 93 94