oso-oso 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2f319a22c3568b2a11da1be2ff92d458acac50a1
4
- data.tar.gz: b42631f294bbf9f5f45c70c8c8beef6bf13756ce
3
+ metadata.gz: 919322c6735cfeb3615da5dd85b4188c59e8716d
4
+ data.tar.gz: 1c881b365f4098e3bbdad3152168e82ab31df87f
5
5
  SHA512:
6
- metadata.gz: 60774d89d1abec361c3d4ad96c2c5e1dd56fde369f4c49cb36fbdd6c9cb3f78d3ea51ee394febbf5472d1500dace92a8f346281fd3c04c8a88e9e040d467e5fd
7
- data.tar.gz: 2e08087f17170f44fcd528c5f8f756d5979a1b30765b4417506195f10b6b8587f70500582efea0d1780a8124091b7ccc71a7c0d66d00ef601dbd48077d5a3707
6
+ metadata.gz: b898b3636cdb1cfa5fe909634292cf030bd60ccf768e964cb258c7e1c076d34b52e953bf8b37b27e2cc42926c44efdbd7b600dc21fea63e7144834870d80db1f
7
+ data.tar.gz: 1e38944c4a55b81b3dbecbf1864be035632bd840e0f709380c8b14bfaecf657a1abb273b74b171aae35df9210beddb7e42f4c3547af74e482d0db4b214ca987f
@@ -0,0 +1,7 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.4
3
+ Exclude:
4
+ - '**/*~'
5
+ - 'bin/oso'
6
+ - 'vendor/**/*'
7
+ NewCops: enable
data/Gemfile CHANGED
@@ -3,4 +3,3 @@
3
3
  source 'https://rubygems.org'
4
4
 
5
5
  gemspec
6
-
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- oso-oso (0.3.1)
4
+ oso-oso (0.4.0)
5
5
  ffi (~> 1.0)
6
6
 
7
7
  GEM
@@ -12,18 +12,18 @@ GEM
12
12
  benchmark (0.1.0)
13
13
  byebug (11.1.3)
14
14
  coderay (1.1.3)
15
- diff-lcs (1.3)
15
+ diff-lcs (1.4.4)
16
16
  e2mmap (0.1.0)
17
17
  ffi (1.13.1)
18
18
  jaro_winkler (1.5.4)
19
19
  maruku (0.7.3)
20
20
  method_source (1.0.0)
21
21
  mini_portile2 (2.4.0)
22
- nokogiri (1.10.9)
22
+ nokogiri (1.10.10)
23
23
  mini_portile2 (~> 2.4.0)
24
- parallel (1.19.1)
25
- parser (2.7.1.3)
26
- ast (~> 2.4.0)
24
+ parallel (1.19.2)
25
+ parser (2.7.1.4)
26
+ ast (~> 2.4.1)
27
27
  pry (0.13.1)
28
28
  coderay (~> 1.1)
29
29
  method_source (~> 1.0)
@@ -49,19 +49,19 @@ GEM
49
49
  diff-lcs (>= 1.2.0, < 2.0)
50
50
  rspec-support (~> 3.9.0)
51
51
  rspec-support (3.9.3)
52
- rubocop (0.85.1)
52
+ rubocop (0.89.0)
53
53
  parallel (~> 1.10)
54
- parser (>= 2.7.0.1)
54
+ parser (>= 2.7.1.1)
55
55
  rainbow (>= 2.2.2, < 4.0)
56
56
  regexp_parser (>= 1.7)
57
57
  rexml
58
- rubocop-ast (>= 0.0.3)
58
+ rubocop-ast (>= 0.1.0, < 1.0)
59
59
  ruby-progressbar (~> 1.7)
60
60
  unicode-display_width (>= 1.4.0, < 2.0)
61
- rubocop-ast (0.0.3)
62
- parser (>= 2.7.0.1)
61
+ rubocop-ast (0.3.0)
62
+ parser (>= 2.7.1.4)
63
63
  ruby-progressbar (1.10.1)
