Module: Jade::CLI::Q

Defined in:
lib/jade/cli/q.rb

Overview

Headless query interface to the same compiler intelligence the LSP server uses. Intended for tools and agents that want a quick JSON answer instead of speaking JSON-RPC.

Defined Under Namespace

Classes: Context

Constant Summary collapse

USAGE =
<<~TXT.freeze
  Usage: jade q COMMAND [ARGS]

    hover   FILE:LINE:COL    Type info at the given position.
    symbols FILE             Document symbols (outline) for FILE.
    defn    FILE:LINE:COL    Goto-definition location.
    refs    FILE:LINE:COL    Find all references (incl. declaration).

  FILE is relative to the project root (cwd).
  LINE and COL are 0-indexed (LSP convention).

  Compile cache lives at .jade/cache, so repeat queries are fast.
TXT

Class Method Summary collapse

Class Method Details

.defn(arg) ⇒ Object



58
59
60
61
62
63
64
65
# File 'lib/jade/cli/q.rb', line 58

def defn(arg)
  file, line, col = parse_position(arg)
  Context.new(file).then do |ctx|
    Jade::LSP::Converters.definition_for_path(
      ctx.path_at(line, col), ctx.registry, ctx.entry, ctx.source_root
    )
  end
end

.dump(result) ⇒ Object



84
85
86
# File 'lib/jade/cli/q.rb', line 84

def dump(result)
  puts JSON.pretty_generate(result)
end

.hover(arg) ⇒ Object



39
40
41
42
43
44
45
46
# File 'lib/jade/cli/q.rb', line 39

def hover(arg)
  file, line, col = parse_position(arg)
  Context.new(file).then do |ctx|
    Jade::LSP::Converters.hover_for_path(
      ctx.path_at(line, col), ctx.registry, ctx.entry
    )
  end
end

.parse_position(arg) ⇒ Object



77
78
79
80
81
82
# File 'lib/jade/cli/q.rb', line 77

def parse_position(arg)
  fail 'FILE:LINE:COL required' unless arg
  fail "expected FILE:LINE:COL, got #{arg.inspect}" unless arg.count(':') == 2

  arg.split(':').then { |(file, line, col)| [file, line.to_i, col.to_i] }
end

.refs(arg) ⇒ Object



67
68
69
70
71
72
73
74
75
# File 'lib/jade/cli/q.rb', line 67

def refs(arg)
  file, line, col = parse_position(arg)
  Context.new(file).then do |ctx|
    Jade::LSP::Converters.references_for_path(
      ctx.path_at(line, col), ctx.registry, ctx.entry, ctx.source_root,
      include_declaration: true,
    )
  end
end

.run(argv) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
# File 'lib/jade/cli/q.rb', line 27

def run(argv)
  case argv[0]
  when 'hover'   then dump(hover(argv[1]))
  when 'symbols' then dump(symbols(argv[1]))
  when 'defn'    then dump(defn(argv[1]))
  when 'refs'    then dump(refs(argv[1]))
  else
    warn USAGE
    exit 1
  end
end

.symbols(file) ⇒ Object



48
49
50
51
52
53
54
55
56
# File 'lib/jade/cli/q.rb', line 48

def symbols(file)
  fail 'FILE required' unless file

  Context.new(file).entry.then do |entry|
    entry.ast.body.expressions.filter_map do |node|
      Jade::LSP::Converters.to_document_symbol(node, entry.source)
    end
  end
end