Class: Ryac::Pipeline::Stage

Inherits:
Object
  • Object
show all
Includes:
SourcePatcher
Defined in:
lib/ryac/pipeline/stage.rb,
sig/ryac/pipeline/stage.rbs

Overview

The one stage contract.

A stage declares what it needs (needs_analysis?), whether it must be re-run to a fixed point (fixpoint?), collects byte patches against the context, and contributes aliases/preamble in finish. Parsing, patch application and iteration belong to the runner, never to the stage.

Class Method Summary collapse

Instance Method Summary collapse

Methods included from SourcePatcher

#apply_patches, #mk, #src, #verify_parses

Class Method Details

.new ⇒ Stage

Parameters:

  • (Object)

Returns:



16
# File 'sig/ryac/pipeline/stage.rbs', line 16

def self.new: (**untyped) -> Stage

Instance Method Details

#analysis(ctx) ⇒ AnalysisResult

Analysis stages run only inside the runner's batch, which always supplies the AnalysisResult.

Parameters:

Returns:



71
72
73
# File 'lib/ryac/pipeline/stage.rb', line 71

def analysis(ctx)
  ctx.analysis #: AnalysisResult
end

#analysis_options ⇒ Hash[Symbol, untyped]

Keyword options this stage needs the analysis batch's Analyzer to honor. The runner merges every batch member's contribution.

Returns:

  • (Hash[Symbol, untyped])


33
# File 'lib/ryac/pipeline/stage.rb', line 33

def analysis_options = {}

#call(input) ⇒ String

Driver for a standalone syntactic stage: the per-stage public API.

Parameters:

  • input (String)

Returns:

  • (String)


46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/ryac/pipeline/stage.rb', line 46

def call(input)
  if needs_analysis?
    raise InternalError, "#{self.class} needs analysis; run it through StageRunner"
  end

  source = input
  loop do
    ctx = StageContext.new(source, Prism.parse(source).value, nil, '', '')
    patches = [] #: Array[patch_entry]
    collect(ctx, patches)
    break if patches.none?

    new_source = apply_patches(source, patches)
    break if fixpoint? && new_source == source

    source = new_source
    break unless fixpoint?
  end
  source
end

#collect(ctx, patches) ⇒ void

This method returns an undefined value.

Parameters:

Raises:

  • (NotImplementedError)


35
36
37
# File 'lib/ryac/pipeline/stage.rb', line 35

def collect(ctx, patches)
  raise NotImplementedError, "#{self.class}#collect must be implemented"
end

#finish(ctx) ⇒ void

This method returns an undefined value.

Post-application contribution (aliases/preamble). Stages with nothing to add do not override this — no identity fakes. Only the runner collects the contribution; the standalone driver below returns text alone.

Parameters:



43
# File 'lib/ryac/pipeline/stage.rb', line 43

def finish(ctx) = nil

#fixpoint? ⇒ Boolean

true → the runner re-parses and re-collects until no patches remain.

Returns:

  • (Boolean)


29
# File 'lib/ryac/pipeline/stage.rb', line 29

def fixpoint? = false

#needs_analysis? ⇒ Boolean

true → member of an analysis batch: the runner parses and runs TypeProf once per maximal run of consecutive analysis stages, and every member collects against that single AnalysisResult.

Returns:

  • (Boolean)


26
# File 'lib/ryac/pipeline/stage.rb', line 26

def needs_analysis? = false