64
- solargraph (0.39.8)
64
+ solargraph (0.39.13)
65
65
  backport (~> 1.1)
66
66
  benchmark
67
67
  bundler (>= 1.17.2)
@@ -88,6 +88,7 @@ DEPENDENCIES
88
88
  pry-byebug (~> 3.9.0)
89
89
  rake (~> 12.0)
90
90
  rspec (~> 3.0)
91
+ rubocop (~> 0.89.0)
91
92
  solargraph (~> 0.39.8)
92
93
  yard (~> 0.9.25)
93
94
 
data/Makefile CHANGED
@@ -1,4 +1,4 @@
1
- .PHONY: install rust test
1
+ .PHONY: rust install test lint typecheck repl
2
2
 
3
3
  rust:
4
4
  $(MAKE) -C ../.. rust-build
@@ -9,5 +9,11 @@ install: rust
9
9
  test: install
10
10
  bundle exec rake spec
11
11
 
12
- repl:
12
+ lint:
13
+ bundle exec rubocop
14
+
15
+ typecheck:
16
+ bundle exec solargraph typecheck
17
+
18
+ repl: install
13
19
  bundle exec oso
data/Rakefile CHANGED
@@ -6,4 +6,3 @@ require 'rspec/core/rake_task'
6
6
  RSpec::Core::RakeTask.new(:spec)
7
7
 
8
8
  task default: :spec
9
-
Binary file
Binary file
@@ -3,7 +3,7 @@
3
3
  module Oso
4
4
  # An HTTP resource.
5
5
  class Http
6
- def initialize(hostname: nil, path: nil, query: nil)
6
+ def initialize(hostname, path, query)
7
7
  @hostname = hostname
8
8
  @path = path
9
9
  @query = query
@@ -4,7 +4,7 @@ module Oso
4
4
  # Map from a template string with capture groups of the form
5
5
  # `{name}` to a dictionary of the form `{name: captured_value}`
6
6
  class PathMapper
7
- def initialize(template:)
7
+ def initialize(template)
8
8
  capture_group = /({([^}]+)})/
9
9
 
10
10
  template = template.dup
@@ -5,16 +5,12 @@ module Oso
5
5
  # Base error type for Oso::Polar.
6
6
  class Error < ::RuntimeError
7
7
  attr_reader :stack_trace
8
-
8
+
9
9
  # @param message [String]
10
10
  # @param details [Hash]
11
11
  def initialize(message = nil, details: nil)
12
12
  @details = details
13
- if details and details.key?("stack_trace")
14
- @stack_trace = details['stack_trace']
15
- else
16
- @stack_trace = nil
17
- end
13
+ @stack_trace = details&.fetch('stack_trace', nil)
18
14
  super(message)
19
15
  end
20
16
  end
@@ -44,9 +40,28 @@ module Oso
44
40
  class InlineQueryFailedError < PolarRuntimeError; end
45
41
  class NullByteInPolarFileError < PolarRuntimeError; end
46
42
  class UnexpectedPolarTypeError < PolarRuntimeError; end
43
+ class PolarFileAlreadyLoadedError < PolarRuntimeError # rubocop:disable Style/Documentation
44
+ # @param file [String]
45
+ def initialize(file)
46
+ super("File #{file} has already been loaded.")
47
+ end
48
+ end
49
+ class PolarFileContentsChangedError < PolarRuntimeError # rubocop:disable Style/Documentation
50
+ # @param file [String]
51
+ def initialize(file)
52
+ super("A file with the name #{file}, but different contents, has already been loaded.")
53
+ end
54
+ end
55
+ class PolarFileNameChangedError < PolarRuntimeError # rubocop:disable Style/Documentation
56
+ # @param file [String]
57
+ # @param existing [String]
58
+ def initialize(file, existing)
59
+ super("A file with the same contents as #{file} named #{existing} has already been loaded.")
60
+ end
61
+ end
47
62
  class PolarFileExtensionError < PolarRuntimeError # rubocop:disable Style/Documentation
