riml 0.3.7 → 0.3.8

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.
data/lib/riml.rb CHANGED
@@ -32,6 +32,9 @@ module Riml
32
32
  EXTRACT_COMPILE_OPTIONS = lambda { |k,_| DEFAULT_COMPILE_OPTIONS.keys.include?(k.to_sym) }
33
33
  EXTRACT_COMPILE_FILES_OPTIONS = lambda { |k,_| DEFAULT_COMPILE_FILES_OPTIONS.keys.include?(k.to_sym) }
34
34
 
35
+ FILENAME_OPTION_KEYS = [:commandline_filename, :sourced_filename]
36
+ EXTRACT_FILENAME_OPTIONS = lambda { |k,_| FILENAME_OPTION_KEYS.include?(k.to_sym) }
37
+
35
38
  # lex code (String) into tokens (Array)
36
39
  def self.lex(code)
37
40
  Lexer.new(code).tokenize
@@ -53,13 +56,14 @@ module Riml
53
56
  parser.options = DEFAULT_PARSE_OPTIONS.merge(parse_options)
54
57
  compiler = Compiler.new
55
58
  compiler.options = DEFAULT_COMPILE_OPTIONS.merge(compile_options)
56
- do_compile(input, parser, compiler)
59
+ filename_options = Hash[options.select(&EXTRACT_FILENAME_OPTIONS)]
60
+ do_compile(input, parser, compiler, filename_options)
57
61
  end
58
62
 
59
63
  # compile AST (Nodes), tokens (Array), code (String) or object that returns
60
64
  # String from :read to output code (String). Writes file(s) if `input` is a
61
65
  # File.
62
- def self.do_compile(input, parser = Parser.new, compiler = Compiler.new)
66
+ def self.do_compile(input, parser = Parser.new, compiler = Compiler.new, filename_options = {})
63
67
  if input.is_a?(Nodes)
64
68
  nodes = input
65
69
  elsif input.is_a?(String) || input.is_a?(Array)
@@ -73,17 +77,26 @@ module Riml
73
77
  "code (String) or respond_to?(:read), is #{input.inspect}"
74
78
  end
75
79
 
76
- if compiler.parser == parser
77
- compiling_cmdline_file = false
78
- else
79
- compiler.parser = parser
80
- compiling_cmdline_file = true
80
+ compiler.parser = parser
81
+
82
+ # This is to avoid cases where the file we're compiling from the
83
+ # commandline gets recompiled but put in a different location because
84
+ # it's also sourced, and `Riml.source_path` is set to a non-default value.
85
+ if input.is_a?(File)
86
+ pathname = Pathname.new(input.path)
87
+ full_path =
88
+ if pathname.absolute?
89
+ pathname.to_s
90
+ else
91
+ File.expand_path(input.path, compiler.output_dir || Dir.getwd)
92
+ end
93
+ compiler.sourced_files_compiled << full_path
81
94
  end
82
95
 
83
96
  output = compiler.compile(nodes)
84
97
 
85
98
  if input.is_a?(File)
86
- write_file(compiler, output, input.path, compiling_cmdline_file)
99
+ write_file(compiler, output, input.path, filename_options)
87
100
  else
88
101
  output
89
102
  end
@@ -125,7 +138,7 @@ module Riml
125
138
  threads << Thread.new do
126
139
  f = File.open(fname)
127
140
  # `do_compile` will close file handle
128
- do_compile(f, _parser, _compiler)
141
+ do_compile(f, _parser, _compiler, :commandline_filename => fname)
129
142
  end
130
143
  end
131
144
  threads.each(&:join)
@@ -136,7 +149,7 @@ module Riml
136
149
  fname = filenames.first
137
150
  f = File.open(fname)
138
151
  # `do_compile` will close file handle
139
- with_file_rollback { do_compile(f, parser, compiler) }
152
+ with_file_rollback { do_compile(f, parser, compiler, :commandline_filename => fname) }
140
153
  else
141
154
  raise ArgumentError, "need filenames to compile"
142
155
  end
@@ -268,10 +281,11 @@ module Riml
268
281
 
