rbs 1.0.6 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +2 -2
  3. data/CHANGELOG.md +37 -0
  4. data/Rakefile +3 -2
  5. data/Steepfile +2 -0
  6. data/bin/rbs-prof +1 -1
  7. data/core/array.rbs +8 -4
  8. data/core/thread.rbs +14 -1
  9. data/lib/rbs.rb +3 -0
  10. data/lib/rbs/ancestor_graph.rb +90 -0
  11. data/lib/rbs/char_scanner.rb +20 -0
  12. data/lib/rbs/definition_builder.rb +38 -20
  13. data/lib/rbs/definition_builder/method_builder.rb +14 -0
  14. data/lib/rbs/environment.rb +42 -5
  15. data/lib/rbs/environment_walker.rb +4 -4
  16. data/lib/rbs/errors.rb +32 -17
  17. data/lib/rbs/parser.rb +437 -416
  18. data/lib/rbs/parser.y +29 -16
  19. data/lib/rbs/test/type_check.rb +7 -3
  20. data/lib/rbs/version.rb +1 -1
  21. data/sig/ancestor_graph.rbs +40 -0
  22. data/sig/char_scanner.rbs +9 -0
  23. data/sig/definition_builder.rbs +5 -1
  24. data/sig/environment.rbs +22 -2
  25. data/sig/environment_walker.rbs +39 -0
  26. data/sig/errors.rbs +42 -17
  27. data/sig/method_builder.rbs +2 -0
  28. data/sig/parser.rbs +11 -4
  29. data/sig/polyfill.rbs +0 -14
  30. data/stdlib/cgi/0/core.rbs +595 -0
  31. data/stdlib/rubygems/0/basic_specification.rbs +3 -0
  32. data/stdlib/rubygems/0/config_file.rbs +3 -0
  33. data/stdlib/rubygems/0/dependency_installer.rbs +5 -0
  34. data/stdlib/rubygems/0/installer.rbs +3 -0
  35. data/stdlib/rubygems/0/path_support.rbs +3 -0
  36. data/stdlib/rubygems/0/platform.rbs +3 -0
  37. data/stdlib/rubygems/0/request_set.rbs +7 -0
  38. data/stdlib/rubygems/0/requirement.rbs +3 -0
  39. data/stdlib/rubygems/0/rubygems.rbs +710 -0
  40. data/stdlib/rubygems/0/source_list.rbs +2 -0
  41. data/stdlib/rubygems/0/specification.rbs +3 -0
  42. data/stdlib/rubygems/0/stream_ui.rbs +3 -0
  43. data/stdlib/rubygems/0/uninstaller.rbs +3 -0
  44. data/stdlib/rubygems/0/version.rbs +228 -0
  45. data/stdlib/strscan/0/string_scanner.rbs +582 -0
  46. metadata +23 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0c8f0c698e503246f1952a9f05aed05cd1a820d4ea67721970497664bf0ee3fd
4
- data.tar.gz: bf2d2e438893b213ad750d1fcd71c9d1b318f9cff1f2212ee65a3dc50cf43e39
3
+ metadata.gz: e7a862e1af5773b464ebf201344cf823512ca551df1f827825328863225a26c8
4
+ data.tar.gz: 2853162048f342a1dad949b518887e82bc4ede46d79d57626fabb49e2edf920d
5
5
  SHA512:
6
- metadata.gz: 53fd4afc4d095999f7a03d6199af9cdd1009a378ebd2976c690c54a2bd2aed81d129912c70a16914733bd252a58e50223f9090bd995ca53a01a1acef513efd4a
7
- data.tar.gz: b976e7a9c8bd2b80912290d7047403cfc2d7b09ed405e82aa52b75e9ed19737c144bc9c62d72f0ddcf2839117400d3e5207952753fb73097b21fdfd1192d214f
6
+ metadata.gz: 99fbc15297542d7d0bd952806556b128e071a7f31e0f175b573f77c00db3ec4a6ddd473f33aaf170f2a08f99991939cbcc0484d4287413c9e2b55dfbadc7dff0
7
+ data.tar.gz: 3553c8cc89269a9579ccd52d3c9f61bd44f4f6117856da23726930c5c5b17f5aa5da7f1d69a9748fffc1b2fe62587149856a2c1ddee0fed79fb155be6aee6037
@@ -27,10 +27,10 @@ jobs:
27
27
  run: |