48
- def initialize
49
- super('Polar files must have .pol or .polar extension.')
63
+ def initialize(file)
64
+ super("Polar files must have .polar extension. Offending file: #{file}")
50
65
  end
51
66
  end
52
67
  class PolarFileNotFoundError < PolarRuntimeError # rubocop:disable Style/Documentation
@@ -59,7 +74,7 @@ module Oso
59
74
  # @param as [String]
60
75
  # @param old [Class]
61
76
  # @param new [Class]
62
- def initialize(name:, old:, new:) # rubocop:disable Naming/MethodParameterName
77
+ def initialize(name:, old:, new:)
63
78
  super("Attempted to alias #{new} as '#{name}', but #{old} already has that alias.")
64
79
  end
65
80
  end
@@ -5,7 +5,7 @@ require 'ffi'
5
5
  module Oso
6
6
  module Polar
7
7
  module FFI
8
- LIB = ::FFI::Platform::LIBPREFIX + 'polar.' + ::FFI::Platform::LIBSUFFIX
8
+ LIB = "#{::FFI::Platform::LIBPREFIX}polar.#{::FFI::Platform::LIBSUFFIX}"
9
9
  RELEASE_PATH = File.expand_path(File.join(__dir__, "../../../ext/oso-oso/lib/#{LIB}"))
10
10
  DEV_PATH = File.expand_path(File.join(__dir__, "../../../../../target/debug/#{LIB}"))
11
11
  # If the lib exists in the ext/ dir, use it. Otherwise, fall back to
@@ -22,7 +22,7 @@ module Oso
22
22
  #
23
23
  # @return [::Oso::Polar::Error] if there's an FFI error.
24
24
  # @return [::Oso::Polar::FFIErrorNotFound] if there isn't one.
25
- def self.get # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
25
+ def self.get # rubocop:disable Metrics/MethodLength
26
26
  error = Rust.get
27
27
  return ::Oso::Polar::FFIErrorNotFound if error.null?
28
28
 
@@ -48,7 +48,7 @@ module Oso
48
48
  # @param msg [String]
49
49
  # @param details [Hash<String, Object>]
50
50
  # @return [::Oso::Polar::ParseError] the object converted into the expected format.
51
- private_class_method def self.parse_error(kind, msg:, details:) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength
51
+ private_class_method def self.parse_error(kind, msg:, details:) # rubocop:disable Metrics/MethodLength
52
52
  case kind
53
53
  when 'ExtraToken'
54
54
  ::Oso::Polar::ParseError::ExtraToken.new(msg, details: details)
@@ -3,8 +3,9 @@
3
3
  module Oso
4
4
  module Polar
5
5
  # Translate between Polar and the host language (Ruby).
6
- class Host
6
+ class Host # rubocop:disable Metrics/ClassLength
7
7
  protected
8
+
8
9
  # @return [FFI::Polar]
9
10
  attr_reader :ffi_polar
10
11
  # @return [Hash<String, Class>]
@@ -15,6 +16,7 @@ module Oso
15
16
  attr_reader :instances
16
17
 
17
18
  public
19
+
18
20
  def initialize(ffi_polar)
19
21
  @ffi_polar = ffi_polar
20
22
  @classes = {}
@@ -46,7 +48,7 @@ module Oso
46
48
  # @param name [String] the name to cache the class as. Defaults to the name of the class.
47
49
  # @return [String] the name the class is cached as.
48
50
  # @raise [UnregisteredClassError] if the class has not been registered.
49
- def cache_class(cls, name:, constructor:)
51
+ def cache_class(cls, name:, constructor:) # rubocop:disable Metrics/MethodLength
50
52
  name = cls.name if name.nil?
51
53
  raise DuplicateClassAliasError, name: name, old: get_class(name), new: cls if classes.key? name