269
282
  # This is for when another file is sourced within a file we're compiling.
270
283
  def self.process_compile_queue!(compiler)
271
- while full_path = compiler.compile_queue.shift
284
+ while paths = compiler.compile_queue.shift
285
+ basename, full_path = *paths
272
286
  unless compiler.sourced_files_compiled.include?(full_path)
273
287
  compiler.sourced_files_compiled << full_path
274
- do_compile(File.open(full_path), compiler.parser, compiler)
288
+ do_compile(File.open(full_path), compiler.parser, compiler, :sourced_filename => basename)
275
289
  end
276
290
  end
277
291
  end
@@ -280,19 +294,30 @@ module Riml
280
294
  INCLUDE_COMMENT_FMT = File.read(File.expand_path("../riml/included.vim", __FILE__))
281
295
  GET_SID_FUNCTION_SRC = File.read(File.expand_path("../riml/get_sid_function.vim", __FILE__))
282
296
 
283
- def self.write_file(compiler, output, fname, cmdline_file = true)
297
+ # Files are written following these rules:
298
+ # If a filename is given from the commandline,
299
+ # 1) if the filename is absolute, output it to the directory in which the file resides
300
+ # 2) if there's an `output_dir` given, output the file to that directory
301
+ # 3) otherwise, output it into pwd
302
+ # If a filename is sourced,
303
+ # 1) if the filename is absolute, output it to the directory in which the file resides
304
+ # 2) otherwise, output it to the directory in which the `riml` file is found, checking `Riml.source_path`
305
+ def self.write_file(compiler, output, full_path, filename_options = {})
306
+ fname = filename_options[:commandline_filename] || filename_options[:sourced_filename]
307
+ fname or raise ArgumentError, "must pass correct filename_options"
284
308
  # writing out a file that's compiled from cmdline, output into output_dir
285
- output_dir = if cmdline_file
309
+ output_dir = if filename_options[:commandline_filename]
286
310
  compiler.output_dir || Dir.getwd
287
311
  # writing out a riml_source'd file
288
312
  else
289
- # absolute path for filename sent from cmdline or from riml_sourced files,
313
+ # absolute path for filename sent from riml_sourced files,
290
314
  # output to that same directory if no --output-dir option is set
291
- if fname[0, 1] == File::SEPARATOR && !compiler.output_dir
292
- Pathname.new(fname).parent.to_s
293
- # relative path
315
+ if full_path[0, 1] == File::SEPARATOR && !compiler.output_dir
316
+ Pathname.new(full_path).parent.to_s
317
+ # relative path, join it with output_dir
294
318
  else
295
- File.join(compiler.output_dir || Dir.getwd, Pathname.new(fname).parent.to_s)
319
+ rel_dir = Pathname.new(full_path).parent.to_s
320
+ File.join(compiler.output_dir || Dir.getwd, rel_dir)
296
321
  end
297
322
  end
298
323
  basename_without_riml_ext = File.basename(fname).sub(/\.riml\Z/i, '')
@@ -25,7 +25,6 @@ module Riml
25
25
  # "lib1.riml" => [], "lib2.riml" => [] }
26
26
  @included_and_sourced_file_refs = Hash.new { |h, k| h[k] = [] }
27
27
  @class_dependency_graph = class_dependency_graph || ClassDependencyGraph.new
28
- @class_dependency_graph.classes = @classes
29
28
  @resolving_class_dependencies = nil
30
29
  end
31
30
 
@@ -187,7 +186,7 @@ module Riml
187
186
 
188
187
  def class_name_full_name(class_name)
189
188
  return nil if class_name.nil?
190
- if class_name[1..1] == ':'
189
+ if class_name[1, 1] == ':'
191
190
  class_name
192
191
  else
193
192
  ClassDefinitionNode::DEFAULT_SCOPE_MODIFIER + class_name
@@ -20,7 +20,9 @@ module Riml
20
20
  raise ArgumentError, "first index must come before (or be equal to) last index"
21
21
  end
22
22
 
