Class: Ibex::Frontend::SourceLoader
- Inherits:
-
Object
- Object
- Ibex::Frontend::SourceLoader
- Defined in:
- lib/ibex/frontend/source_loader.rb,
sig/ibex/frontend/source_loader.rbs
Overview
Resolves canonical grammar paths and reads either open-buffer overlays or disk.
Instance Method Summary collapse
-
#canonical_missing_path(expanded) ⇒ String
Resolve the nearest existing ancestor so symlink escapes remain visible for new files.
-
#canonical_path(path, base: Dir.pwd, allow_missing: false) ⇒ String
Canonicalize an existing file, or a missing path explicitly allowed by an open overlay.
-
#delete_overlay(path) ⇒ String
Remove an editor buffer and return its canonical path.
- #disk_file?(path) ⇒ Boolean
-
#disk_path(path) ⇒ String
Resolve the current disk target without consulting overlay aliases.
-
#disk_source(path) ⇒ String
Read disk while deliberately bypassing an open overlay.
- #file?(path) ⇒ Boolean
-
#initialize(overlays: {}, record_reads: false) ⇒ SourceLoader
constructor
A new instance of SourceLoader.
- #overlay?(path) ⇒ Boolean
- #read(path) ⇒ String
- #read_records ⇒ Array[GenerationInput]
-
#record_access(canonical, access_path) ⇒ void
Associate the lexical path used by a resolver with its canonical source.
-
#set_overlay(path, source) ⇒ String
Install or replace an editor buffer without writing it to disk.
Constructor Details
#initialize(overlays: {}, record_reads: false) ⇒ SourceLoader
Returns a new instance of SourceLoader.
30 31 32 33 34 35 36 37 |
# File 'lib/ibex/frontend/source_loader.rb', line 30 def initialize(overlays: {}, record_reads: false) @overlays = {} #: Hash[String, String] @aliases = {} #: Hash[String, String] @read_records = {} #: Hash[String, GenerationInput] @record_reads = record_reads @access_paths = {} #: Hash[String, Array[String]] .each { |path, source| (path, source) } end |
Instance Method Details
#canonical_missing_path(expanded) ⇒ String
Resolve the nearest existing ancestor so symlink escapes remain visible for new files.
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/ibex/frontend/source_loader.rb', line 131 def canonical_missing_path() raise Errno::ENOENT, if File.symlink?() cursor = suffix = [] #: Array[String] loop do parent = File.dirname(cursor) raise Errno::ENOENT, if parent == cursor suffix.unshift(File.basename(cursor)) cursor = parent break if File.exist?(cursor) || File.symlink?(cursor) end raise Errno::ENOTDIR, cursor unless File.directory?(File.realpath(cursor)) File.join(File.realpath(cursor), *suffix) end |
#canonical_path(path, base: Dir.pwd, allow_missing: false) ⇒ String
Canonicalize an existing file, or a missing path explicitly allowed by an open overlay.
41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/ibex/frontend/source_loader.rb', line 41 def canonical_path(path, base: Dir.pwd, allow_missing: false) = File.(path, base) aliased = @aliases[] return aliased if aliased begin File.realpath() rescue Errno::ENOENT canonical = canonical_missing_path() return canonical if allow_missing || @overlays.key?(canonical) raise end end |
#delete_overlay(path) ⇒ String
Remove an editor buffer and return its canonical path.
100 101 102 103 104 105 106 |
# File 'lib/ibex/frontend/source_loader.rb', line 100 def (path) = File.(path) canonical = @aliases.delete() || canonical_path(, allow_missing: true) @aliases.delete_if { |_alias_path, target| target == canonical } @overlays.delete(canonical) canonical end |
#disk_file?(path) ⇒ Boolean
115 116 117 118 119 |
# File 'lib/ibex/frontend/source_loader.rb', line 115 def disk_file?(path) File.file?(disk_path(path)) rescue SystemCallError false end |
#disk_path(path) ⇒ String
Resolve the current disk target without consulting overlay aliases.
123 124 125 |
# File 'lib/ibex/frontend/source_loader.rb', line 123 def disk_path(path) File.realpath(File.(path)) end |
#disk_source(path) ⇒ String
Read disk while deliberately bypassing an open overlay.
110 111 112 |
# File 'lib/ibex/frontend/source_loader.rb', line 110 def disk_source(path) File.binread(disk_path(path)) end |
#file?(path) ⇒ Boolean
71 72 73 74 75 76 |
# File 'lib/ibex/frontend/source_loader.rb', line 71 def file?(path) canonical = canonical_path(path, allow_missing: true) @overlays.key?(canonical) || File.file?(canonical) rescue SystemCallError false end |
#overlay?(path) ⇒ Boolean
79 80 81 82 83 84 |
# File 'lib/ibex/frontend/source_loader.rb', line 79 def (path) canonical = canonical_path(path, allow_missing: true) @overlays.key?(canonical) rescue SystemCallError false end |
#read(path) ⇒ String
57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/ibex/frontend/source_loader.rb', line 57 def read(path) canonical = canonical_path(path, allow_missing: true) = @overlays[canonical] source = || File.binread(canonical) if @record_reads record = GenerationInput.new(canonical, source) (@access_paths[canonical] || []).each { |access| record.add_access_path(access) } @read_records[canonical] = record end source end |
#read_records ⇒ Array[GenerationInput]
16 17 18 |
# File 'lib/ibex/frontend/source_loader.rb', line 16 def read_records @read_records.values end |
#record_access(canonical, access_path) ⇒ void
This method returns an undefined value.
Associate the lexical path used by a resolver with its canonical source.
22 23 24 25 26 27 |
# File 'lib/ibex/frontend/source_loader.rb', line 22 def record_access(canonical, access_path) paths = (@access_paths[canonical] ||= []) = File.(access_path) paths << unless paths.include?() @read_records[canonical]&.add_access_path() end |
#set_overlay(path, source) ⇒ String
Install or replace an editor buffer without writing it to disk.
88 89 90 91 92 93 94 95 96 |
# File 'lib/ibex/frontend/source_loader.rb', line 88 def (path, source) = File.(path) canonical = canonical_path(, allow_missing: true) raise ArgumentError, "overlay path must not be a directory" if File.directory?(canonical) @aliases[] = canonical @overlays[canonical] = source.dup.freeze canonical end |