typecheck: diagnose unknown method field annotations

This commit is contained in:
Hermes Agent
2026-09-15 15:02:58 +00:00
parent 88c684da37
commit 304c43ba45
8 changed files with 25 additions and 1 deletions
+5
View File
@@ -1,5 +1,10 @@
# Changelog # Changelog
### Diagnose unknown inline method-field annotations
- `claro typecheck` now rejects unknown inline field annotations such as `BANANA` and suggests the class-declared `HAS` type.
- Added focused negative coverage to the complete typecheck validation matrix.
### Align inline method-field annotations with class fields ### Align inline method-field annotations with class fields
- `claro typecheck` now compares an inline method assignment annotation with the class field declared by `HAS`. - `claro typecheck` now compares an inline method assignment annotation with the class field declared by `HAS`.
+2
View File
@@ -111,6 +111,8 @@ OBJECT FIELDS player AS fields
Inside a method, an inline field type must agree with the class declaration. For example, `HAS score NUMBER` must not be assigned with `SET score TEXT 10`; `claro typecheck` explains the conflict and suggests `NUMBER`. The same check applies to older `TEACH ... TAKES ...` / `LEARNED` methods, so compatibility lessons get the same feedback. Inside a method, an inline field type must agree with the class declaration. For example, `HAS score NUMBER` must not be assigned with `SET score TEXT 10`; `claro typecheck` explains the conflict and suggests `NUMBER`. The same check applies to older `TEACH ... TAKES ...` / `LEARNED` methods, so compatibility lessons get the same feedback.
If an inline method-field annotation is not a Claro type, `claro typecheck` names the field and method and suggests the class declaration. For example, `SET score AS BANANA TO 10` reports that `BANANA` is unknown and recommends `NUMBER`.
## Static type safety ## Static type safety
Beginners can still write the simplest form: Beginners can still write the simplest form:
+2
View File
@@ -867,3 +867,5 @@ This is currently a static checker feature. It improves `claro typecheck` and va
Method-body field assignments are covered in both modern and compatibility syntax, including a valid YESNO assignment through `TEACH toggle TAKES value` and `CALL player.toggle WITH YES`. Method-body `CHECK TYPE` metadata has the same balanced coverage: a modern `DO player.toggle YES` example and the compatibility `CALL` example both verify a declared YESNO field. The focused release validator keeps these positive examples beside the wrong-type diagnostics. Method-body field assignments are covered in both modern and compatibility syntax, including a valid YESNO assignment through `TEACH toggle TAKES value` and `CALL player.toggle WITH YES`. Method-body `CHECK TYPE` metadata has the same balanced coverage: a modern `DO player.toggle YES` example and the compatibility `CALL` example both verify a declared YESNO field. The focused release validator keeps these positive examples beside the wrong-type diagnostics.
A bare field typo inside a method's `CHECK TYPE` is also checked now. For example, `CHECK TYPE level IS NUMBER` in `Player.train` reports `Object Player has no field level. Check the field name or add HAS level NUMBER to the class.` The older `TAKES` / `LEARNED` method spelling receives the same diagnostic. This keeps method metadata checks consistent with direct method-field assignments and uses the expected type to make the repair actionable. A bare field typo inside a method's `CHECK TYPE` is also checked now. For example, `CHECK TYPE level IS NUMBER` in `Player.train` reports `Object Player has no field level. Check the field name or add HAS level NUMBER to the class.` The older `TAKES` / `LEARNED` method spelling receives the same diagnostic. This keeps method metadata checks consistent with direct method-field assignments and uses the expected type to make the repair actionable.
Inline method-field annotations are checked for known type names too. For example, `SET score AS BANANA TO 10` inside `Player.set_score` reports `Field score in Player.set_score needs a known type such as NUMBER, TEXT, or YESNO, but BANANA is not a Claro type. Use NUMBER for score.`
+1
View File
@@ -69,6 +69,7 @@ Still needed:
- richer object field type checking beyond simple direct assignments - richer object field type checking beyond simple direct assignments
- typed imports/modules - typed imports/modules
- inline method-field annotations must agree with the class `HAS` declaration in both modern `TEACH` / `END` and compatibility `TAKES` / `LEARNED` methods; conflicting annotations now get a repair-oriented diagnostic even when the value's inferred type is otherwise correct. - inline method-field annotations must agree with the class `HAS` declaration in both modern `TEACH` / `END` and compatibility `TAKES` / `LEARNED` methods; conflicting annotations now get a repair-oriented diagnostic even when the value's inferred type is otherwise correct.
- inline method-field annotations also reject unknown names such as `BANANA`, naming the field and method and suggesting the class-declared type.
Good starting docs: Good starting docs:
- `ADVANCED_STATIC_TYPING.md` - `ADVANCED_STATIC_TYPING.md`
+1
View File
@@ -50,6 +50,7 @@ Keep declared return types honest: `claro typecheck` now reports friendly diagno
8c. Keep explicit method-field annotations aligned with class declarations: `SET score TEXT "oops"` inside a method with `HAS score NUMBER` now reports the declared field mismatch instead of accepting the inline annotation; broader annotation consistency remains planned. 8c. Keep explicit method-field annotations aligned with class declarations: `SET score TEXT "oops"` inside a method with `HAS score NUMBER` now reports the declared field mismatch instead of accepting the inline annotation; broader annotation consistency remains planned.
8d. Keep inline method-field annotations consistent with `HAS` declarations: `claro typecheck` now rejects a conflicting annotation even when the assigned value itself has the class-declared type, and explains which type to use. 8d. Keep inline method-field annotations consistent with `HAS` declarations: `claro typecheck` now rejects a conflicting annotation even when the assigned value itself has the class-declared type, and explains which type to use.
8e. Keep inline method-field annotation coverage aligned across syntax generations: compatibility `TAKES` / `LEARNED` methods now have matching positive and negative fixtures, so older lessons retain the same class-declared-type guidance. 8e. Keep inline method-field annotation coverage aligned across syntax generations: compatibility `TAKES` / `LEARNED` methods now have matching positive and negative fixtures, so older lessons retain the same class-declared-type guidance.
8f. Keep inline method-field annotations learner-facing: an unknown annotation such as `BANANA` now names the field and method and suggests the `HAS` type instead of silently treating the annotation as an expression.
### 1. Strong static types ### 1. Strong static types
+1 -1
View File
File diff suppressed because one or more lines are too long
@@ -0,0 +1,10 @@
CLASS Player
HAS score NUMBER
TEACH set_score
SET score AS BANANA TO 10
END
END
NEW Player player
DO player.set_score
+3
View File
@@ -302,6 +302,9 @@ EXPECTED = {
"tests/typecheck_method_compat_inline_field_annotation_bad.claro": [ "tests/typecheck_method_compat_inline_field_annotation_bad.claro": [
"tests/typecheck_method_compat_inline_field_annotation_bad.claro:5: Type mismatch for field score in Player.set_score: class declares NUMBER, but this assignment says TEXT. Use NUMBER for score.", "tests/typecheck_method_compat_inline_field_annotation_bad.claro:5: Type mismatch for field score in Player.set_score: class declares NUMBER, but this assignment says TEXT. Use NUMBER for score.",
], ],
"tests/typecheck_method_inline_field_annotation_unknown_type_bad.claro": [
"tests/typecheck_method_inline_field_annotation_unknown_type_bad.claro:5: Field score in Player.set_score needs a known type such as NUMBER, TEXT, or YESNO, but BANANA is not a Claro type. Use NUMBER for score.",
],
"tests/typecheck_method_unknown_field_expression_bad.claro": [ "tests/typecheck_method_unknown_field_expression_bad.claro": [
"tests/typecheck_method_unknown_field_expression_bad.claro:5: Object Player has no field level. Check the field name or add the field to the class with the right type.", "tests/typecheck_method_unknown_field_expression_bad.claro:5: Object Player has no field level. Check the field name or add the field to the class with the right type.",
], ],