23
- unless Riml.debug
23
+ # check if `responds_to?(:debug)` because we don't want to have to require 'riml.rb'
24
+ # just for this
25
+ unless Riml.respond_to?(:debug) && Riml.debug
24
26
  add_to_head = @error.backtrace[0...first_i] || []
25
27
  add_to_tail = @error.backtrace[last_i...-1] || []
26
28
  backtrace = @error.backtrace[first_i..last_i] || []
@@ -1,5 +1,4 @@
1
1
  # topological sorting module from stdlib
2
- # uses Tarjan's algorithm for strongly connected components
3
2
  require 'tsort'
4
3
 
5
4
  module Riml
@@ -8,14 +7,12 @@ module Riml
8
7
  include TSort
9
8
 
10
9
  attr_reader :definition_graph, :encountered_graph
11
- # for checking imported classes
12
- attr_accessor :classes
13
10
 
14
11
  # definition_graph: { "faster_car.riml" => { "s:FasterCar" => "s:Car" }, "car.riml" => { "s:Car" => nil } }
15
12
  # encountered_graph: { "faster_car.riml" => ["s:FasterCar", "s:Car"], "car.riml" => ["s:Car"] }
16
- def initialize(definition_graph = {}, encountered_graph = {})
17
- @definition_graph = definition_graph
18
- @encountered_graph = encountered_graph
13
+ def initialize
14
+ @definition_graph = {}
15
+ @encountered_graph = {}
19
16
  @filename_graph = nil
20
17
  end
21
18
 
@@ -48,19 +45,17 @@ module Riml
48
45
  def prepare_filename_graph!
49
46
  @filename_graph = {}
50
47
  @encountered_graph.each do |filename, encountered_classes|
51
- # must be imported class or undefined class
52
- if @definition_graph[filename].nil?
53
- encountered_classes.each do |enc|
54
- # raises Riml::ClassNotFound if not found
55
- @classes[enc]
48
+ dependent_class_names =
49
+ if @definition_graph[filename].nil?
50
+ encountered_classes
51
+ else
52
+ class_names_defined_in_file = @definition_graph[filename].keys
53
+ # all superclass names that this file depends on
54
+ class_names_dependent_by_superclass = @definition_graph[filename].values.compact - class_names_defined_in_file
55
+ class_names_dependent_by_use = encountered_classes - class_names_defined_in_file
56
+ class_names_dependent_by_superclass + class_names_dependent_by_use
56
57
  end
57
- next
58
- end
59
- defined_in_filename = @definition_graph[filename].keys
60
- dependent_by_superclass = @definition_graph[filename].values.compact - defined_in_filename
61
- dependent_by_use = encountered_classes - (defined_in_filename + dependent_by_superclass)
62
- dependents = dependent_by_superclass + dependent_by_use
63
- dependents.each do |dep|
58
+ dependent_class_names.each do |dep|
64
59
  dependent_definition_fname = @definition_graph.detect { |fname, hash| hash.has_key?(dep) }.first rescue nil
65
60
  if dependent_definition_fname
66
61
  @filename_graph[filename] ||= []
data/lib/riml/compiler.rb CHANGED
@@ -603,7 +603,7 @@ module Riml
603
603
  if node.name == 'riml_source'
604
604
  node.name = 'source'
605
605
  node.each_existing_file! do |basename, full_path|
606
- current_compiler(node).compile_queue << full_path
606
+ current_compiler(node).compile_queue << [basename, full_path]
607
607
  end
608
608
  elsif node.name == 'riml_include'
609
609
  # riml_include has to be top-level
data/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Riml
2
- # release date: Nov. 17, 2013
3
- VERSION = [0,3,7]
2
+ # release date: Dec 4, 2013
3
+ VERSION = [0,3,8]
4
4
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: riml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.7
4
+ version: 0.3.8
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-11-17 00:00:00.000000000 Z
12
+ date: 2013-12-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: racc
@@ -153,7 +153,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
153
153
  version: '0'
154
154
  segments:
155
155
  - 0
156
- hash: -3912845296806528754
156
+ hash: 4386632180611596538
157
157
  requirements: []
158
158
  rubyforge_project:
159
159
  rubygems_version: 1.8.25