Skip to content

Conversation

@michaelnebel
Copy link
Contributor

@michaelnebel michaelnebel commented Feb 11, 2026

In this PR we make support for the C# 14 field keyword in properties. Using the keyword field in property accessors implicitly make a synthetic backing field.
That is, you can declare

public class C
{
    public object Prop1
    {
        get { return field; }
        set { field = value; }
    }
}

Some notes on the implementation.

  • An important implementation detail is that PropertyField objects are hashed on the (field,property) pair and not only on the field itself. The symbol visitor is being applied to all backing fields, which means that Field objects are created for backing fields as well - however, the DB is not populated based on these as they are implicitly declared.
  • An auto-property has a similar backing field, which we are not extracting.
  • We only extract the property backing field, if it is referenced by the use of the field keyword. That is, we only extract the backing field, if we are encountering an expression with FieldExpression kind.

@github-actions github-actions bot added the C# label Feb 11, 2026
@michaelnebel michaelnebel changed the title C# 14: Support for field usage in properties. C# 14: Support the field keyword. Feb 11, 2026
@michaelnebel
Copy link
Contributor Author

DCA looks good.

  • Performance appears to be un-affected.
  • Fewer extraction errors and a reduction in missing call targets.
  • Changes to alerts, which could be explained by the above.

@michaelnebel michaelnebel marked this pull request as ready for review February 13, 2026 09:20
@michaelnebel michaelnebel requested a review from a team as a code owner February 13, 2026 09:20
Copilot AI review requested due to automatic review settings February 13, 2026 09:20
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds C# extractor and library test support for the C# 14 field keyword in property accessors by modeling the synthetic backing field (and its accesses) when the keyword is used.

Changes:

  • Introduces a new PropertyField entity to represent the synthetic backing field created by field-using properties.
  • Adds expression extraction support for Roslyn’s FieldExpression syntax via PropertyFieldAccess.
  • Updates C# QL library tests, AST expectations, and dataflow expectations to cover field keyword scenarios; adds a changelog entry.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
csharp/ql/test/library-tests/properties/properties.cs Adds a property that uses the field keyword to exercise extraction.
csharp/ql/test/library-tests/properties/Properties17.ql Updates test description to reflect new backing-field behavior for field.
csharp/ql/test/library-tests/properties/Properties17.expected Updates expected results to include the extracted Prop.field.
csharp/ql/test/library-tests/properties/PrintAst.expected Updates AST expectations for field accesses and the synthetic field.
csharp/ql/test/library-tests/dataflow/fields/FieldFlow.expected Updates dataflow expectations to include flows through field-backed properties.
csharp/ql/test/library-tests/dataflow/fields/D.cs Adds dataflow test cases using field in instance/static properties (incl. initializer).
csharp/ql/lib/change-notes/2026-02-12-field-keyword.md Adds a changelog note for the new field keyword support.
csharp/extractor/Semmle.Extraction.CSharp/Entities/PropertyField.cs New entity representing the synthetic backing field for field-using properties.
csharp/extractor/Semmle.Extraction.CSharp/Entities/Field.cs Makes the Field constructor protected to support subclassing.
csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/PropertyFieldAccess.cs New expression handler that extracts access to PropertyField for field expressions.
csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Factory.cs Routes SyntaxKind.FieldExpression to PropertyFieldAccess.

Comment on lines +26 to +30
PopulateNullability(trapFile, Symbol.GetAnnotatedType());

var unboundFieldKey = PropertyField.Create(Context, Symbol.OriginalDefinition);
var name = Symbol.AssociatedSymbol is not null ? $"{Symbol.AssociatedSymbol.GetName()}.field" : Symbol.Name;
trapFile.fields(this, VariableKind.None, name, ContainingType!, Type.TypeRef, unboundFieldKey);
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PropertyField.Populate only emits the fields row (plus nullability/location) but does not extract attributes/modifiers/ref-kind like Field.Populate does. As a result the synthetic backing field will be missing has_modifiers (e.g. private/static/readonly/required) and any [field: ...] attributes that Roslyn attaches to the backing field symbol. Consider reusing the same extraction steps as Field.Populate (at least PopulateAttributes() + PopulateModifiers(trapFile) and PopulateRefKind).

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uh, it is a really good point that we should extract the modifiers. For static properties, the generated backing field is also static (which might be relevant - otherwise it looks like a static property accesses a non-static field).
However,

  • Properties can't be ref, in, out etc, so there is no need to attempt to extract such information.
  • Also, I don't see the need to extracting attributes either.

@michaelnebel michaelnebel marked this pull request as draft February 13, 2026 12:01
@michaelnebel michaelnebel marked this pull request as ready for review February 13, 2026 14:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant