class ExportableGrammar

Represents a partial Grammar object

@note this has additional behavior to allow for partial grammars to reuse non exported keys @note only one may exist per file

Attributes

exports[RW]

@return [Array<Symbol>] names that will be exported by the grammar partial

external_repos[RW]

@return [Array<Symbol>] external names the this grammar partial may reference

parent_grammar[RW]

Grammars that are a parent to this grammar partial

@api private @return [Grammar]

Public Class Methods

new() click to toggle source

Initialize a new Exportable Grammar @note use {Grammar.new_exportable_grammar} instead

Calls superclass method Grammar::new
# File lib/textmate_grammar/grammar.rb, line 544
def initialize
    # skip: initialize, new, and new_exportable_grammar
    location = caller_locations(3, 1).first
    # and the first 5 bytes of the hash to get the seed
    # will not be unique if multiple exportable grammars are created in the same file
    # Don't do that
    @seed = Digest::MD5.hexdigest(File.basename(location.path))[0..10]
    super(
        name: "export",
        scope_name: "export"
    )

    if @@export_grammars[location.path].is_a? Hash
        return if @@export_grammars[location.path][:line] == location.lineno

        raise "Only one export grammar is allowed per file"
    end
    @@export_grammars[location.path] = {
        line: location.lineno,
        grammar: self,
    }

    @parent_grammar = []
end

Public Instance Methods

[]=(key, value) click to toggle source

(see Grammar#[]=)

@note grammar partials cannot constribute to $initial_context

Calls superclass method Grammar#[]=
# File lib/textmate_grammar/grammar.rb, line 574
def []=(key, value)
    if key.to_s == "$initial_context"
        puts "ExportGrammar cannot store to $initial_context"
        raise "See error above"
    end
    super(key, value)

    parent_grammar.each { |g| g.import self }
end
export() click to toggle source

Modifies the ExportableGrammar to namespace unexported keys

@return [self]

# File lib/textmate_grammar/grammar.rb, line 589
def export
    @repository.transform_keys! do |key|
        next if [:$initial_context, :$base, :$self].include? key

        # convert all repository keys to a prefixed version unless in exports
        if key.to_s.start_with? @seed
            # if exports has changed remove the seed
            bare_key = (key.to_s.split(@seed + "_")[1]).to_sym
            next bare_key if @exports.include? bare_key

            next key
        end

        next key if @exports.include? key

        (@seed + "_" + key.to_s).to_sym
    end
    # prefix all include symbols unless in external_repos or exports
    @repository.transform_values! { |v| fixupValue(v) }
    # ensure the grammar does not refer to a symbol not in repository or external_repos
    # ensure the grammar has all keys named in exports
    exports.each do |key|
        unless @repository.has_key? key
            raise "#{key} is exported but is missing in the repository"
        end
    end
    self
end

Private Instance Methods

fixupValue(value) click to toggle source
# File lib/textmate_grammar/grammar.rb, line 620
def fixupValue(value)
    # TDOD: rename this function it is too similar to fixup_value
    if value.is_a? Symbol
        return value if [:$initial_context, :$base, :$self].include? value

        if value.to_s.start_with? @seed
            # if exports or external_repos, has changed remove the seed
            bare_value = (value.to_s.split(@seed + "_")[1]).to_sym
            if @external_repos.include?(bare_value) || @exports.include?(bare_value)
                return bare_value
            end

            return value
        end

        return value if @external_repos.include?(value) || @exports.include?(value)

        (@seed + "_" + value.to_s).to_sym
    elsif value.is_a? Array
        value.map { |v| fixupValue(v) }
    elsif value.is_a? PatternBase
        value
    else
        raise "Unexpected object of type #{value.class} in value"
    end
end