Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove backing fields when weaving generated classes #3088

Merged
merged 13 commits into from
Nov 18, 2022

Conversation

gagik
Copy link
Contributor

@gagik gagik commented Nov 11, 2022

Description

We are weaving the properties of the generated classes to go directly to the accessors, so the backing fields are unused. This PR attempts to remove them for generated classes.

Fixes #2994

TODO

  • Changelog entry
  • Tests (if applicable)

var il = prop.GetMethod.Body.GetILProcessor();
prop.GetMethod.Body.Instructions.Clear();
Copy link
Contributor Author

@gagik gagik Nov 11, 2022

Choose a reason for hiding this comment

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

I believe the previous implementation of replacing the getter was causing some unintended behavior, it was actually just adding instructions to the getter rather than removing the old instructions---the reason why this was not noticeable was because the old instruction became unreachable because of the ret/return statement. My ILSpy was actually giving me an error about this prior. One issue this was causing was the fact that it kept instructions that have a reference to the backing field, making it error-prone when removing them. This change makes it identical to the functionality in the ReplaceGeneratedClassSetter.

Copy link
Contributor

Choose a reason for hiding this comment

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

Good eye! Need to take a look at this

Copy link
Contributor Author

@gagik gagik left a comment

Choose a reason for hiding this comment

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

This seems to be working! At least with the classes we have so far, will probably need some more proper testing.

// it considers this th start index of backing field initializaion instructions.
// And removes all backing field instructions from end to start.
else if (instruction.OpCode == OpCodes.Ldarg_0) {
for(var j = backingFieldInstructionsEnd; j >= i; j--) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Setting backingFieldInstructionsEnd=-1 actually takes care of cases when we never come across any backing fields beforehand, but I could also more explicitly avoid this by doing something like if (instruction.OpCode == OpCodes.Ldarg_0 && backingFieldInstructionsEnd != -1)

Realm/Realm.Weaver/RealmWeaver.cs Outdated Show resolved Hide resolved
Realm/Realm.Weaver/RealmWeaver.cs Show resolved Hide resolved
Realm/Realm.Weaver/RealmWeaver.cs Outdated Show resolved Hide resolved
Copy link
Member

@nirinchev nirinchev left a comment

Choose a reason for hiding this comment

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

Looks reasonable - you'll need to add some spaces between if/for/foreach and ( and move all the opening braces to a newline 😄 I have a low priority background task to figure out a linter that will automatically do this for you, but for now it's a matter of looking at warnings and doing what the analyzer tells you.

Realm/Realm.Weaver/RealmWeaver.cs Outdated Show resolved Hide resolved
Realm/Realm.Weaver/RealmWeaver.cs Outdated Show resolved Hide resolved
Realm/Realm.Weaver/RealmWeaver.cs Outdated Show resolved Hide resolved
Realm/Realm.Weaver/RealmWeaver.cs Outdated Show resolved Hide resolved
Realm/Realm.Weaver/RealmWeaver.cs Outdated Show resolved Hide resolved
Realm/Realm.Weaver/RealmWeaver.cs Outdated Show resolved Hide resolved
Realm/Realm.Weaver/RealmWeaver.cs Show resolved Hide resolved
Realm/Realm.Weaver/RealmWeaver.cs Outdated Show resolved Hide resolved
var il = prop.GetMethod.Body.GetILProcessor();
prop.GetMethod.Body.Instructions.Clear();
Copy link
Contributor

Choose a reason for hiding this comment

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

Good eye! Need to take a look at this

@gagik gagik marked this pull request as ready for review November 16, 2022 11:57
@gagik gagik changed the title Add attempt at backing field removal Remove backing fields during source generator weaving Nov 16, 2022
@gagik gagik changed the title Remove backing fields during source generator weaving Remove backing fields when weaving generated classes Nov 16, 2022
Copy link
Member

@nirinchev nirinchev left a comment

Choose a reason for hiding this comment

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

LGTM, only needs a minor clarification in the changelog

CHANGELOG.md Outdated Show resolved Hide resolved
@gagik gagik merged commit c9f1b87 into main Nov 18, 2022
@gagik gagik deleted the gagik/removebackingfields branch November 18, 2022 14:42
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 14, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[SG] Remove backing fields from generated class
3 participants