Skip to content

Identifiers that are target-language keywords are emitted verbatim: a property named Type or Default generates fn type(...) (Rust) / int default() (C++) that fails to compile #106

Description

@matt-edmondson

What's wrong

No generator checks a spelled identifier against the target language's reserved words. LanguageGeneratorBase and the language generators have no reserved-word set, and names only go through NameStyles.Spell (re-casing). The AST is language-neutral, so a name that is perfectly legal in one target becomes a keyword in another once re-cased. The clearest case is the getter name made up for a computed property, PropertyDeclaration.GetterName (Coder/Ast/PropertyDeclaration.cs ~141), used from StandardLanguageGenerator.cs ~393:

Repro (reproduced with MSTest, output checked with the real compilers)

A struct Box with new PropertyDeclaration("Type", "int") and new PropertyDeclaration("Default", "int"), each with a getter body return 1. Both are ordinary C# property names.

Target Generated Compiler
Rust pub fn type(&self) -> i32 rustc: expected identifier, found keyword 'type'
C++ int default() const g++ -std=c++20: expected unqualified-id before 'default'
C Box_type fine, because of the prefix

The same applies to any other spelled identifier (parameter, local, field, function) that lands on a keyword after casing, e.g. match/impl/fn in Rust, range/func/type in Go, lambda/def in Python, delete/new in C++.

This is independent of #71: ktsu.CaseConverter would still produce type.

Suggested fix / acceptance criteria

  • Give each generator a reserved-word set and a single EscapeIdentifier hook applied wherever a name is spelled:
    • Rust: raw identifiers (r#type). Note that self/Self/crate/super can't be raw, so suffix those.
    • C++/C/Go/Python/JS: append _ (e.g. default_, type_).
    • C#: @default.
  • Apply it consistently at declaration and use sites so references still resolve.
  • Add compile tests with a property named Type/Default and a parameter named after a keyword in each target.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingreadyFully specified; implement as written

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions