Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Imagine a microservice with Python code and a Dockerfile. You want to ensure:

```hielements
element orders_service:
# Define scopes with language annotations (V2 syntax)
# Define scopes with language annotations
scope python_module<python> = python.module_selector('orders')
scope dockerfile<docker> = docker.file_selector('orders_service.dockerfile')

Expand All @@ -76,18 +76,18 @@ Define architectural patterns once and reuse them across your codebase:
```hielements
pattern compiler {
element lexer {
scope module<rust> # Unbounded scope (V2)
scope module<rust> # Unbounded scope in pattern
ref tokens: TokenStream
}
element parser {
scope module<rust> # Unbounded scope (V2)
scope module<rust> # Unbounded scope in pattern
ref ast: AbstractSyntaxTree
}
check compiler.lexer.tokens.compatible_with(compiler.parser.input)
}

element python_compiler implements compiler {
# Bind pattern scopes using V2 binds keyword
# Bind pattern scopes using binds keyword
scope lexer_mod<rust> binds compiler.lexer.module = rust.module_selector('pycompiler::lexer')
ref lexer_tokens: TokenStream binds compiler.lexer.tokens = rust.function_selector(lexer_mod, 'tokenize')

Expand Down Expand Up @@ -270,7 +270,7 @@ Reject PRs that violate architectural rules.
### 1. Define Elements (Descriptive)

Elements represent logical components with:
- **Scope**: What code/artifacts belong to this element (with V2 language annotations like `<rust>`)
- **Scope**: What code/artifacts belong to this element (with language annotations like `<rust>`)
- **Connection Points**: APIs, interfaces, or dependencies the element exposes
- **Children**: Sub-elements for hierarchical composition

Expand Down Expand Up @@ -504,7 +504,7 @@ Check out our [Contributing Guide](CONTRIBUTING.md) (coming soon).
- **Multi-level**: From high-level system design to low-level module structure
- **Flexible**: Support both description (documenting what exists) and prescription (enforcing what should be)

**Hielements V2 makes this possible** through:
**Hielements makes this possible** through:
- **Descriptive mode**: Document your architecture without enforcement
- **Prescriptive mode**: Use patterns and checks to enforce architectural rules
- **Hybrid approach**: Mix both modes as needed for different parts of your system
Expand Down
2 changes: 1 addition & 1 deletion USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ element containerized_service:

## Using Patterns

Patterns are reusable architectural blueprints that can be instantiated with concrete implementations. Patterns (declared with the `template` keyword) help enforce consistent structure across similar components.
Patterns are reusable architectural blueprints that can be instantiated with concrete implementations. Patterns (declared with the `pattern` keyword) help enforce consistent structure across similar components.

> 📚 **See the [Pattern Catalog](doc/patterns_catalog.md)** for an extensive collection of common software engineering patterns with their Hielements implementations.

Expand Down
65 changes: 65 additions & 0 deletions agent-changelog/remove-backwards-compatibility.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Remove Backwards Compatibility and Version References

## Summary

Removed all backwards compatible elements of the language, all version references (V1, V2, V3), and all migration guides. The repository now has a single, clean language definition with no version history.

## Changes Made

### Source Code (Rust)

**`crates/hielements-core/src/lexer.rs`**:
- Removed `Template` token kind (`template` keyword no longer recognized)
- Removed `ConnectionPoint` token kind (`connection_point` keyword no longer recognized)
- Updated tests to use `pattern` instead of `template`, and no longer reference `connection_point`

**`crates/hielements-core/src/parser.rs`**:
- Removed handling of `Template` token (only `pattern` keyword accepted)
- Removed handling of `ConnectionPoint` token (only `ref` keyword accepted)
- Removed legacy colon syntax for scope language annotation (`scope src : python` no longer valid)
- Updated all error messages to say "patterns" instead of "templates"
- Updated all tests to use current language syntax

**`crates/hielements-core/src/ast.rs`**:
- Removed `ConnectionPointDeclaration` type alias
- Removed backward-compat comments mentioning V2 or `connection_point`

**`crates/hielements-core/src/interpreter.rs`**:
- Removed V2 references from inline comments

### Documentation

- **Deleted** `doc/language_v2.md` (V2 language documentation no longer needed)
- **Updated** `doc/language_reference.md`: Removed all V1/V2/V3 labels, version header, migration appendix (Appendix D), and backward compatibility notes throughout
- **Updated** `doc/implementation_status.md`: Removed V2/V3 labels from feature table, removed `template` and `connection_point` backward compat rows

### Examples

- **Deleted** `examples/v2_syntax_example.hie` (used deprecated `connection_point` keyword)
- **Deleted** `examples/v3_syntax_example.hie` (referenced V3 version)
- **Created** `examples/syntax_example.hie` (clean demonstration of current language features)
- **Updated** `examples/language_example.hie`: Removed V2 annotation comments

### Self-Description

- **Updated** `hielements.hie`: Removed V3 syntax comment, updated example file checks, updated internal comments

### Other Files

- **Updated** `README.md`: Removed V2 references in code examples
- **Updated** `USAGE.md`: Changed `template` keyword reference to `pattern`
- **Updated** `doc/scope_management.md`: Changed `template` keyword reference to `pattern`
- **Updated** `specs/core.hie`: Removed V3 syntax comment

## Language Changes (Breaking)

The following keywords are **no longer supported**:
- `template` - use `pattern` instead
- `connection_point` - use `ref` instead

The following syntax is **no longer supported**:
- `scope name : language` (colon syntax for language annotation) - use `scope name<language>` instead

## Test Results

All 92 tests pass. All 121 self-check passes.
18 changes: 7 additions & 11 deletions crates/hielements-core/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ pub struct Template {
pub name: Identifier,
/// Scope declarations
pub scopes: Vec<ScopeDeclaration>,
/// Ref declarations (formerly connection_point)
/// Ref declarations
pub refs: Vec<RefDeclaration>,
/// Check declarations
pub checks: Vec<CheckDeclaration>,
Expand Down Expand Up @@ -92,7 +92,7 @@ pub struct Element {
pub implements: Vec<TemplateImplementation>,
/// Scope declarations
pub scopes: Vec<ScopeDeclaration>,
/// Ref declarations (formerly connection_point, renamed to avoid confusion with uses)
/// Ref declarations
pub refs: Vec<RefDeclaration>,
/// Uses declarations - dependencies on other elements or scopes
pub uses: Vec<UsesDeclaration>,
Expand All @@ -108,7 +108,7 @@ pub struct Element {
pub span: Span,
}

/// A scope declaration (V2 supports unbounded scopes and bindings).
/// A scope declaration (supports unbounded scopes and bindings).
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ScopeDeclaration {
/// Scope name
Expand All @@ -123,8 +123,7 @@ pub struct ScopeDeclaration {
pub span: Span,
}

/// A ref declaration (V2 supports unbounded refs and bindings).
/// Renamed from connection_point to avoid confusion with 'uses' declarations.
/// A ref declaration (supports unbounded refs and bindings).
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RefDeclaration {
/// Ref name
Expand All @@ -139,9 +138,6 @@ pub struct RefDeclaration {
pub span: Span,
}

/// Type alias for backward compatibility
pub type ConnectionPointDeclaration = RefDeclaration;

/// A uses declaration - declares that this element/scope uses another element or scope.
/// This represents a dependency relationship (calling/importing).
#[derive(Debug, Clone, Serialize, Deserialize)]
Expand Down Expand Up @@ -278,10 +274,10 @@ impl BooleanLiteral {
// New Unified Syntax Types
// ============================================================================

/// Unified component requirement that supports the new syntax:
/// Unified component requirement that supports the syntax:
/// `requires [descendant] element name [: Type] [implements template]`
/// `allows [descendant] connection to pattern`
/// `forbids [descendant] connection_point name: Type`
/// `forbids [descendant] ref name: Type`
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ComponentRequirement {
/// The action: requires, allows, or forbids
Expand Down Expand Up @@ -325,7 +321,7 @@ pub enum ComponentSpec {
},
/// Connection requirement: `connection to pattern` (deprecated, use UsesDeclaration)
Connection(ConnectionPattern),
/// Ref requirement: `ref name: Type [= expr]` (formerly connection_point)
/// Ref requirement: `ref name: Type [= expr]`
Ref {
/// Ref name
name: Identifier,
Expand Down
10 changes: 5 additions & 5 deletions crates/hielements-core/src/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,14 +123,14 @@ impl Interpreter {
file_path: &str,
diagnostics: &mut Diagnostics,
) {
// Validate scopes (expression is optional for unbounded scopes in V2)
// Validate scopes (expression is optional for unbounded scopes in patterns)
for scope in &template.scopes {
if let Some(ref expr) = scope.expression {
self.validate_expression(expr, file_path, diagnostics);
}
}

// Validate refs (expression is optional for unbounded in V2)
// Validate refs (expression is optional for unbounded in patterns)
for r in &template.refs {
if let Some(ref expr) = r.expression {
self.validate_expression(expr, file_path, diagnostics);
Expand Down Expand Up @@ -172,14 +172,14 @@ impl Interpreter {
let _ = template_impl; // Acknowledge the field
}

// Validate scopes (expression is optional for unbounded scopes in V2)
// Validate scopes (expression is optional for unbounded scopes in patterns)
for scope in &element.scopes {
if let Some(ref expr) = scope.expression {
self.validate_expression(expr, file_path, diagnostics);
}
}

// Validate refs (expression is optional for unbounded in V2)
// Validate refs (expression is optional for unbounded in patterns)
for r in &element.refs {
if let Some(ref expr) = r.expression {
self.validate_expression(expr, file_path, diagnostics);
Expand Down Expand Up @@ -326,7 +326,7 @@ impl Interpreter {
if options.verbose {
eprintln!("[verbose] Evaluating scope: {}", scope_name);
}
// V2: expression is optional for unbounded scopes
// Expression is optional for unbounded scopes in patterns
if let Some(ref expr) = scope.expression {
match self.evaluate_expression(expr) {
Ok(value) => {
Expand Down
20 changes: 7 additions & 13 deletions crates/hielements-core/src/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ pub enum TokenKind {
#[token("element")]
Element,

#[token("template")]
Template,

#[token("pattern")]
Pattern,

Expand All @@ -29,9 +26,6 @@ pub enum TokenKind {
#[token("scope")]
Scope,

#[token("connection_point")]
ConnectionPoint,

#[token("ref")]
Ref,

Expand Down Expand Up @@ -418,16 +412,16 @@ mod tests {

#[test]
fn test_keywords() {
let source = "element template implements scope connection_point check import from as true false";
let source = "element pattern implements scope ref check import from as true false";
let mut lexer = Lexer::new(source);
let tokens = lexer.tokenize();

let kinds: Vec<_> = tokens.iter().map(|t| &t.kind).collect();
assert!(kinds.contains(&&TokenKind::Element));
assert!(kinds.contains(&&TokenKind::Template));
assert!(kinds.contains(&&TokenKind::Pattern));
assert!(kinds.contains(&&TokenKind::Implements));
assert!(kinds.contains(&&TokenKind::Scope));
assert!(kinds.contains(&&TokenKind::ConnectionPoint));
assert!(kinds.contains(&&TokenKind::Ref));
assert!(kinds.contains(&&TokenKind::Check));
assert!(kinds.contains(&&TokenKind::Import));
assert!(kinds.contains(&&TokenKind::From));
Expand All @@ -437,13 +431,13 @@ mod tests {
}

#[test]
fn test_template_keyword() {
let source = "template compiler:\n element lexer";
fn test_pattern_keyword() {
let source = "pattern compiler:\n element lexer";
let mut lexer = Lexer::new(source);
let tokens = lexer.tokenize();

let kinds: Vec<_> = tokens.iter().map(|t| &t.kind).collect();
assert!(kinds.contains(&&TokenKind::Template));
assert!(kinds.contains(&&TokenKind::Pattern));
assert!(kinds.contains(&&TokenKind::Identifier));
assert!(kinds.contains(&&TokenKind::Colon));
assert!(kinds.contains(&&TokenKind::Element));
Expand Down Expand Up @@ -544,7 +538,7 @@ mod tests {
}

#[test]
fn test_v2_scope_with_binds() {
fn test_scope_with_binds() {
let source = "scope main_module<rust> binds observable.metrics.module = rust.module_selector('api')";
let mut lexer = Lexer::new(source);
let tokens = lexer.tokenize();
Expand Down
Loading