28
28
  apt-get update
29
29
  apt-get install -y libdb-dev
30
- - name: Install bundler
30
+ - name: Update rubygems & bundler
31
31
  run: |
32
32
  ruby -v
33
- gem install bundler
33
+ gem update --system
34
34
  - name: bundle config set with
35
35
  run: |
36
36
  echo "NO_MINITEST=true" >> $GITHUB_ENV
data/CHANGELOG.md CHANGED
@@ -2,6 +2,43 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 1.1.0 (2021-03-08)
6
+
7
+ ### Summary
8
+
9
+ Errors are now organized by `RBS::BaseError`, `RBS::ParsingError`, `RBS::LoadingError`, and `RBS::DefinitionError`.
10
+ The library users can rescue RBS related errors with `RBS::BaseError`, parsing errors with `RBS::ParsingError`, and other errors with `RBS::LoadingError` and `RBS::DefinitionErrors`.
11
+
12
+ Updating a part of environments are supported. Library users can remove declarations read from a set of files, adding new declarations, running name resolution related to the new decls, and deleting `DefinitionBuilder` caches related to the changes.
13
+ See `RBS::Environment#reject`, `RBS::Environment#resolve_type_names`, `RBS::AncestorGraph`, and `RBS::DefinitionBuilder#update`.
14
+
15
+ `RBS::DefinitionBuilder#build_singleton` now returns definitions containing `instance` type, which had returned resolved class instance types. This is a breaking change, but we consider it a bug fix because `RBS::DefinitionBuilder#build_instance` has returned `instance` types and `#build_singleton` has returned `class` type.
16
+
17
+ ### Signature updates
18
+
19
+ * rubygem ([\#605](https://github.com/ruby/rbs/pull/605), [\#610](https://github.com/ruby/rbs/pull/610))
20
+ * Array ([\#612](https://github.com/ruby/rbs/pull/612), [\#614](https://github.com/ruby/rbs/pull/614))
21
+ * cgi/core ([\#599](https://github.com/ruby/rbs/pull/599))
22
+ * Thread ([\#618](https://github.com/ruby/rbs/pull/618))
23
+
24
+ ### Language updates
25
+
26
+ * Allow trailing comma for Record and Tuple types ([\#606](https://github.com/ruby/rbs/pull/606))
27
+
28
+ ### Library changes
29
+
30
+ * Allow partial update of RBS declarations ([\#608](https://github.com/ruby/rbs/pull/608), [\#621](https://github.com/ruby/rbs/pull/621))
31
+ * Let errors have `TypeName` ([\#611](https://github.com/ruby/rbs/pull/611))
32
+ * Add `Parser::LexerError` ([\#615](https://github.com/ruby/rbs/pull/615))
33
+ * Performance improvement ([\#617](https://github.com/ruby/rbs/pull/617), [\#620](https://github.com/ruby/rbs/pull/620))
34
+ * No substitute `instance` types on `#build_singleton` ([\#619](https://github.com/ruby/rbs/pull/619))
35
+
36
+ ### Miscellaneous
37
+
38
+ * Make racc name customizable by `RACC` environment variable ([\#602](https://github.com/ruby/rbs/pull/602))
39
+ * Suppress warnings ([\#624](https://github.com/ruby/rbs/pull/624))
40
+ * Remove needless `Gem::Version` polyfill ([\#622](https://github.com/ruby/rbs/pull/622))
41
+
5
42
  ## 1.0.6 (2021-02-17)
6
43
 
7
44
  * Signature Updates
data/Rakefile CHANGED
@@ -3,6 +3,7 @@ require "rake/testtask"
3
3
  require "rbconfig"
4
4
 
5
5
  ruby = ENV["RUBY"] || RbConfig.ruby
6
+ racc = ENV.fetch("RACC", "racc")
6
7
  rbs = File.join(__dir__, "exe/rbs")
7
8
  bin = File.join(__dir__, "bin")
8
9
 
@@ -67,7 +68,7 @@ task :rubocop do
67
68
  end
68
69
 
69
70
  rule ".rb" => ".y" do |t|
70
- sh "racc -v -o #{t.name} #{t.source}"
71
+ sh "#{racc} -v -o #{t.name} #{t.source}"
71
72
  end
72
73
 
73
74
  task :parser => "lib/rbs/parser.rb"
@@ -77,7 +78,7 @@ task :build => :parser
77
78
 
78
79
  task :confirm_parser do
79
80
  puts "Testing if parser.rb is updated with respect to parser.y"
80
- sh "racc -v -o lib/rbs/parser.rb lib/rbs/parser.y"
81
+ sh "#{racc} -v -o lib/rbs/parser.rb lib/rbs/parser.y"
81
82
  sh "git diff --exit-code lib/rbs/parser.rb"
82
83
  end
83
84
 
data/Steepfile CHANGED
@@ -5,6 +5,8 @@ target :lib do
5
5
  ignore "lib/rbs/prototype", "lib/rbs/test", "lib/rbs/test.rb"
6
6
 
7
7
  library "set", "pathname", "json", "logger", "monitor", "tsort"
8
+ signature "stdlib/strscan/0/"
9
+ signature "stdlib/rubygems/0/"
8
10
  end
9
11
 
10
12
  # target :lib do
data/bin/rbs-prof CHANGED
@@ -4,6 +4,6 @@ require "stackprof"
4
4
 
5
5
  out = ENV["RBS_STACKPROF_OUT"] || 'tmp/stackprof-cpu-rbs.dump'
6
6
 
7
- StackProf.run(mode: :cpu, out: out) do
7
+ StackProf.run(mode: :cpu, out: out, raw: true) do
8
8
  load File.join(__dir__, "../exe/rbs")
9
9
  end
data/core/array.rbs CHANGED
@@ -1584,8 +1584,8 @@ class Array[unchecked out Elem] < Object
1584
1584
  # a.sample(random: Random.new(1)) #=> 6
1585
1585
  # a.sample(4, random: Random.new(1)) #=> [6, 10, 9, 2]
1586
1586
  #
1587
- def sample: (?random: Random rng) -> Elem?
1588
- | (?int n, ?random: Random rng) -> ::Array[Elem]
1587
+ def sample: (?random: _Rand rng) -> Elem?
1588
+ | (?int n, ?random: _Rand rng) -> ::Array[Elem]
1589
1589
 
1590
1590
  # Returns a new array containing all elements of `ary` for which the given
1591
1591
  # `block` returns a true value.
@@ -1649,7 +1649,7 @@ class Array[unchecked out Elem] < Object
1649
1649
  #
1650
1650
  # a.shuffle(random: Random.new(1)) #=> [1, 3, 2]
1651
1651
  #
1652
- def shuffle: (?random: Random rng) -> ::Array[Elem]
1652
+ def shuffle: (?random: _Rand rng) -> ::Array[Elem]
1653
1653
 
1654
1654
  # Shuffles elements in `self` in place.
1655
1655
  #
@@ -1661,7 +1661,7 @@ class Array[unchecked out Elem] < Object
1661
1661
  #
1662
1662
  # a.shuffle!(random: Random.new(1)) #=> [1, 3, 2]
1663
1663
  #
1664
- def shuffle!: (?random: Random rng) -> self
1664
+ def shuffle!: (?random: _Rand rng) -> self
1665
1665
 
1666
1666
  alias size length
1667
1667
 
@@ -1997,6 +1997,10 @@ interface _ToAry[T]
1997
1997
  def to_ary: () -> ::Array[T]
1998
1998
  end
1999
1999
 
2000
+ interface _Rand
2001
+ def rand: (::Integer max) -> ::Integer
2002
+ end
2003
+
2000
2004
  interface Array::_Pattern[T]
2001
2005
  def ===: (T) -> bool
2002
2006
  end
data/core/thread.rbs CHANGED
@@ -287,7 +287,20 @@ class Thread < Object
287
287
 
288
288
  def group: () -> ThreadGroup?
289
289
 
290
- def initialize: (*untyped args) -> Thread
290
+ # Creates a new thread executing the given block.
291
+ #
292
+ # Any `args` given to ::new will be passed to the block:
293
+ #
294
+ # arr = []
295
+ # a, b, c = 1, 2, 3
296
+ # Thread.new(a,b,c) { |d,e,f| arr << d << e << f }.join
297
+ # arr #=> [1, 2, 3]
298
+ #
299
+ # A ThreadError exception is raised if ::new is called without a block.
300
+ #
301
+ # If you're going to subclass Thread, be sure to call super in your `initialize`
302
+ # method, otherwise a ThreadError will be raised.
303
+ def initialize: (*untyped) { (*untyped) -> void } -> void
291
304
 
292
305
  # The calling thread will suspend execution and run this `thr` .
293
306
  #
data/lib/rbs.rb CHANGED
@@ -7,7 +7,9 @@ require "pp"
7
7
  require "ripper"
8
8
  require "logger"
9
9
  require "tsort"
10
+ require "strscan"
10
11
 
12
+ require "rbs/char_scanner"
11
13
  require "rbs/errors"
12
14
  require "rbs/buffer"
13
15
  require "rbs/location"
@@ -40,6 +42,7 @@ require "rbs/vendorer"
40
42
  require "rbs/validator"
41
43
  require "rbs/factory"
42
44
  require "rbs/repository"
45
+ require "rbs/ancestor_graph"
43
46
 
44
47
  begin
45
48
  require "rbs/parser"
@@ -0,0 +1,90 @@
1
+ module RBS
2
+ class AncestorGraph
3
+ InstanceNode = _ = Struct.new(:type_name, keyword_init: true)
4
+ SingletonNode = _ = Struct.new(:type_name, keyword_init: true)
5
+
6
+ attr_reader :env
7
+ attr_reader :ancestor_builder
8
+ attr_reader :parents
9
+ attr_reader :children
10
+
11
+ def initialize(env:, ancestor_builder: DefinitionBuilder::AncestorBuilder.new(env: env))
12
+ @env = env
13
+ @ancestor_builder = ancestor_builder
14
+ build()
15
+ end
16
+
17
+ def build()
18
+ @parents = {}
19
+ @children = {}
20
+
21
+ env.class_decls.each_key do |type_name|
22
+ build_ancestors(InstanceNode.new(type_name: type_name), ancestor_builder.one_instance_ancestors(type_name))
23
+ build_ancestors(SingletonNode.new(type_name: type_name), ancestor_builder.one_singleton_ancestors(type_name))
24
+ end
25
+ env.interface_decls.each_key do |type_name|
26
+ build_ancestors(InstanceNode.new(type_name: type_name), ancestor_builder.one_interface_ancestors(type_name))
27
+ end
28
+ end
29
+
30
+ def build_ancestors(node, ancestors)
31
+ ancestors.each_ancestor do |ancestor|
32
+ case ancestor
33
+ when Definition::Ancestor::Instance
34
+ register(child: node, parent: InstanceNode.new(type_name: ancestor.name))
35
+ when Definition::Ancestor::Singleton
36
+ register(child: node, parent: SingletonNode.new(type_name: ancestor.name))
37
+ end
38
+ end
39
+ end
40
+
41
+ def register(parent:, child:)
42
+ (parents[child] ||= Set[]) << parent
43
+ (children[parent] ||= Set[]) << child
44
+ end
45
+
46
+ def each_parent(node, &block)
47
+ if block
48
+ parents[node]&.each(&block)
49
+ else
50
+ enum_for :each_parent, node
51
+ end
52
+ end
53
+
54
+ def each_child(node, &block)
55
+ if block
56
+ children[node]&.each(&block)
57
+ else
58
+ enum_for :each_child, node
59
+ end
60
+ end
61
+
62
+ def each_ancestor(node, yielded: Set[], &block)
63
+ if block
64
+ each_parent(node) do |parent|
65
+ unless yielded.member?(parent)
66
+ yielded << parent
67
+ yield parent
68
+ each_ancestor(parent, yielded: yielded, &block)
69
+ end
70
+ end
71
+ else
72
+ enum_for :each_ancestor, node
73
+ end
74
+ end
75
+
76
+ def each_descendant(node, yielded: Set[], &block)
77
+ if block
78
+ each_child(node) do |child|
79
+ unless yielded.member?(child)
80
+ yielded << child
81
+ yield child
82
+ each_descendant(child, yielded: yielded, &block)
83
+ end
84
+ end
85
+ else
86
+ enum_for :each_descendant, node
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,20 @@
1
+ module RBS
2
+ class CharScanner < StringScanner
3
+ def initialize(string)
4
+ super(string)
5
+ @charpos = 0
6
+ end
7
+
8
+ alias original_charpos charpos
9
+
10
+ def charpos
11
+ @charpos
12
+ end
13
+
14
+ def scan(pattern)
15
+ s = super
16
+ @charpos += s.size if s
17
+ s
18
+ end
19
+ end
20
+ end
@@ -10,11 +10,11 @@ module RBS
10
10
  attr_reader :singleton0_cache
11
11
  attr_reader :interface_cache
12
12
 
13
- def initialize(env:)
13
+ def initialize(env:, ancestor_builder: nil, method_builder: nil)
14
14
  @env = env
15
15
  @type_name_resolver = TypeNameResolver.from_env(env)
16
- @ancestor_builder = AncestorBuilder.new(env: env)
17
- @method_builder = MethodBuilder.new(env: env)
16
+ @ancestor_builder = ancestor_builder || AncestorBuilder.new(env: env)
17
+ @method_builder = method_builder || MethodBuilder.new(env: env)
18
18
 
19
19
  @instance_cache = {}
20
20
  @singleton_cache = {}
@@ -80,6 +80,7 @@ module RBS
80
80
  when AST::Members::Alias
81
81
  unless definition.methods.key?(original.old_name)
82
82
  raise UnknownMethodAliasError.new(
83
+ type_name: type_name,
83
84
  original_name: original.old_name,
84
85
  aliased_name: original.new_name,
85
86
  location: original.location
@@ -360,15 +361,10 @@ module RBS
360
361
  when Environment::ClassEntry, Environment::ModuleEntry
361
362
  ancestors = ancestor_builder.singleton_ancestors(type_name)
362
363
  self_type = Types::ClassSingleton.new(name: type_name, location: nil)
363
- instance_type = Types::ClassInstance.new(
364
- name: type_name,
365
- args: entry.type_params.each.map { Types::Bases::Any.new(location: nil) },
366
- location: nil
367
- )
368
364
 
369
365
  Definition.new(type_name: type_name, entry: entry, self_type: self_type, ancestors: ancestors).tap do |definition|
370
366
  def0 = build_singleton0(type_name)
371
- subst = Substitution.build([], [], instance_type: instance_type)
367
+ subst = Substitution.new
372
368
 
373
369
  merge_definition(src: def0, dest: definition, subst: subst, keep_super: true)
374
370
 
@@ -561,6 +557,7 @@ module RBS
561
557
 
562
558
  unless original_method
563
559
  raise UnknownMethodAliasError.new(
560
+ type_name: definition.type_name,
564
561
  original_name: original.old_name,
565
562
  aliased_name: original.new_name,
566
563
  location: original.location
@@ -730,11 +727,13 @@ module RBS
730
727
  end
731
728
 
732
729
  def merge_method(type_name, methods, name, method, sub, implemented_in: :keep, keep_super: false)
733
- defs = method.defs.yield_self do |defs|
730
+ if sub.empty? && implemented_in == :keep && keep_super
731
+ methods[name] = method
732
+ else
734
733
  if sub.empty? && implemented_in == :keep
735
- defs
734
+ defs = method.defs
736
735
  else
737
- defs.map do |defn|
736
+ defs = method.defs.map do |defn|
738
737
  defn.update(
739
738
  type: sub.empty? ? defn.type : defn.type.sub(sub),
740
739
  implemented_in: case implemented_in
@@ -748,16 +747,16 @@ module RBS
748
747
  )
749
748
  end
750
749
  end
751
- end
752
750
 
753
- super_method = methods[name]
751
+ super_method = methods[name]
754
752
 
755
- methods[name] = Definition::Method.new(
756
- super_method: keep_super ? method.super_method : super_method,
757
- accessibility: method.accessibility,
758
- defs: defs,
759
- alias_of: method.alias_of
760
- )
753
+ methods[name] = Definition::Method.new(
754
+ super_method: keep_super ? method.super_method : super_method,
755
+ accessibility: method.accessibility,
756
+ defs: defs,
757
+ alias_of: method.alias_of
758
+ )
759
+ end
761
760
  end
762
761
 
763
762
  def try_cache(type_name, cache:, key: type_name)
@@ -788,5 +787,24 @@ module RBS
788
787
  ensure_namespace!(type_name.namespace, location: entry.decl.location)
789
788
  entry.decl.type
790
789
  end
790
+
791
+ def update(env:, except:, ancestor_builder:)
792
+ method_builder = self.method_builder.update(env: env, except: except)
793
+
794
+ DefinitionBuilder.new(env: env, ancestor_builder: ancestor_builder, method_builder: method_builder).tap do |builder|
795
+ builder.instance_cache.merge!(instance_cache)
796
+ builder.singleton_cache.merge!(singleton_cache)
797
+ builder.singleton0_cache.merge!(singleton0_cache)
798
+ builder.interface_cache.merge!(interface_cache)
799
+
800
+ except.each do |name|
801
+ builder.instance_cache.delete([name, true])
802
+ builder.instance_cache.delete([name, false])
803
+ builder.singleton_cache.delete(name)
804
+ builder.singleton0_cache.delete(name)
805
+ builder.interface_cache.delete(name)
806
+ end
807
+ end
808
+ end
791
809
  end
792
810
  end
@@ -219,6 +219,20 @@ module RBS
219
219
  end
220
220
  end
221
221
  end
222
+
223
+ def update(env:, except:)
224
+ MethodBuilder.new(env: env).tap do |copy|
225
+ copy.instance_methods.merge!(instance_methods)
226
+ copy.singleton_methods.merge!(singleton_methods)
227
+ copy.interface_methods.merge!(interface_methods)
228
+
229
+ except.each do |type_name|
230
+ copy.instance_methods.delete(type_name)
231
+ copy.singleton_methods.delete(type_name)
232
+ copy.interface_methods.delete(type_name)
233
+ end
234
+ end
235
+ end
222
236
  end
223
237
  end
224
238
  end
@@ -1,6 +1,5 @@
1
1
  module RBS
2
2
  class Environment
3
- attr_reader :buffers
4
3
  attr_reader :declarations
5
4
 
6
5
  attr_reader :class_decls
@@ -169,7 +168,7 @@ module RBS
169
168
  # @type var decl: AST::Declarations::Class
170
169
  existing_entry.insert(decl: decl, outer: outer)
171
170
  else
172
- raise DuplicatedDeclarationError.new(name, decl, existing_entry.primary.decl)
171
+ raise DuplicatedDeclarationError.new(name, decl, existing_entry.decls[0].decl)
173
172
  end
174
173
 
175
174
  prefix = outer + [decl]
@@ -204,12 +203,22 @@ module RBS
204
203
  self
205
204
  end
206
205
 
207
- def resolve_type_names
206
+ def validate_type_params
207
+ class_decls.each_value do |decl|
208
+ decl.primary
209
+ end
210
+ end
211
+
212
+ def resolve_type_names(only: nil)
208
213
  resolver = TypeNameResolver.from_env(self)
209
214
  env = Environment.new()
210
215
 
211
216
  declarations.each do |decl|
212
- env << resolve_declaration(resolver, decl, outer: [], prefix: Namespace.root)
217
+ if only && !only.member?(decl)
218
+ env << decl
219
+ else
220
+ env << resolve_declaration(resolver, decl, outer: [], prefix: Namespace.root)
221
+ end
213
222
  end
214
223
 
215
224
  env
@@ -431,8 +440,36 @@ module RBS
431
440
  end
432
441
 
433
442
  def inspect
434
- ivars = %i[@buffers @declarations @class_decls @interface_decls @alias_decls @constant_decls @global_decls]
443
+ ivars = %i[@declarations @class_decls @interface_decls @alias_decls @constant_decls @global_decls]
435
444
  "\#<RBS::Environment #{ivars.map { |iv| "#{iv}=(#{instance_variable_get(iv).size} items)"}.join(' ')}>"
436
445
  end
446
+
447
+ def buffers
448
+ buffers_decls.keys.compact
449
+ end
450
+
451
+ def buffers_decls
452
+ # @type var hash: Hash[Buffer, Array[AST::Declarations::t]]
453
+ hash = {}
454
+
455
+ declarations.each do |decl|
456
+ location = decl.location or next
457
+ (hash[location.buffer] ||= []) << decl
458
+ end
459
+
460
+ hash
461
+ end
462
+
463
+ def reject
464
+ env = Environment.new
465
+
466
+ declarations.each do |decl|
467
+ unless yield(decl)
468
+ env << decl
469
+ end
470
+ end
471
+
472
+ env
473
+ end
437
474
  end
438
475
  end