1#!/usr/bin/env ruby 2# Copyright (c) 2021-2025 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 keywords 27 @keywords 28 end 29 30 def build_tree(keys) 31 tree = Hash.new() 32 offset = 0 33 34 while true 35 has_more = false 36 keys.each do |key| 37 if key.length < offset + 1 38 next 39 end 40 41 has_more = true 42 func_name = key[0..offset]; 43 if tree.has_key?(func_name) 44 tree[func_name].add(key[offset + 1]) 45 else 46 tree[func_name] = Set[key[offset + 1]] 47 end 48 end 49 50 if has_more 51 offset += 1 52 next 53 end 54 break 55 end 56 57 return tree 58 end 59 60 def wrap_data(data) 61 @extensions = Hash.new() 62 63 if !data || !data.extensions || !data.keywords 64 return 65 end 66 67 @keywords = data.keywords.map do |keyword| 68 keyword.string = keyword.name 69 keyword 70 end 71 72 data.extensions.each do |extension| 73 @extensions[extension.name] = Hash.new() 74 all_words = data.keywords.select do |desc| 75 s_kw = Set.new(desc&.keyword) 76 groups = [s_kw, Set.new(desc&.keyword_like), Set.new(desc&.custom_handler)] 77 groups.combination(2).each { |a,b| raise "Conflicting keyword type" unless (a & b).empty? } 78 79 active = Set.new(); 80 groups.each { |group| active.merge(group) } 81 82 raise "Unknown extension" unless active.subset?(Set.new(data.extensions.map { |ext| ext.name })) 83 active.include? extension.name 84 end 85 86 keywords = data.keywords.select do |desc| 87 desc&.keyword&.include? extension.name or desc&.custom_handler&.include? extension.name 88 end 89 90 @extensions[extension.name]['keywords'] = keywords 91 @extensions[extension.name]['keyword_starts'] = Set.new(keywords.map { |desc| desc.name[0] }) 92 @extensions[extension.name]['all_words'] = all_words 93 @extensions[extension.name]['all_word_starts'] = Set.new(all_words.map { |desc| desc.name[0] }) 94 @extensions[extension.name]['tree'] = build_tree(all_words.map { |desc| desc.name }) 95 end 96 end 97end 98 99def Gen.on_require(data) 100 Keywords.wrap_data(data) 101end 102 103