refactor(joinir): Phase 44 - Capability-based shape guard
Refactor shape detection from function-name-based to capability-based architecture for better extensibility and maintainability. Key changes: - ShapeCapabilityKind enum: P2CoreSimple/SkipWs/Atoi/ParseNumber - ShapeCapability: Capability descriptor with future extensibility - Helper functions: - capability_for_shape(): Map shape to capability - is_canonical_shape(): Exact shape-level check - is_p2_core_capability(): Broad capability family check - is_supported_by_normalized(): Normalized dev support Benefits: - Extensibility: Easy to add new capability kinds - Clarity: Shape purpose explicit in kind names - Maintainability: Centralized mapping vs scattered ifs - Future-ready: Infrastructure for carrier roles, method signatures Backward compatibility: - Zero behavioral changes (pure refactoring) - Canonical set preserved: Pattern2Mini, skip_ws mini/real, atoi mini - All existing code paths unchanged Tests: 937/937 PASS Files: +78 lines (shape_guard.rs), design doc created
This commit is contained in:
@ -4,6 +4,43 @@ use crate::config::env::joinir_dev_enabled;
|
||||
use crate::mir::join_ir::normalized::dev_env;
|
||||
use crate::mir::join_ir::{JoinFuncId, JoinFunction, JoinInst, JoinModule};
|
||||
|
||||
/// Phase 44: Shape capability kinds (capability-based routing)
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum ShapeCapabilityKind {
|
||||
/// P2 Core: Simple mini patterns (i/acc/n etc)
|
||||
P2CoreSimple,
|
||||
|
||||
/// P2 Core: skip_whitespace mini/real
|
||||
P2CoreSkipWs,
|
||||
|
||||
/// P2 Core: _atoi mini/real
|
||||
P2CoreAtoi,
|
||||
|
||||
/// P2 Mid: _parse_number real (p + num_str + result)
|
||||
P2MidParseNumber,
|
||||
|
||||
/// Future: Other P2 patterns
|
||||
// P2MidAtOfLoop,
|
||||
// P2HeavyString,
|
||||
}
|
||||
|
||||
/// Phase 44: Shape capability descriptor
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ShapeCapability {
|
||||
pub kind: ShapeCapabilityKind,
|
||||
// Future extensibility fields (not all used yet):
|
||||
// pub pattern_kind: LoopPatternKind,
|
||||
// pub loop_param_count: usize,
|
||||
// pub carrier_roles: Vec<CarrierRole>,
|
||||
// pub method_calls: Vec<MethodCallSignature>,
|
||||
}
|
||||
|
||||
impl ShapeCapability {
|
||||
pub fn new(kind: ShapeCapabilityKind) -> Self {
|
||||
Self { kind }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub(crate) enum NormalizedDevShape {
|
||||
Pattern1Mini,
|
||||
@ -56,20 +93,56 @@ pub(crate) fn supported_shapes(module: &JoinModule) -> Vec<NormalizedDevShape> {
|
||||
shapes
|
||||
}
|
||||
|
||||
/// Phase 44: Map NormalizedDevShape to ShapeCapability
|
||||
pub fn capability_for_shape(shape: &NormalizedDevShape) -> ShapeCapability {
|
||||
use NormalizedDevShape::*;
|
||||
use ShapeCapabilityKind::*;
|
||||
|
||||
let kind = match shape {
|
||||
Pattern2Mini => P2CoreSimple,
|
||||
JsonparserSkipWsMini | JsonparserSkipWsReal => P2CoreSkipWs,
|
||||
JsonparserAtoiMini | JsonparserAtoiReal => P2CoreAtoi,
|
||||
JsonparserParseNumberReal => P2MidParseNumber,
|
||||
Pattern1Mini => P2CoreSimple, // Also core simple pattern
|
||||
};
|
||||
|
||||
ShapeCapability::new(kind)
|
||||
}
|
||||
|
||||
/// Phase 44: Check if shape is canonical P2-Core (shape-level check)
|
||||
///
|
||||
/// Phase 41 canonical set (exact): Pattern2Mini, skip_ws (mini/real), atoi mini.
|
||||
/// Excludes: Pattern1Mini, atoi real, parse_number real.
|
||||
pub fn is_canonical_shape(shape: &NormalizedDevShape) -> bool {
|
||||
use NormalizedDevShape::*;
|
||||
matches!(
|
||||
shape,
|
||||
Pattern2Mini | JsonparserSkipWsMini | JsonparserSkipWsReal | JsonparserAtoiMini
|
||||
)
|
||||
}
|
||||
|
||||
/// Phase 44: Check if capability kind is in P2-Core family
|
||||
///
|
||||
/// This checks capability-level membership, not granular canonical status.
|
||||
/// Use `is_canonical_shape()` for exact canonical filtering.
|
||||
pub fn is_p2_core_capability(cap: &ShapeCapability) -> bool {
|
||||
use ShapeCapabilityKind::*;
|
||||
matches!(cap.kind, P2CoreSimple | P2CoreSkipWs | P2CoreAtoi | P2MidParseNumber)
|
||||
}
|
||||
|
||||
/// Phase 44: Check if capability is supported by Normalized dev
|
||||
pub fn is_supported_by_normalized(cap: &ShapeCapability) -> bool {
|
||||
// Currently same as P2-Core family
|
||||
is_p2_core_capability(cap)
|
||||
}
|
||||
|
||||
/// canonical(常時 Normalized 経路を通す)対象。
|
||||
/// Phase 41: P2 コアセット(P2 mini + JP skip_ws mini/real + JP atoi mini)。
|
||||
/// Phase 44: Capability-based filtering (backward compatible)。
|
||||
pub(crate) fn canonical_shapes(module: &JoinModule) -> Vec<NormalizedDevShape> {
|
||||
let shapes: Vec<_> = detect_shapes(module)
|
||||
.into_iter()
|
||||
.filter(|s| {
|
||||
matches!(
|
||||
s,
|
||||
NormalizedDevShape::Pattern2Mini
|
||||
| NormalizedDevShape::JsonparserSkipWsMini
|
||||
| NormalizedDevShape::JsonparserSkipWsReal
|
||||
| NormalizedDevShape::JsonparserAtoiMini
|
||||
)
|
||||
})
|
||||
.filter(|s| is_canonical_shape(s))
|
||||
.collect();
|
||||
log_shapes("canonical", &shapes);
|
||||
shapes
|
||||
|
||||
Reference in New Issue
Block a user