52
54
 
@@ -111,22 +113,29 @@ module Oso
111
113
  # Construct and cache a Ruby instance.
112
114
  #
113
115
  # @param cls_name [String]
114
- # @param fields [Hash<String, Hash>]
116
+ # @param initargs [Hash<String, Hash>]
115
117
  # @param id [Integer]
116
118
  # @raise [PolarRuntimeError] if instance construction fails.
117
- def make_instance(cls_name, fields:, id:) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
119
+ def make_instance(cls_name, initargs:, id:) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
118
120
  constructor = get_constructor(cls_name)
119
- fields = Hash[fields.map { |k, v| [k.to_sym, to_ruby(v)] }]
120
121
  instance = if constructor == :new
121
- if fields.empty?
122
+ if initargs.empty?
122
123
  get_class(cls_name).__send__(:new)
124
+ elsif initargs.is_a? Array
125
+ get_class(cls_name).__send__(:new, *initargs)
126
+ elsif initargs.is_a? Hash
127
+ get_class(cls_name).__send__(:new, **initargs)
123
128
  else
124
- get_class(cls_name).__send__(:new, **fields)
129
+ raise PolarRuntimeError, "Bad initargs: #{initargs}"
125
130
  end
126
- elsif fields.empty?
131
+ elsif initargs.empty?
127
132
  constructor.call
133
+ elsif initargs.is_a? Array
134
+ constructor.call(*initargs)
135
+ elsif initargs.is_a? Hash
136
+ constructor.call(**initargs)
128
137
  else
129
- constructor.call(**fields)
138
+ raise PolarRuntimeError, "Bad initargs: #{initargs}"
130
139
  end
131
140
  cache_instance(instance, id: id)
132
141
  rescue StandardError => e
@@ -149,11 +158,11 @@ module Oso
149
158
 
150
159
  # Check if instance is an instance of class.
151
160
  #
152
- # @param instance_id [Integer]
161
+ # @param instance [Hash<String, Object>]
153
162
  # @param class_tag [String]
154
163
  # @return [Boolean]
155
- def isa?(instance_id, class_tag:)
156
- instance = get_instance(instance_id)
164
+ def isa?(instance, class_tag:)
165
+ instance = to_ruby(instance)
157
166
  cls = get_class(class_tag)
158
167
  instance.is_a? cls
159
168
  rescue PolarRuntimeError
@@ -3,23 +3,41 @@
3
3
  require 'json'
4
4
  require 'pp'
5
5
  require 'set'
6
+ require 'digest/md5'
7
+
8
+ # Missing Ruby type.
9
+ module PolarBoolean; end
10
+ # Monkey-patch Ruby true type.
11
+ class TrueClass; include PolarBoolean; end
12
+ # Monkey-patch Ruby false type.
13
+ class FalseClass; include PolarBoolean; end
6
14
 
7
15
  module Oso
8
16
  module Polar
9
17
  # Create and manage an instance of the Polar runtime.
10
- class Polar
18
+ class Polar # rubocop:disable Metrics/ClassLength
11
19
  # @return [Host]
12
20
  attr_reader :host
13
21
 
14
22
  def initialize
15
23
  @ffi_polar = FFI::Polar.create
16
24
  @host = Host.new(ffi_polar)
17
- @load_queue = Set.new
25
+ @loaded_names = {}
26
+ @loaded_contents = {}
27
+
28
+ # Register built-in classes.
29
+ register_class PolarBoolean, name: 'Boolean'
30
+ register_class Integer
31
+ register_class Float
32
+ register_class Array, name: 'List'
33
+ register_class Hash, name: 'Dictionary'
34
+ register_class String
18
35
  end
19
36
 
20
37
  # Replace the current Polar instance but retain all registered classes and constructors.
21
38
  def clear
22
- load_queue.clear
39
+ loaded_names.clear
40
+ loaded_contents.clear
23
41
  @ffi_polar = FFI::Polar.create
24
42
  end
25
43
 
@@ -28,11 +46,25 @@ module Oso
28
46
  # @param name [String]
29
47
  # @raise [PolarFileExtensionError] if provided filename has invalid extension.
30
48
  # @raise [PolarFileNotFoundError] if provided filename does not exist.
31
- def load_file(name)
32
- raise PolarFileExtensionError unless ['.pol', '.polar'].include? File.extname(name)
33
- raise PolarFileNotFoundError, name unless File.file?(name)
49
+ def load_file(name) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
50
+ raise PolarFileExtensionError, name unless File.extname(name) == '.polar'
51
+
52
+ file_data = File.open(name, &:read)
53
+ hash = Digest::MD5.hexdigest(file_data)
54
+
55
+ if loaded_names.key?(name)
56
+ raise PolarFileAlreadyLoadedError, name if loaded_names[name] == hash
34
57
 
35
- load_queue << name
58
+ raise PolarFileContentsChangedError, name
59
+ elsif loaded_contents.key?(hash)
60
+ raise PolarFileNameChangedError, name, loaded_contents[hash]
61
+ else
62
+ load_str(file_data, filename: name)
63
+ loaded_names[name] = hash
64
+ loaded_contents[hash] = name
65
+ end
66
+ rescue Errno::ENOENT
67
+ raise PolarFileNotFoundError, name
36
68
  end
37
69
 
38
70
  # Load a Polar string into the KB.
@@ -60,11 +92,15 @@ module Oso
60
92
 
61
93
  # Query for a predicate, parsing it if necessary.
62
94
  #
63
- # @param query [String or Predicate]
64
- # @return Enumerator of resulting bindings
65
- # @raise [Error] if the FFI call raises one.
95
+ # @overload query(query)
96
+ # @param query [String]
97
+ # @return [Enumerator] of resulting bindings
98
+ # @raise [Error] if the FFI call raises one.
99
+ # @overload query(query)
100
+ # @param query [Predicate]
101
+ # @return [Enumerator] of resulting bindings
102
+ # @raise [Error] if the FFI call raises one.
66
103
  def query(query)
67
- load_queued_files
68
104
  new_host = host.dup
69
105
  case query
70
106
  when String
@@ -81,6 +117,7 @@ module Oso
81
117
  #
82
118
  # @param name [String]
83
119
  # @param args [Array<Object>]
120
+ # @return [Enumerator] of resulting bindings
84
121
  # @raise [Error] if the FFI call raises one.
85
122
  def query_rule(name, *args)
86
123
  query(Predicate.new(name, args: args))
@@ -89,14 +126,13 @@ module Oso
89
126
  # Start a REPL session.
90
127
  #
91
128
  # @raise [Error] if the FFI call raises one.
92
- def repl(load: false) # rubocop:disable Metrics/MethodLength
129
+ def repl(load: false) # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/AbcSize
93
130
  ARGV.map { |f| load_file(f) } if load
94
- load_queued_files
95
131
 
96
- loop do
97
- print('query> ')
132
+ loop do # rubocop:disable Metrics/BlockLength
133
+ print 'query> '
98
134
  begin
99
- query = STDIN.readline.chomp.chomp(';')
135
+ query = $stdin.readline.chomp.chomp(';')
100
136
  rescue EOFError
101
137
  return
102
138
  end
@@ -104,14 +140,14 @@ module Oso
104
140
  begin
105
141
  ffi_query = ffi_polar.new_query_from_str(query)
106
142
  rescue ParseError => e
107
- puts("Parse error: " + e.to_s)
143
+ puts "Parse error: #{e}"
108
144
  next
109
145
  end
110
146
 
111
147
  begin
112
148
  results = Query.new(ffi_query, host: host).results.to_a
113
149
  rescue PolarRuntimeError => e
114
- puts(e.to_s)
150
+ puts e
115
151
  next
116
152
  end
117
153
 
