typecheck: reject extra short field tokens

This commit is contained in:
Hermes Agent
2026-09-21 09:33:21 +00:00
parent 72a5589a3e
commit 44937b074f
7 changed files with 28 additions and 3 deletions
+5
View File
@@ -1,5 +1,10 @@
# Changelog # Changelog
### Diagnose extra words after short typed field assignments
- `claro typecheck` now rejects trailing words after the value in short explicit object-field assignments such as `SET player.score NUMBER 10 extra`.
- Added focused negative coverage to the complete typecheck validation matrix and documented the repair hint.
### Validate explicitly typed YESNO object-field assignments ### Validate explicitly typed YESNO object-field assignments
- Added positive typecheck coverage for `SET player.ready YESNO YES` when the class declares `HAS ready YESNO`. - Added positive typecheck coverage for `SET player.ready YESNO YES` when the class declares `HAS ready YESNO`.
+11 -1
View File
@@ -825,7 +825,7 @@ SET player.score AS NUMBER TO 10
Both explicit forms must agree with the class field declaration. Both explicit forms must agree with the class field declaration.
The separated form accepts one value expression only. Extra words are rejected Each explicit field annotation accepts one value expression only. Extra words are rejected
with a repair hint instead of being silently ignored: with a repair hint instead of being silently ignored:
```claro ```claro
@@ -836,6 +836,16 @@ SET player.score AS NUMBER TO 10 extra
SET player.score has extra text after value 10. Keep only the field name, type, TO, and one expression. SET player.score has extra text after value 10. Keep only the field name, type, TO, and one expression.
``` ```
The short explicit form is checked too:
```claro
SET player.score NUMBER 10 extra
```
```text
SET player.score has extra text after value 10. Keep only the field name, type, and one expression.
```
The `AS ... TO` spelling also works inside modern and compatibility object methods: The `AS ... TO` spelling also works inside modern and compatibility object methods:
```claro ```claro
+1 -1
View File
@@ -83,7 +83,7 @@ Ready now:
- object creation now rejects repeated object names with a direct repair hint, so two `NEW Player player` statements cannot silently replace one another during type checking; when a script declares at least one class, a misspelled `NEW` class name gets a direct declaration hint without changing the older permissive no-class form; a missing class name or object name gets a direct example repair; extra words after the object name get a direct repair hint instead of being silently ignored - object creation now rejects repeated object names with a direct repair hint, so two `NEW Player player` statements cannot silently replace one another during type checking; when a script declares at least one class, a misspelled `NEW` class name gets a direct declaration hint without changing the older permissive no-class form; a missing class name or object name gets a direct example repair; extra words after the object name get a direct repair hint instead of being silently ignored
- a narrow object-field assignment/check-type check for simple `NEW Class object` plus direct `SET object.field value` and `CHECK TYPE object.field IS TYPE` cases when the class declares `HAS field TYPE`; validation now covers correct NUMBER, TEXT, and YESNO direct assignments, dedicated positive and explicitly typed NUMBER/TEXT field assignments, explicitly typed method-body assignments to undeclared fields with a `HAS field TYPE` repair hint in modern and compatibility method syntax, dedicated positive NUMBER/TEXT/YESNO `CHECK TYPE` metadata fixtures, simple and chained object aliases for both field assignments and `CHECK TYPE` metadata (including a chained TEXT-field check), aliased object-method calls including chained aliases in modern `DO` and compatibility `CALL ... WITH` forms (with a dedicated positive modern `DO` chained-alias fixture), field-to-field, compound arithmetic field expressions, and arithmetic/text expression result types, negative NUMBER/TEXT/YESNO field `CHECK TYPE` metadata mismatches, NUMBER/TEXT/YESNO-expectation unknown-field `CHECK TYPE` diagnostics, missing-object field assignment and `CHECK TYPE` diagnostics, NUMBER/TEXT/YESNO wrong-type diagnostics, field collection when a `HAS` field appears after a simple method, NUMBER/TEXT/YESNO-valued unknown-field diagnostics for direct assignments to undeclared fields including explicitly typed assignments, numeric and text results from simple arithmetic/text expressions in object-field assignments, plus method-body field assignment and `CHECK TYPE` diagnostics for NUMBER, TEXT, and YESNO fields in modern and compatibility syntax, including compatibility YESNO `CHECK TYPE` metadata coverage, direct method assignments to undeclared fields now produce a beginner-facing missing-field diagnostic when the assigned expression has a known type, and a plain beginner-facing unknown-field diagnostic when the assigned expression is not inferable yet in both modern and compatibility method syntax; method-body `CHECK TYPE` now reports an unknown field with a repair hint in both method syntaxes, including compatibility `TAKES` / `LEARNED` methods; explicitly typed assignments to declared method fields now validate the class-declared field type instead of trusting only the inline type annotation, so a wrong value such as `SET score TEXT \"oops\"` reports the method and field in the diagnostic. - a narrow object-field assignment/check-type check for simple `NEW Class object` plus direct `SET object.field value` and `CHECK TYPE object.field IS TYPE` cases when the class declares `HAS field TYPE`; validation now covers correct NUMBER, TEXT, and YESNO direct assignments, dedicated positive and explicitly typed NUMBER/TEXT field assignments, explicitly typed method-body assignments to undeclared fields with a `HAS field TYPE` repair hint in modern and compatibility method syntax, dedicated positive NUMBER/TEXT/YESNO `CHECK TYPE` metadata fixtures, simple and chained object aliases for both field assignments and `CHECK TYPE` metadata (including a chained TEXT-field check), aliased object-method calls including chained aliases in modern `DO` and compatibility `CALL ... WITH` forms (with a dedicated positive modern `DO` chained-alias fixture), field-to-field, compound arithmetic field expressions, and arithmetic/text expression result types, negative NUMBER/TEXT/YESNO field `CHECK TYPE` metadata mismatches, NUMBER/TEXT/YESNO-expectation unknown-field `CHECK TYPE` diagnostics, missing-object field assignment and `CHECK TYPE` diagnostics, NUMBER/TEXT/YESNO wrong-type diagnostics, field collection when a `HAS` field appears after a simple method, NUMBER/TEXT/YESNO-valued unknown-field diagnostics for direct assignments to undeclared fields including explicitly typed assignments, numeric and text results from simple arithmetic/text expressions in object-field assignments, plus method-body field assignment and `CHECK TYPE` diagnostics for NUMBER, TEXT, and YESNO fields in modern and compatibility syntax, including compatibility YESNO `CHECK TYPE` metadata coverage, direct method assignments to undeclared fields now produce a beginner-facing missing-field diagnostic when the assigned expression has a known type, and a plain beginner-facing unknown-field diagnostic when the assigned expression is not inferable yet in both modern and compatibility method syntax; method-body `CHECK TYPE` now reports an unknown field with a repair hint in both method syntaxes, including compatibility `TAKES` / `LEARNED` methods; explicitly typed assignments to declared method fields now validate the class-declared field type instead of trusting only the inline type annotation, so a wrong value such as `SET score TEXT \"oops\"` reports the method and field in the diagnostic.
- inline method-field annotations are checked against the class `HAS` declaration in modern and compatibility methods; conflicting known types and unknown annotation names produce field-specific repair guidance, with positive and negative focused fixtures for both syntaxes. - inline method-field annotations are checked against the class `HAS` declaration in modern and compatibility methods; conflicting known types and unknown annotation names produce field-specific repair guidance, with positive and negative focused fixtures for both syntaxes.
- direct object-field `AS ... TO` assignments reject extra words after the value with a repair hint, so `SET player.score AS NUMBER TO 10 extra` cannot silently ignore the trailing text. - direct object-field `AS ... TO` assignments reject extra words after the value with a repair hint, so `SET player.score AS NUMBER TO 10 extra` cannot silently ignore the trailing text; short explicitly typed assignments such as `SET player.score NUMBER 10 extra` receive the same repair-oriented check
- Direct object-field validation also has positive coverage for explicit `NUMBER`, `TEXT`, and `YESNO` annotations, such as `SET player.ready YESNO YES`, plus the compatibility-shaped `AS ... TO` form such as `SET player.score AS NUMBER TO 10`, while the shorter unannotated form remains supported; method-body field assignments have matching positive coverage for both modern and compatibility `TEACH` forms using `SET score AS NUMBER TO 10`, and those two `AS ... TO` method fixtures are now included in `claro validate`; conflicting annotations such as `SET player.score TEXT "oops"` explain the class-declared type and how to repair it, and unknown annotations such as `SET player.score AS BANANA TO 10` or `SET player.score BANANA 10` identify the invalid type and suggest the declared field type. - Direct object-field validation also has positive coverage for explicit `NUMBER`, `TEXT`, and `YESNO` annotations, such as `SET player.ready YESNO YES`, plus the compatibility-shaped `AS ... TO` form such as `SET player.score AS NUMBER TO 10`, while the shorter unannotated form remains supported; method-body field assignments have matching positive coverage for both modern and compatibility `TEACH` forms using `SET score AS NUMBER TO 10`, and those two `AS ... TO` method fixtures are now included in `claro validate`; conflicting annotations such as `SET player.score TEXT "oops"` explain the class-declared type and how to repair it, and unknown annotations such as `SET player.score AS BANANA TO 10` or `SET player.score BANANA 10` identify the invalid type and suggest the declared field type.
Still needed: Still needed:
+1
View File
@@ -53,6 +53,7 @@ Keep declared return types honest: `claro typecheck` now reports friendly diagno
8d.2. Keep method field annotation forms balanced: modern and compatibility methods now have dedicated positive fixtures for `SET score AS NUMBER TO 10`, so the compatibility-shaped annotation remains protected inside both supported method syntaxes. 8d.2. Keep method field annotation forms balanced: modern and compatibility methods now have dedicated positive fixtures for `SET score AS NUMBER TO 10`, so the compatibility-shaped annotation remains protected inside both supported method syntaxes.
8d.3. Keep release validation aligned with method annotation coverage: the modern and compatibility `AS ... TO` method fixtures now run through `claro validate`, not only the focused Python diagnostic validator. 8d.3. Keep release validation aligned with method annotation coverage: the modern and compatibility `AS ... TO` method fixtures now run through `claro validate`, not only the focused Python diagnostic validator.
8d.4. Keep separated direct field assignments unambiguous: `SET player.score AS NUMBER TO 10 extra` now reports the trailing text and explains the one-expression form instead of accepting a partially parsed value. 8d.4. Keep separated direct field assignments unambiguous: `SET player.score AS NUMBER TO 10 extra` now reports the trailing text and explains the one-expression form instead of accepting a partially parsed value.
8d.5. Keep short direct field assignments unambiguous: `SET player.score NUMBER 10 extra` now rejects trailing words with a repair hint, matching the separated `AS ... TO` form.
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. 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.
8g. Keep unknown inline method-field annotation diagnostics aligned across syntax generations: compatibility `TAKES` / `LEARNED` methods now have matching focused coverage for misspelled annotations. 8g. Keep unknown inline method-field annotation diagnostics aligned across syntax generations: compatibility `TAKES` / `LEARNED` methods now have matching focused coverage for misspelled annotations.
+1 -1
View File
File diff suppressed because one or more lines are too long
@@ -0,0 +1,6 @@
CLASS Player
HAS score NUMBER
END
NEW Player player
SET player.score NUMBER 10 extra
+3
View File
@@ -263,6 +263,9 @@ EXPECTED = {
"tests/typecheck_object_field_typed_as_to_extra_tokens_bad.claro": [ "tests/typecheck_object_field_typed_as_to_extra_tokens_bad.claro": [
"tests/typecheck_object_field_typed_as_to_extra_tokens_bad.claro:6: SET player.score has extra text after value 10. Keep only the field name, type, TO, and one expression.", "tests/typecheck_object_field_typed_as_to_extra_tokens_bad.claro:6: SET player.score has extra text after value 10. Keep only the field name, type, TO, and one expression.",
], ],
"tests/typecheck_object_field_short_extra_tokens_bad.claro": [
"tests/typecheck_object_field_short_extra_tokens_bad.claro:6: SET player.score has extra text after value 10. Keep only the field name, type, and one expression.",
],
"tests/typecheck_object_field_typed_unknown_type_bad.claro": [ "tests/typecheck_object_field_typed_unknown_type_bad.claro": [
"tests/typecheck_object_field_typed_unknown_type_bad.claro:6: Field player.score needs a known type such as NUMBER, TEXT, or YESNO, but BANANA is not a Claro type. Use NUMBER for score.", "tests/typecheck_object_field_typed_unknown_type_bad.claro:6: Field player.score needs a known type such as NUMBER, TEXT, or YESNO, but BANANA is not a Claro type. Use NUMBER for score.",
], ],