sbuilder-ethereum 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/VERSION +1 -0
- data/lib/mixer/decl_ref.rb +19 -0
- data/lib/mixer/domain_ref.rb +18 -0
- data/lib/mixer/scope.rb +92 -0
- data/lib/mixer/scoped.rb +17 -0
- data/lib/mixer/symbol_ref.rb +16 -0
- data/lib/mixer/type_symbol.rb +75 -0
- data/lib/plugin/plugin.rb +332 -0
- data/lib/resources/correctness/accouns_type.tla +1 -0
- data/lib/resources/correctness/accounts_unique.tla +2 -0
- data/lib/resources/correctness/accounts_valid.tla +2 -0
- data/lib/resources/correctness/storage_root_unique.tla +2 -0
- data/lib/resources/correctness/total_value.tla +1 -0
- data/lib/resources/eth/accounts_state.tla +2 -0
- data/lib/resources/eth/accounts_temp.tla +2 -0
- data/lib/resources/eth/address_free.tla +2 -0
- data/lib/resources/eth/mined_state.tla +1 -0
- data/lib/resources/eth/storageRoot.tla +1 -0
- data/lib/resources/eth/storageRoot_temp.tla +1 -0
- data/lib/resources/mine/mine_entry.tla +4 -0
- data/lib/resources/mine/mine_service.tla +22 -0
- data/lib/resources/operators/elementExists.tla +4 -0
- data/lib/resources/operators/gasPrice.tla +2 -0
- data/lib/resources/operators/gasValue.tla +2 -0
- data/lib/resources/operators/getElement.tla +5 -0
- data/lib/resources/operators/intrinsicGas.tla +4 -0
- data/lib/resources/operators/transactionGas.tla +4 -0
- data/lib/resources/operators/upFrontCost.tla +6 -0
- data/lib/resources/personal_newAccount/personal_newAccount_done.tla +14 -0
- data/lib/resources/personal_newAccount/personal_newAccount_entry.tla +10 -0
- data/lib/resources/personal_newAccount/personal_newAccount_service.tla +29 -0
- data/lib/resources/removed/sendTransaction_entry.tla +5 -0
- data/lib/resources/removed/sendTransaction_service.tla +36 -0
- data/lib/resources/removed/tst.tla +1 -0
- data/lib/resources/transaction/ethereum_service_done.tla +24 -0
- data/lib/resources/transaction/ethereum_service_pop.tla +24 -0
- data/lib/resources/transaction/ethereum_service_push.tla +14 -0
- data/lib/resources/transaction/ethereum_service_start.tla +13 -0
- data/lib/resources/transaction/status_fail.tla +1 -0
- data/lib/resources/transaction/status_ok.tla +1 -0
- data/lib/sbuilder-ethereum.rb +52 -0
- data/lib/sbuilder/compile.rb +163 -0
- data/lib/sbuilder/constants.rb +93 -0
- data/lib/sbuilder/exception.rb +22 -0
- data/lib/sbuilder/generate/sexp_processor_tla.rb +2674 -0
- data/lib/sbuilder/generate/tla_element_generator.rb +1206 -0
- data/lib/sbuilder/generate/tla_element_text.rb +703 -0
- data/lib/sbuilder/load.rb +119 -0
- data/lib/sbuilder/mustache/renderer.rb +152 -0
- data/lib/sbuilder/render.rb +141 -0
- data/lib/sbuilder/s.rb +21 -0
- data/lib/sbuilder/sexp_ast.rb +1378 -0
- data/lib/sbuilder/sexp_processor_api.rb +184 -0
- data/lib/sbuilder/sexp_processor_canonize.rb +326 -0
- data/lib/sbuilder/sexp_processor_dataflow.rb +461 -0
- data/lib/sbuilder/sexp_processor_ethereum.rb +127 -0
- data/lib/sbuilder/sexp_processor_need_to_canonize.rb +572 -0
- data/lib/sbuilder/sexp_processor_snippet.rb +154 -0
- data/lib/sbuilder/sexp_processor_symboltable1.rb +296 -0
- data/lib/sbuilder/sexp_processor_symboltable2.rb +175 -0
- data/lib/sbuilder/sexp_utils.rb +417 -0
- data/lib/utils/logger.rb +82 -0
- data/lib/utils/string_inject.rb +11 -0
- data/sbuilder-ethereum.gemspec +39 -0
- metadata +190 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: fa3a1818b9e4c6c2f3eb5fcc251320fce12bf664
|
4
|
+
data.tar.gz: 4b5e415b5aacf139ae0b495d78df88c0db29f51f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e80192d1a6c95840eed592ead93333e74e4dc8a70d6b505a3257224faf312a0e27ceb7db51d5a0820578099a38bdd1d38ddb742a56f6db3e7dc29a77cea22f9c
|
7
|
+
data.tar.gz: 8a9a1faba9367c4048c324448d67e133506c3bc3d9198b05a0683c08838df9afd679c8796154fea1553b25ec357712177289eb4570367cc91893d0c2fd4f1c7b
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.6
|
@@ -0,0 +1,19 @@
|
|
1
|
+
|
2
|
+
module Sbuilder; module Ethereum
|
3
|
+
|
4
|
+
module DeclRef
|
5
|
+
|
6
|
+
# @attr [Ast] enclosingScope pointer to scope (sets in SexpProcessorSymbolTable1)
|
7
|
+
attr_accessor :enclosingScope
|
8
|
+
|
9
|
+
# @attr [Ast] declationRef pointer to declartion (set in SexpProcessorSymbolTable2)
|
10
|
+
attr_accessor :declationRef
|
11
|
+
|
12
|
+
# @return [Boolean] true because mixes as declaration reference
|
13
|
+
def isDeclarationRef
|
14
|
+
true
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
end; end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Sbuilder
|
2
|
+
module Ethereum
|
3
|
+
|
4
|
+
module DomainRef
|
5
|
+
|
6
|
+
# @attr [Domain] domainReference
|
7
|
+
attr_accessor :domainReference
|
8
|
+
|
9
|
+
# @return [Boolean] true because mixes as declaration reference
|
10
|
+
def isDomainRef
|
11
|
+
true
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
data/lib/mixer/scope.rb
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
|
2
|
+
module Sbuilder
|
3
|
+
module Ethereum
|
4
|
+
|
5
|
+
module Scope
|
6
|
+
# @attr [Hash] map name to symbol
|
7
|
+
attr_reader :symbols
|
8
|
+
|
9
|
+
# @attr [Sccope] enclosing_scope
|
10
|
+
attr_accessor :enclosing_scope
|
11
|
+
|
12
|
+
#
|
13
|
+
# @param [SexpAst] symbol to add to scope
|
14
|
+
#
|
15
|
+
def define( name, symbol )
|
16
|
+
@symbols ||={}
|
17
|
+
symbols[name] = symbol
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
def allSymbols()
|
22
|
+
parentSymbols = {}
|
23
|
+
if getEnclosingScope
|
24
|
+
parentSymbols = getEnclosingScope.allSymbols
|
25
|
+
end
|
26
|
+
parentSymbols.merge( symbols || {} )
|
27
|
+
end
|
28
|
+
|
29
|
+
##
|
30
|
+
# Return symbol definitions
|
31
|
+
def symbolDefinitions
|
32
|
+
symbols.values
|
33
|
+
end
|
34
|
+
|
35
|
+
def scopeHiearachy
|
36
|
+
hierarchy = [ sexp_type ]
|
37
|
+
if getEnclosingScope
|
38
|
+
hierarchy += getEnclosingScope.scopeHiearachy
|
39
|
+
end
|
40
|
+
hierarchy
|
41
|
+
end
|
42
|
+
|
43
|
+
##
|
44
|
+
# Return top most scope
|
45
|
+
def globalScope
|
46
|
+
return self if getEnclosingScope.nil?
|
47
|
+
getEnclosingScope.globalScope
|
48
|
+
end
|
49
|
+
|
50
|
+
def getSymbol( name )
|
51
|
+
symbols[name] if symbols && symbols[name]
|
52
|
+
end
|
53
|
+
|
54
|
+
# @param [String] name to resolve
|
55
|
+
#
|
56
|
+
# @return [Symbol] symbol resolved for the {name}, nil if not found
|
57
|
+
def resolve( name )
|
58
|
+
ret = getSymbol( name )
|
59
|
+
return ret unless ret.nil?
|
60
|
+
return getEnclosingScope.resolve( name ) if getEnclosingScope
|
61
|
+
nil
|
62
|
+
end
|
63
|
+
|
64
|
+
def resolveOrReportError( name )
|
65
|
+
resolved = resolve( name )
|
66
|
+
return resolved if resolved
|
67
|
+
|
68
|
+
raise SbuilderEtherumScopeException, <<-EOS
|
69
|
+
Could not resolve '#{name}' on #{self}
|
70
|
+
|
71
|
+
Scope hierarchy: #{scopeHiearachy.join(',')}
|
72
|
+
Known symbols : #{allSymbols.keys().join(',')}
|
73
|
+
EOS
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
# @return [Scope|nil] scope for enclosing scope, nil for root scope
|
79
|
+
def getEnclosingScope
|
80
|
+
enclosing_scope
|
81
|
+
end
|
82
|
+
|
83
|
+
# @return [Boolean] true because mixes module scope
|
84
|
+
def isScope
|
85
|
+
true
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|
data/lib/mixer/scoped.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
module Sbuilder
|
2
|
+
module Ethereum
|
3
|
+
|
4
|
+
module Scoped
|
5
|
+
|
6
|
+
# @attr [Ast] enclosingScope pointer to scope (sets in SexpProcessorSymbolTable1)
|
7
|
+
attr_accessor :scopeDefining
|
8
|
+
|
9
|
+
# @return [Boolean] true because can be scoped
|
10
|
+
def isScoped
|
11
|
+
true
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Sbuilder
|
2
|
+
module Ethereum
|
3
|
+
module SymbolRef
|
4
|
+
# add a reference to type definition
|
5
|
+
|
6
|
+
# @attr [TypeSymbol] symbolTypeReference pointer to symbol (sets in SexpProcessorSymbolTable2)
|
7
|
+
attr_accessor :symbolTypeReference
|
8
|
+
|
9
|
+
# @return [Boolean] true because mixes module symbol reference
|
10
|
+
def isSymbolRef
|
11
|
+
true
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module Sbuilder
|
2
|
+
module Ethereum
|
3
|
+
|
4
|
+
# Depends on 'scope'
|
5
|
+
|
6
|
+
module TypeSymbol
|
7
|
+
# add a reference to type definition
|
8
|
+
|
9
|
+
# @attr [TypeSymbol] isA pointer to parent type
|
10
|
+
attr_accessor :isA
|
11
|
+
|
12
|
+
# @attr [TypeSymbol:Array] derivedTypes direct 'derivedTypes'
|
13
|
+
# @return [TypeSymbol:Array]
|
14
|
+
def derivedTypes
|
15
|
+
@derivedTypes || []
|
16
|
+
end
|
17
|
+
|
18
|
+
# @return [Hash] knownTypes all known 'derivedTypes' in
|
19
|
+
# derication hierarch
|
20
|
+
# @option knownTypes [String] <key >typeName
|
21
|
+
# @option knownTypes [Array] <value> array of known types
|
22
|
+
|
23
|
+
def allDerivedTypes( knownTypes )
|
24
|
+
childTypes = []
|
25
|
+
knownTypes[typeName] = [self]
|
26
|
+
derivedTypes.each do |derivedType|
|
27
|
+
# find out knownTypes in 'derivedTypes'
|
28
|
+
knownTypes = derivedType.allDerivedTypes( knownTypes )
|
29
|
+
# propagete derived types to parent type
|
30
|
+
childTypes += knownTypes[derivedType.typeName] unless knownTypes[derivedType.typeName].nil?
|
31
|
+
end
|
32
|
+
|
33
|
+
knownTypes[typeName] += childTypes.uniq
|
34
|
+
knownTypes
|
35
|
+
end
|
36
|
+
|
37
|
+
# @return [TypeSymbol|nil] typeSymbol scope for enclosing type,
|
38
|
+
# nil for root type. Wrapper to isA
|
39
|
+
def getEnclosingType
|
40
|
+
isA
|
41
|
+
end
|
42
|
+
|
43
|
+
#
|
44
|
+
# @return [TypeSymbol] top element in type hierarchy
|
45
|
+
def rootSymbol
|
46
|
+
return self if isA.nil?
|
47
|
+
isA.rootSymbol
|
48
|
+
end
|
49
|
+
|
50
|
+
# Build type hierarchy bottom up ie. child.inherits( parent )'
|
51
|
+
#
|
52
|
+
# @param [TypeSymbol] parentExp inherited
|
53
|
+
def inherits( parentExp )
|
54
|
+
raise "parentExp #{parentExp} is not 'TypeSymbol'" unless parentExp.respond_to?(:isTypeSymbol) && parentExp.isTypeSymbol
|
55
|
+
self.isA = parentExp
|
56
|
+
# add back pointer in parent to poin to me
|
57
|
+
parentExp.addDerivedTypes( self )
|
58
|
+
self
|
59
|
+
end
|
60
|
+
|
61
|
+
# Add 'childEntry' to '@derivedTypes', private method
|
62
|
+
def addDerivedTypes( childEntry )
|
63
|
+
@derivedTypes = [] if @derivedTypes.nil?
|
64
|
+
@derivedTypes << childEntry
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
# @return [Boolean] true because mixes module symbol
|
69
|
+
def isTypeSymbol
|
70
|
+
true
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,332 @@
|
|
1
|
+
require 'sbuilder'
|
2
|
+
|
3
|
+
module Sbuilder
|
4
|
+
module Ethereum
|
5
|
+
|
6
|
+
class Plugin < Sbuilder::LoaderPluginRoot
|
7
|
+
|
8
|
+
extend Forwardable # for easy delegation
|
9
|
+
|
10
|
+
# mix api loader plugin services
|
11
|
+
include ApiLoaderPluginMixer
|
12
|
+
|
13
|
+
# mix snippet loader plugin services
|
14
|
+
include SnippetLoaderPluginMixer
|
15
|
+
|
16
|
+
# @attr [SexpProcessorTla] tla which has created +interfaces+,
|
17
|
+
# +snippets+, +partials+, and +metatypes+
|
18
|
+
attr_reader :tla
|
19
|
+
|
20
|
+
# @attr [GlobalScope] globalScope the one
|
21
|
+
attr_reader :globalScope
|
22
|
+
|
23
|
+
def_delegators :tla,
|
24
|
+
# @attr [Interfaces] interfaces created by tla-processor
|
25
|
+
:interfaces,
|
26
|
+
# @attr [Definitions] definitions created by tla-processor
|
27
|
+
:definitions,
|
28
|
+
# @attr [Snippets] snippets i.e. TLA generate
|
29
|
+
# elements created by tla-processor
|
30
|
+
:snippets,
|
31
|
+
# @attr [Hash] partials mapping TLA generate element to mustache partial
|
32
|
+
:partials,
|
33
|
+
# @attr [Hash] metatypes used by TLA generate,
|
34
|
+
# key=metatype, value=desciption
|
35
|
+
:metatypes,
|
36
|
+
# @attr [String:Array] domainNames to create in TLA model
|
37
|
+
:domainNames
|
38
|
+
|
39
|
+
# @attr [Domains] dataFlowDomains
|
40
|
+
attr_reader :dataFlowDomains
|
41
|
+
|
42
|
+
# @attr [Hash] preferences passesed as PREFERENCES property to rendering
|
43
|
+
attr_reader :preferences
|
44
|
+
|
45
|
+
##
|
46
|
+
# Collect domains in 'dataFlowDomains'.
|
47
|
+
#
|
48
|
+
# @param [Domains] resolvedDomains
|
49
|
+
def addDataflowDomains( resolvedDomains )
|
50
|
+
if dataFlowDomains.nil?
|
51
|
+
# init array
|
52
|
+
@dataFlowDomains = resolvedDomains
|
53
|
+
else
|
54
|
+
# concat arrays
|
55
|
+
resolvedDomains.domains.each do |resolvedDomain|
|
56
|
+
@dataFlowDomains << resolvedDomain
|
57
|
+
end
|
58
|
+
end
|
59
|
+
@logger.info "#{__method__}: domains=#{dataFlowDomains}"
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
# @attr [Hash] options set in constructor
|
64
|
+
attr_reader :options
|
65
|
+
|
66
|
+
# ------------------------------------------------------------------
|
67
|
+
# @!group Construct && configure
|
68
|
+
|
69
|
+
def initialize( options = {} )
|
70
|
+
super( options )
|
71
|
+
@options = options
|
72
|
+
logger.info "#{__method__}: plugin created"
|
73
|
+
end
|
74
|
+
|
75
|
+
# Class level configuration
|
76
|
+
#
|
77
|
+
# @param [Hash] configuration given in 'extend.loaders'
|
78
|
+
# @option configuration [String] solc_command path to solc executable
|
79
|
+
#
|
80
|
+
def self.configure( configuration )
|
81
|
+
validateProperties( configuration, Constants::VALIDATION[:class_configure][:required], Constants::VALIDATION[:class_configure][:allowed] )
|
82
|
+
@@solc_command = configuration['solc_command'] if configuration.is_a?(Hash ) && configuration.key?( 'solc_command' )
|
83
|
+
end
|
84
|
+
|
85
|
+
# Instance level configuration
|
86
|
+
#
|
87
|
+
# @param [Hash] configuration for object instance
|
88
|
+
def configure( configuration )
|
89
|
+
logger.info "#{__method__}: configuration=#{configuration}"
|
90
|
+
validateProperties( configuration, Constants::VALIDATION[:configure][:required], Constants::VALIDATION[:configure][:allowed] )
|
91
|
+
@preferences = configuration['preferences']
|
92
|
+
end
|
93
|
+
|
94
|
+
##
|
95
|
+
# @return [String] solc_command path to compile executable- if configerd
|
96
|
+
def self.solc_command
|
97
|
+
@@solc_command if defined?( @@solc_command )
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
|
102
|
+
# @!endgroup
|
103
|
+
|
104
|
+
# ------------------------------------------------------------------
|
105
|
+
# @!group compile & parse solidity
|
106
|
+
|
107
|
+
##
|
108
|
+
# compile, load, create symbol table, resolve symbols, identify domains,
|
109
|
+
# create TLA snippets && infterfaces
|
110
|
+
#
|
111
|
+
|
112
|
+
def processSource( soliditySource )
|
113
|
+
|
114
|
+
# Compile +soliditySource+ to +astPath+ json file
|
115
|
+
compiler = Compile.new( options )
|
116
|
+
compiler.output_directory = compileWorkDirectory
|
117
|
+
compiler.solc_command = self.class.solc_command
|
118
|
+
compiler.compile( soliditySource )
|
119
|
+
astPath = compiler.compiledAst
|
120
|
+
|
121
|
+
# load +astPath+ into SexpAst tree +ast+
|
122
|
+
loader = Load.new( options )
|
123
|
+
|
124
|
+
# Create the unique global scope
|
125
|
+
@globalScope = SexpUtils.createGlobalScope
|
126
|
+
@logger.debug "#{__method__}: globalScope=#{globalScope}" if @logger.debug?
|
127
|
+
# create tla processor, which maps ast to snippets,
|
128
|
+
# interfaces, etc. make tla aware of +baseMetatypes+ in
|
129
|
+
# 'sbuilder' framework.
|
130
|
+
|
131
|
+
@tla = SexpProcessorTla.new( facade.baseMetatypes, options )
|
132
|
+
# tla.setBaseMetatypes( facade.baseMetatypes )
|
133
|
+
|
134
|
+
# process global scope - it defines global functions, which should be processed
|
135
|
+
processAst( "GlobalScope", globalScope, nil )
|
136
|
+
|
137
|
+
# process all compile units
|
138
|
+
|
139
|
+
asts = []
|
140
|
+
loader.processAllAsts( astPath ) do |ast, astName |
|
141
|
+
processAst( astName, ast, globalScope )
|
142
|
+
asts << ast
|
143
|
+
end
|
144
|
+
|
145
|
+
# after all solidity ast's have been preprossesed
|
146
|
+
tla.process( globalScope )
|
147
|
+
asts.each do |ast|
|
148
|
+
# Create +snippets+, +interfaces+, +partials+, +domains+
|
149
|
+
tla.process( ast )
|
150
|
+
end
|
151
|
+
|
152
|
+
end
|
153
|
+
|
154
|
+
|
155
|
+
##
|
156
|
+
# Process 'ast' trhough steps: 1) fix.point( canonize ), 2)
|
157
|
+
# Create symbol table hierarchy, 3) Resolve refernces using the
|
158
|
+
# symbol table, 4) identify data flows, 4) map processed ast to
|
159
|
+
# tla-language elements
|
160
|
+
#
|
161
|
+
# @param [String] compileUnit name of solidity AST
|
162
|
+
private def processAst( compileUnit, ast, globalScope )
|
163
|
+
|
164
|
+
@logger.debug "#{__method__}: ast=#{ast}" if @logger.debug?
|
165
|
+
|
166
|
+
# preprocess
|
167
|
+
needAnalyzer = Sbuilder::Ethereum::SexpProcessorNeedToCanonize.new( options )
|
168
|
+
needProcessor = Sbuilder::Ethereum::SexpProcessorCanonize.new( options )
|
169
|
+
needProcessor.setCompileUnit( compileUnit )
|
170
|
+
|
171
|
+
# iterate canonization until fixpoint
|
172
|
+
begin
|
173
|
+
needAnalyzer.initIt
|
174
|
+
needAnalyzer.process( ast )
|
175
|
+
needProcessor.setNeeds( needAnalyzer )
|
176
|
+
needProcessor.process( ast );
|
177
|
+
end while ( needProcessor.somethingCanonized )
|
178
|
+
|
179
|
+
|
180
|
+
# Scope hierarchy for symbol table in +ast+
|
181
|
+
symbolTable1 = SexpProcessorSymbolTable1.new( options )
|
182
|
+
symbolTable1.globalScope = globalScope
|
183
|
+
symbolTable1.process( ast )
|
184
|
+
|
185
|
+
# Resolve references in +ast+
|
186
|
+
symbolTable2 = SexpProcessorSymbolTable2.new( options )
|
187
|
+
symbolTable2.process( ast )
|
188
|
+
|
189
|
+
# Identity dataflow in in +ast+ and produde +domains+
|
190
|
+
dataFlow = SexpProcessorDataflow.new( options )
|
191
|
+
dataFlow.process( ast )
|
192
|
+
|
193
|
+
# adds to context accross compile units
|
194
|
+
addDataflowDomains( dataFlow.domains )
|
195
|
+
|
196
|
+
# # Create +snippets+, +interfaces+, +partials+, +domains+
|
197
|
+
# tla.process( ast )
|
198
|
+
|
199
|
+
# @logger.debug "#{__method__}: #{compileUnit} defines-snippets=#{snippets.length}" if @logger.debug?
|
200
|
+
# @logger.debug "#{__method__}: interfaces=#{interfaces}" if @logger.debug?
|
201
|
+
# @logger.debug "#{__method__}: definitions=#{definitions}" if @logger.debug?
|
202
|
+
|
203
|
+
end
|
204
|
+
|
205
|
+
# @!endgroup
|
206
|
+
|
207
|
+
|
208
|
+
# ------------------------------------------------------------------
|
209
|
+
# @!group APi loader
|
210
|
+
|
211
|
+
##
|
212
|
+
# Load API interfaces to sbuilder for solidity source
|
213
|
+
#
|
214
|
+
# @param [String] soliditySource given in sbuilder.yaml
|
215
|
+
#
|
216
|
+
def load( soliditySource )
|
217
|
+
logger.info "#{__method__} soliditySource=#{soliditySource}"
|
218
|
+
# snippets parsed
|
219
|
+
|
220
|
+
processSource( soliditySource )
|
221
|
+
|
222
|
+
loadDomains
|
223
|
+
|
224
|
+
loadApis
|
225
|
+
|
226
|
+
end
|
227
|
+
|
228
|
+
##
|
229
|
+
# Load domainNames to sbuilder using via +facade+
|
230
|
+
private def loadDomains
|
231
|
+
logger.info "#{__method__}: starting"
|
232
|
+
|
233
|
+
# Load domains idendified during dataflow analysis
|
234
|
+
dataFlowDomains.domains.each do |domain|
|
235
|
+
logger.info "#{__method__}: dataflow domainName=#{domain.domainName}, values=#{domain.domainValues.join(',')}"
|
236
|
+
facade.defineDomain( domain.domainName, domain.domainValues )
|
237
|
+
end
|
238
|
+
|
239
|
+
# Load domains identified during TLA processing
|
240
|
+
domainNames.each do |domain|
|
241
|
+
logger.info "#{__method__}: TLA app-domainName=#{domain.domainName}, values=#{domain.domainValues.join(',')}"
|
242
|
+
facade.defineDomain( domain.domainName, domain.domainValues )
|
243
|
+
end
|
244
|
+
logger.debug "#{__method__} done" if logger.debug?
|
245
|
+
end
|
246
|
+
|
247
|
+
|
248
|
+
##
|
249
|
+
# Ensture that 'getCacheDir'/solidity exists && return this
|
250
|
+
# directory as a path. Called in API loader phase --> use facade
|
251
|
+
# to access sbuilder context.
|
252
|
+
#
|
253
|
+
# @return [String] path to compiler wordking directory private
|
254
|
+
|
255
|
+
def compileWorkDirectory()
|
256
|
+
|
257
|
+
subDir = "solidity"
|
258
|
+
|
259
|
+
directoryPath = "#{facade.getCacheDir}/#{subDir}"
|
260
|
+
|
261
|
+
Dir.mkdir( directoryPath ) unless File.exist?( directoryPath )
|
262
|
+
directoryPath
|
263
|
+
|
264
|
+
end
|
265
|
+
|
266
|
+
##
|
267
|
+
# Load api configuration to sbuilder using via +facade+.
|
268
|
+
private def loadApis
|
269
|
+
|
270
|
+
# Create loader to process :Interfaces sexps
|
271
|
+
apiLoader = SexpProcessorApi.new( options )
|
272
|
+
apiLoader.apiFacade = facade
|
273
|
+
# InfrastructureService -> support returning 'response'
|
274
|
+
facade.configureInfrastructureService( true )
|
275
|
+
apiLoader.process( interfaces )
|
276
|
+
|
277
|
+
apiLoader.process( definitions )
|
278
|
+
|
279
|
+
end
|
280
|
+
|
281
|
+
# @return [Boolean] true #load has called #process, which sets +snippets+
|
282
|
+
def loadDone
|
283
|
+
!tla.nil? && !snippets.nil?
|
284
|
+
end
|
285
|
+
|
286
|
+
|
287
|
+
# @!endgroup
|
288
|
+
|
289
|
+
# ------------------------------------------------------------------
|
290
|
+
# @!group Snippet loader
|
291
|
+
|
292
|
+
##
|
293
|
+
# Register snippets for a solidity contract.
|
294
|
+
|
295
|
+
# Implemtnation assumes that +process+ method has been called
|
296
|
+
# earlier, and uses +snippets+ getter to retrive TLA generate
|
297
|
+
# element to load into sbuilder.
|
298
|
+
#
|
299
|
+
# Overrides abstract method in parent class.
|
300
|
+
#
|
301
|
+
# @param [Hash:Array] snippetDefitions given in sbuilder.yaml
|
302
|
+
#
|
303
|
+
# @return [Boolean] true after success
|
304
|
+
#
|
305
|
+
def doRegisterSnippets( snippetDefitions )
|
306
|
+
logger.info "#{__method__}: snippetDefitions=#{snippetDefitions}"
|
307
|
+
raise SbuilderEtherumPluginException, "Should call #load before calling ##{__method__}" unless loadDone
|
308
|
+
logger.debug "#{__method__}: snippets-dump=#{snippets}" if logger.debug?
|
309
|
+
logger.info "#{__method__}: snippets=#{snippets.return_nodes_with_type(:Snippet).map {|s| s.metatype.to_s + '/' + s.appName.to_s}.join(',')}"
|
310
|
+
|
311
|
+
# Create renderer i.e. an object to convert TLA generate
|
312
|
+
# element to TLA language snippets by using mustache partial
|
313
|
+
renderer = Render.new( options )
|
314
|
+
renderer.setPreferences( preferences )
|
315
|
+
renderer.setPartials( partials )
|
316
|
+
|
317
|
+
# Create && configure snippet loader to process ':Snippets' sexps
|
318
|
+
snippetLoader = SexpProcessorSnippet.new( options )
|
319
|
+
snippetLoader.setSnippetFacade( snippetFacade )
|
320
|
+
snippetLoader.setRenderer( renderer )
|
321
|
+
snippetLoader.setMetatypes( metatypes )
|
322
|
+
snippetLoader.process( snippets )
|
323
|
+
|
324
|
+
true
|
325
|
+
end
|
326
|
+
|
327
|
+
# @!endgroup
|
328
|
+
|
329
|
+
|
330
|
+
end # class Plugin < Sbuilder::SnippetLoaderPlugin
|
331
|
+
end
|
332
|
+
end
|