class CodeGenerator
Constants
- TAB
Attributes
root_dir[RW]
types[RW]
Public Class Methods
new(types, root_dir)
click to toggle source
# File lib/code_generator/code_generator.rb, line 13 def initialize(types, root_dir) @types = types @root_dir = root_dir end
Public Instance Methods
generate_self_code()
click to toggle source
# File lib/code_generator/code_generator.rb, line 18 def generate_self_code generateModules(types) generateReadme(types) end
Private Instance Methods
checkComment(string, tabs = 1)
click to toggle source
# File lib/code_generator/code_generator.rb, line 208 def checkComment(string, tabs = 1) replacedString = "\n" tab = "" tabs.times do |i| tab << TAB end comment = "#" replacedString << "#{tab}#{comment} " symbolsWithSpace = "\\.|\\:|\\!|\\?|\\;" regxp = /([^#{symbolsWithSpace}])\n/ result = string result.gsub!(/\n+/, "\n") result.gsub!(/ \n/, "\n#{comment} ") result.gsub!(/(#{symbolsWithSpace})\s*\n/, "\\1#{replacedString}") result.gsub!(regxp, "\\1") "#{tab}# #{result}" end
checkContent(content)
click to toggle source
# File lib/code_generator/code_generator.rb, line 187 def checkContent(content) content.gsub!(/^([\s]+)# RESPONSE/, "\n\\1# RESPONSE") content.gsub(/<Optional>/i, '<Optional>') end
customTypes()
click to toggle source
# File lib/code_generator/code_generator.rb, line 192 def customTypes content = %{ - #### #{lib_prefix}MnemonicDictionary #{TAB}- case TON = 0 #{TAB}- case ENGLISH = 1 #{TAB}- case CHINESE_SIMPLIFIED = 2 #{TAB}- case CHINESE_TRADITIONAL = 3 #{TAB}- case FRENCH = 4 #{TAB}- case ITALIAN = 5 #{TAB}- case JAPANESE = 6 #{TAB}- case KOREAN = 7 #{TAB}- case SPANISH = 8 } content end
gen_function(function, types)
click to toggle source
# File lib/code_generator/code_generator.rb, line 276 def gen_function(function, types) content = getFunctionComment(function, types) content << "#{TAB}#{TAB}def #{function.name}" if function.arguments.empty? content << "(&block)\n" content << "#{TAB}#{TAB}#{TAB}core.requestLibrary(context: context.id, method_name: full_method_name(MODULE, __method__.to_s), payload: {}, &block)\n" else content << "(payload, &block)\n" content << "#{TAB}#{TAB}#{TAB}core.requestLibrary(context: context.id, method_name: full_method_name(MODULE, __method__.to_s), payload: payload, &block)\n" end content << "#{TAB}#{TAB}end\n\n" content end
generateClientModule(mod, modules)
click to toggle source
# File lib/code_generator/code_generator.rb, line 226 def generateClientModule(mod, modules) content = "module TonClient\n\n#{TAB}class #{mod.name.capitalize}\n#{TAB}#{TAB}include CommonInstanceHelpers\n\n" content << "#{TAB}#{TAB}attr_reader :core, :context\n" content << "#{TAB}#{TAB}private_accessor " modules.each_with_index do |m, i| next if m.name.downcase == 'client' content << ((modules.size - 1) == i ? ":_#{m.name}\n" : ":_#{m.name}, ") end content << "#{TAB}#{TAB}MODULE = self.to_s.downcase.gsub(/^(.+::|)(\\w+)$/, '\\2').freeze\n\n" content << "#{TAB}#{TAB}def initialize(context: Context.new, core: TonClient::TonBinding)\n" content << "#{TAB}#{TAB}#{TAB}@context = context\n" content << "#{TAB}#{TAB}#{TAB}@core = core\n#{TAB}#{TAB}end\n\n" content << "#{TAB}#{TAB}def destroy_context\n" content << "#{TAB}#{TAB}#{TAB}core.tc_destroy_context(context.id)\n#{TAB}#{TAB}end\n\n" modules.each_with_index do |m, i| next if m.name.downcase == 'client' content << "#{TAB}#{TAB}def #{m.name}\n" content << "#{TAB}#{TAB}#{TAB}_#{m.name} ||= #{m.name.capitalize}.new(context: context)\n" content << "#{TAB}#{TAB}end\n\n" end mod.functions.each do |func| content << gen_function(func, types) end content << "#{TAB}end\n" content << "end\n\n" content end
generateModule(mod)
click to toggle source
# File lib/code_generator/code_generator.rb, line 257 def generateModule(mod) content = "module TonClient\n\n#{TAB}class #{mod.name.capitalize}\n#{TAB}#{TAB}include CommonInstanceHelpers\n\n" content << "#{TAB}#{TAB}attr_reader :core, :context\n" content << "#{TAB}#{TAB}MODULE = self.to_s.downcase.gsub(/^(.+::|)(\\w+)$/, '\\2').freeze\n\n" content << "#{TAB}#{TAB}def initialize(context: Context.new, core: TonClient::TonBinding)\n" content << "#{TAB}#{TAB}#{TAB}@context = context\n" content << "#{TAB}#{TAB}#{TAB}@core = core\n" content << "#{TAB}#{TAB}end\n\n" mod.functions.each do |func| content << gen_function(func, types) end content << "#{TAB}end\n" content << "end\n\n" content end
generateModules(types)
click to toggle source
# File lib/code_generator/code_generator.rb, line 25 def generateModules(types) types.modules.each do |mod| modulesFolder = root_dir + "/lib/ton-client-ruby/Client" moduleFilePath = "#{modulesFolder}/#{mod.name.capitalize}.rb" newModuleContent = "" if mod.name == "client" newModuleContent = generateClientModule(mod, types.modules) else newModuleContent = generateModule(mod) end if File.exists?(moduleFilePath) File.delete(moduleFilePath) end File.open(moduleFilePath, 'w+') { |f| f.write(newModuleContent) } end p 'generate_self_code ok' end
generateReadme(types)
click to toggle source
# File lib/code_generator/code_generator.rb, line 44 def generateReadme(types) readmePath = root_dir + "/README.md" content = %{ # Ruby Client for Free TON SDK [](https://rubygems.org/gems/ton-client-ruby) [](https://github.com/tonlabs/TON-SDK) ## Install Install gem ```bash gem install ton-client-ruby ``` Install TON-SDK ```bash ton-client-ruby setup # result - path to dylib file for ton-client-ruby configuration ``` ### Manual build FreeTON SDK 0. Install Rust to your OS 1. git clone https://github.com/tonlabs/TON-SDK 2. cd ./TON-SDK 3. cargo update 4. cargo build --release ## Usage ```ruby # For MAcOS TonClient.configure { |config| config.ffi_lib(./TON-SDK/target/release/libton_client.dylib) } # For Linux # TonClient.configure { |config| config.ffi_lib(./TON-SDK/target/release/libton_client.so) } client = TonClient.create(config: {network: {server_address: "net.ton.dev"}}) # All methods are asynchronous # example: call method for Crypto module payload = {composite: '17ED48941A08F981'} client.crypto.factorize(payload) do |response| p response.result['factors'] end # e.g. ... ```\n\n } content << "## All Modules, methods and types\n\n" # types content << "<details>\n#{TAB}<summary>Types</summary>\n\n" content << "#{customTypes()}\n" types.modules.each do |mod| (mod.enums || []).each do |type| content << checkComment(type.summary, 0) if type.summary content << checkComment(type.description, 0) if type.description content << "\n- #### #{type.name}\n" (type.cases || []).each do |enum_case| content << "#{checkComment(enum_case.summary, 1).gsub(/#/, '')}" if enum_case.summary content << "#{checkComment(enum_case.description, 1).gsub(/#/, '')}" if enum_case.description content << "#{TAB}- case #{enum_case.name} = #{enum_case.value}\n\n" end end (mod.types || []).each do |type| content << checkComment(type.summary, 0) if type.summary content << checkComment(type.description, 0) if type.description content << "\n- #### #{type.name}\n" (type.fields || []).each do |field| content << "#{checkComment(field.summary, 1).gsub(/#/, '')}\n" if field.summary content << "#{checkComment(field.description, 1).gsub(/#/, '')}\n" if field.description content << "#{TAB}- #{field.name}: #{field.type}\n\n" end end end content << "</details>\n\n" # methods types.modules.each do |mod| content << "<details>\n#{TAB}<summary>#{mod.name&.upcase}</summary>\n\n" (mod.functions || []).each do |function| content << "```ruby\n" content << checkComment(function.summary, 2) if function.summary content << checkComment(function.description, 2) if function.description content << "\n#{TAB}#{TAB}def #{function.name}" if function.arguments.empty? content << "(&block)\n" else content << "(payload, &block)\n" end content << getFunctionComment(function, types) content << "```\n" end content << "</details>\n\n" end content << %{ \n## Tests 1. create __.env.test__ file inside root directory of this library with variables example for NodeSE ``` spec_ffi=./TON-SDK/target/release/libton_client.dylib server_address=http://localhost:80 giver_abi_name=GiverNodeSE giver_amount=10000000000 ``` 2. Run tests: inside folder of this library execute this commands **rspec spec/binding.rb** **rspec spec/client.rb** **rspec spec/context.rb** **rspec spec/abi.rb** **rspec spec/boc.rb** **rspec spec/crypto.rb** **rspec spec/net.rb** **rspec spec/processing.rb** **rspec spec/tvm.rb** **rspec spec/utils.rb** \n## Update\n\n ```\n ton-client-ruby update\n ```\n\n or\n\n ```\n curl https://raw.githubusercontent.com/tonlabs/TON-SDK/master/tools/api.json > api.json\n\n ```\n\n ```\n ton-client-ruby update ./api.json\n ```\n } content = checkContent(content) if File.exists?(readmePath) File.delete(readmePath) end File.open(readmePath, 'w+') { |f| f.write(content) } end
getFunctionComment(function, types)
click to toggle source
# File lib/code_generator/code_generator.rb, line 291 def getFunctionComment(function, types) content = '' if argument = function.arguments.first content << "#{TAB}#{TAB}# INPUT: #{argument.type}\n" if types.all_types[argument.type].respond_to?(:fields) types.all_types[argument.type].fields.each do |arg| content << "#{TAB}#{TAB}# #{arg.name}: #{arg.type} - " content << "#{TAB}#{TAB}# #{checkComment(arg.summary, 2)}" if arg.summary content << "#{TAB}#{TAB}# #{checkComment(arg.description, 2)}" if arg.description content << "\n" end elsif types.all_types[argument.type].respond_to?(:cases) end end if types.all_types[function.result] content << "#{TAB}#{TAB}# RESPONSE: #{function.result}\n" if types.all_types[function.result].respond_to?(:fields) types.all_types[function.result].fields.each do |arg| content << "#{TAB}#{TAB}# #{arg.name}: #{arg.type} - " content << "#{TAB}#{TAB}# #{checkComment(arg.summary, 2)}" if arg.summary content << "#{TAB}#{TAB}# #{checkComment(arg.description, 2)}" if arg.description content << "\n" end elsif types.all_types[function.result].respond_to?(:cases) end end content end