@@ -136,9 +172,7 @@ module Oso
136
172
  # @param from_polar [Proc]
137
173
  # @raise [InvalidConstructorError] if provided an invalid 'from_polar' constructor.
138
174
  def register_class(cls, name: nil, from_polar: nil)
139
- if block_given?
140
- from_polar = Proc.new
141
- end
175
+ from_polar = Proc.new if block_given?
142
176
  name = host.cache_class(cls, name: name, constructor: from_polar)
143
177
  register_constant(name, value: cls)
144
178
  end
@@ -147,20 +181,14 @@ module Oso
147
181
  ffi_polar.register_constant(name, value: host.to_polar_term(value))
148
182
  end
149
183
 
150
- # Load all queued files, flushing the {#load_queue}.
151
- def load_queued_files
152
- load_queue.reject! do |filename|
153
- File.open(filename) { |file| load_str(file.read, filename: filename) }
154
- true
155
- end
156
- end
157
-
158
184
  private
159
185
 
160
186
  # @return [FFI::Polar]
161
187
  attr_reader :ffi_polar
162
- # @return [Array<String>]
163
- attr_reader :load_queue
188
+ # @return [Hash<String, String>]
189
+ attr_reader :loaded_names
190
+ # @return [Hash<String, String>]
191
+ attr_reader :loaded_contents
164
192
  end
165
193
  end
166
194
  end
@@ -3,11 +3,12 @@
3
3
  module Oso
4
4
  module Polar
5
5
  # A single Polar query.
6
- class Query
6
+ class Query # rubocop:disable Metrics/ClassLength
7
+ # @return [Enumerator]
7
8
  attr_reader :results
8
9
 
9
10
  # @param ffi_query [FFI::Query]
10
- # @param ffi_polar [FFI::Polar]
11
+ # @param host [Oso::Polar::Host]
11
12
  def initialize(ffi_query, host:)
12
13
  @calls = {}
13
14
  @ffi_query = ffi_query
@@ -38,7 +39,7 @@ module Oso
38
39
  #
39
40
  # @param method [#to_sym]
40
41
  # @param call_id [Integer]
41
- # @param instance [Hash]
42
+ # @param instance [Hash<String, Object>]
42
43
  # @param args [Array<Hash>]
43
44
  # @raise [InvalidCallError] if the method doesn't exist on the instance or
44
45
  # the args passed to the method are invalid.
@@ -46,12 +47,7 @@ module Oso
46
47
  return if calls.key?(call_id)
47
48
 
48
49
  args = args.map { |a| host.to_ruby(a) }
49
- if instance['value'].key? 'ExternalInstance'
50
- instance_id = instance['value']['ExternalInstance']['instance_id']
51
- instance = host.get_instance(instance_id)
52
- else
53
- instance = host.to_ruby(instance)
54
- end
50
+ instance = host.to_ruby(instance)
55
51
  result = instance.__send__(method, *args)
56
52
  result = [result].to_enum unless result.is_a? Enumerator # Call must be a generator.
57
53
  calls[call_id] = result.lazy
@@ -77,10 +73,9 @@ module Oso
77
73
  host.to_polar_term(calls[id].next)
78
74
  end
79
75
 
80
- # Send result of predicate check across FFI boundary.
76
+ # Send application error across FFI boundary.
81
77
  #
82
- # @param result [Boolean]
83
- # @param call_id [Integer]
78
+ # @param message [String]
84
79
  # @raise [Error] if the FFI call raises one.
85
80
  def application_error(message)
86
81
  ffi_query.application_error(message)
@@ -92,7 +87,7 @@ module Oso
92
87
  # @param method [#to_sym]
93
88
  # @param args [Array<Hash>]
94
89
  # @param call_id [Integer]
95
- # @param instance_id [Integer]
90
+ # @param instance [Hash<String, Object>]
96
91
  # @raise [Error] if the FFI call raises one.
97
92
  def handle_call(method, call_id:, instance:, args:)
98
93
  register_call(method, call_id: call_id, instance: instance, args: args)
@@ -110,7 +105,7 @@ module Oso
110
105
  # @yieldparam [Hash<String, Object>]
111
106
  # @return [Enumerator]
112
107
  # @raise [Error] if any of the FFI calls raise one.
113
- def start # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
108
+ def start # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
114
109
  Enumerator.new do |yielder| # rubocop:disable Metrics/BlockLength
115
110
  loop do # rubocop:disable Metrics/BlockLength
116
111
  event = ffi_query.next_event
@@ -123,9 +118,18 @@ module Oso
123
118
  id = event.data['instance_id']
124
119
  raise DuplicateInstanceRegistrationError, id if host.instance? id
125
120
 
126
- cls_name = event.data['instance']['tag']
127
- fields = event.data['instance']['fields']['fields']
128
- host.make_instance(cls_name, fields: fields, id: id)
121
+ constructor = event.data['constructor']['value']
122
+ if constructor.key? 'InstanceLiteral'
123
+ cls_name = constructor['InstanceLiteral']['tag']
124
+ fields = constructor['InstanceLiteral']['fields']['fields']
125
+ initargs = Hash[fields.map { |k, v| [k.to_sym, host.to_ruby(v)] }]
126
+ elsif constructor.key? 'Call'
127
+ cls_name = constructor['Call']['name']
128
+ initargs = constructor['Call']['args'].map { |arg| host.to_ruby(arg) }
129
+ else
130
+ raise InvalidConstructorError
131
+ end
132
+ host.make_instance(cls_name, initargs: initargs, id: id)
129
133
  when 'ExternalCall'
130
134
  call_id = event.data['call_id']
131
135
  instance = event.data['instance']
@@ -139,9 +143,9 @@ module Oso
139
143
  answer = host.subspecializer?(instance_id, left_tag: left_tag, right_tag: right_tag)
140
144
  question_result(answer, call_id: event.data['call_id'])
141
145
  when 'ExternalIsa'
142
- instance_id = event.data['instance_id']
146
+ instance = event.data['instance']
143
147
  class_tag = event.data['class_tag']
144
- answer = host.isa?(instance_id, class_tag: class_tag)
148
+ answer = host.isa?(instance, class_tag: class_tag)
145
149
  question_result(answer, call_id: event.data['call_id'])
146
150
  when 'ExternalUnify'
147
151
  left_instance_id = event.data['left_instance_id']
@@ -152,7 +156,7 @@ module Oso
152
156
  puts event.data['message'] if event.data['message']
153
157
  print 'debug> '
154
158
  begin
155
- input = STDIN.readline.chomp.chomp(';')
159
+ input = $stdin.readline.chomp.chomp(';')
156
160
  rescue EOFError
157
161
  next
158
162
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Oso
4
- VERSION = '0.3.1'
4
+ VERSION = '0.4.0'
5
5
  end
@@ -34,6 +34,7 @@ Gem::Specification.new do |spec|
34
34
  spec.add_development_dependency 'pry-byebug', '~> 3.9.0'
35
35
  spec.add_development_dependency 'rake', '~> 12.0'
36
36
  spec.add_development_dependency 'rspec', '~> 3.0'
37
+ spec.add_development_dependency 'rubocop', '~> 0.89.0'
37
38
  spec.add_development_dependency 'solargraph', '~> 0.39.8'
38
39
  spec.add_development_dependency 'yard', '~> 0.9.25'
39
40
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oso-oso
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oso Security, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-31 00:00:00.000000000 Z
11
+ date: 2020-08-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '3.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.89.0
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.89.0
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: solargraph
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -104,6 +118,7 @@ extra_rdoc_files: []
104
118
  files:
105
119
  - ".gitignore"
106
120
  - ".rspec"
121
+ - ".rubocop.yml"
107
122
  - ".solargraph.yml"
108
123
  - Gemfile
109
124
  - Gemfile.lock