Class: Rigor::Plugin::ProtocolContract
- Inherits:
-
Object
- Object
- Rigor::Plugin::ProtocolContract
- Defined in:
- lib/rigor/plugin/protocol_contract.rb
Overview
ADR-28 declaration: "every instance/singleton method named method_name, defined in a source file
matching path_glob, is implicitly required to satisfy the declared parameter + return-type protocol."
Authored on a plugin manifest:
manifest(
id: "web",
version: "0.1.0",
protocol_contracts: [
Rigor::Plugin::ProtocolContract.new(
path_glob: "lib/controller/**/*.rb",
method_name: :get,
param_types: [{ index: 0, type_name: "Rack::Request" }],
return_type_name: "Rack::Response"
)
]
)
The contract drives two distinct engine behaviours (ADR-28 § "provide-and-check"):
- provide — when the inference engine binds the parameter list of a matching
def, Inference::MethodParameterBinder substitutes the declaredparam_typesfor the usualDynamic[Top]fallback, so the method body is analysed as if the parameter carried its protocol type. - check — the contributing plugin's
#diagnostics_for_filehook confirms the method exists and its inferred return type conforms toreturn_type_name.
Fields
path_glob—File.fnmatchglob (String) selecting the source files the contract applies to, relative to the analysed project root (e.g."lib/controller/**/*.rb").method_name— Symbol; the instance (or singleton) method the contract constrains.singleton— Boolean;trueconstrainsdef self.<name>,false(default) constrains instance methods.param_types— Array ofParamType(positional index → fully-qualified type name). The type names resolve against the analysed project's environment lazily, at consumption time, so the contract value object stays independent of environment construction order.return_type_name— fully-qualified type name (String) the method's inferred return type must conform to.severity— Symbol diagnostic severity for contract violations (:errordefault).
Ractor-shareability
Every field is frozen at construction (ADR-15 Phase 1); the nested ParamType is a frozen Data.
Ractor.shareable? returns true after #initialize, so the contract survives
Plugin::Registry.materialize into a worker Ractor.
Defined Under Namespace
Classes: ParamType
Constant Summary collapse
- VALID_SEVERITIES =
%i[error warning info].freeze
Instance Attribute Summary collapse
-
#method_name ⇒ Object
readonly
Returns the value of attribute method_name.
-
#param_types ⇒ Object
readonly
Returns the value of attribute param_types.
-
#path_glob ⇒ Object
readonly
Returns the value of attribute path_glob.
-
#return_type_name ⇒ Object
readonly
Returns the value of attribute return_type_name.
-
#severity ⇒ Object
readonly
Returns the value of attribute severity.
-
#singleton ⇒ Object
readonly
Returns the value of attribute singleton.
Instance Method Summary collapse
- #==(other) ⇒ Object (also: #eql?)
- #hash ⇒ Object
-
#initialize(path_glob:, method_name:, return_type_name: nil, param_types: [], singleton: false, severity: :error) ⇒ ProtocolContract
constructor
A new instance of ProtocolContract.
- #to_h ⇒ Object
-
#with_path_glob(glob) ⇒ Object
Returns a copy with
path_globreplaced.
Constructor Details
#initialize(path_glob:, method_name:, return_type_name: nil, param_types: [], singleton: false, severity: :error) ⇒ ProtocolContract
Returns a new instance of ProtocolContract.
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/rigor/plugin/protocol_contract.rb', line 59 def initialize(path_glob:, method_name:, return_type_name: nil, param_types: [], singleton: false, severity: :error) validate_path_glob!(path_glob) validate_method_name!(method_name) validate_return_type_name!(return_type_name) validate_severity!(severity) @path_glob = path_glob.dup.freeze @method_name = method_name.to_sym @singleton = singleton ? true : false @param_types = coerce_param_types(param_types) @return_type_name = return_type_name.nil? ? nil : return_type_name.dup.freeze @severity = severity.to_sym freeze end |
Instance Attribute Details
#method_name ⇒ Object (readonly)
Returns the value of attribute method_name.
57 58 59 |
# File 'lib/rigor/plugin/protocol_contract.rb', line 57 def method_name @method_name end |
#param_types ⇒ Object (readonly)
Returns the value of attribute param_types.
57 58 59 |
# File 'lib/rigor/plugin/protocol_contract.rb', line 57 def param_types @param_types end |
#path_glob ⇒ Object (readonly)
Returns the value of attribute path_glob.
57 58 59 |
# File 'lib/rigor/plugin/protocol_contract.rb', line 57 def path_glob @path_glob end |
#return_type_name ⇒ Object (readonly)
Returns the value of attribute return_type_name.
57 58 59 |
# File 'lib/rigor/plugin/protocol_contract.rb', line 57 def return_type_name @return_type_name end |
#severity ⇒ Object (readonly)
Returns the value of attribute severity.
57 58 59 |
# File 'lib/rigor/plugin/protocol_contract.rb', line 57 def severity @severity end |
#singleton ⇒ Object (readonly)
Returns the value of attribute singleton.
57 58 59 |
# File 'lib/rigor/plugin/protocol_contract.rb', line 57 def singleton @singleton end |
Instance Method Details
#==(other) ⇒ Object Also known as: eql?
99 100 101 |
# File 'lib/rigor/plugin/protocol_contract.rb', line 99 def ==(other) other.is_a?(ProtocolContract) && to_h == other.to_h end |
#hash ⇒ Object
104 105 106 |
# File 'lib/rigor/plugin/protocol_contract.rb', line 104 def hash to_h.hash end |
#to_h ⇒ Object
88 89 90 91 92 93 94 95 96 97 |
# File 'lib/rigor/plugin/protocol_contract.rb', line 88 def to_h { "path_glob" => path_glob, "method_name" => method_name.to_s, "singleton" => singleton, "param_types" => param_types.map { |pt| { "index" => pt.index, "type_name" => pt.type_name } }, "return_type_name" => return_type_name, "severity" => severity.to_s } end |
#with_path_glob(glob) ⇒ Object
Returns a copy with path_glob replaced. Plugins use this to honour a per-project config override of
the convention path without rebuilding the whole contract by hand.
77 78 79 80 81 82 83 84 85 86 |
# File 'lib/rigor/plugin/protocol_contract.rb', line 77 def with_path_glob(glob) ProtocolContract.new( path_glob: glob, method_name: method_name, return_type_name: return_type_name, param_types: param_types.map { |pt| { index: pt.index, type_name: pt.type_name } }, singleton: singleton, severity: severity ) end |