Skip to content

Detect read-only not private fields and fix adding the "readonly" modifier #177#292

Merged
carloscds merged 2 commits intocode-cracker:masterfrom
dmgandini:DetectReadOnlyFieldsCandidatesThroughTheSolution
Mar 2, 2015
Merged

Detect read-only not private fields and fix adding the "readonly" modifier #177#292
carloscds merged 2 commits intocode-cracker:masterfrom
dmgandini:DetectReadOnlyFieldsCandidatesThroughTheSolution

Conversation

@dmgandini
Copy link
Copy Markdown

No description provided.

@carloscds
Copy link
Copy Markdown

@dmgandini I think that it´s a conflict between two analyzers: ReadonlyFieldAnalyzer and NoPrivateReadonlyFieldAnalyzer. For example, this code:

public class Foo
    {
        private int i = 0;
    }

It´s analyzed by both analyzers, but only ReadonlyFieldAnalyzer create diagnostic and trigger fix, although there is a test that says that this is not an error for analyzer (PrivateFieldWithAssignmentOnDeclarationCreatesNoDiagnostic). Test is using only NoPrivateReadonlyFieldAnalyzer, but executing project and creating a code, both analyzers are running.

Can you check this ?

@dmgandini
Copy link
Copy Markdown
Author

@carloscds It is the expected behavior as far as I understood the issue.
The ReadonlyFieldAnalyzer performs tests against private fields, because it needs to search in a single type.

The NoPrivateReadonlyFieldAnalyzer will chase the other modifiers, because it depends to search through other types. On compilation time.

So its normal one analyser be trigged and the another one be quiet, they have different views of same problem and both are correct.

You can argue that NoPrivateReadonlyFieldAnalyzer could do the both roles if CanBecameReadOnlyField method be changed, but It is healthy to keep two analysers because:

NoPrivateReadonlyFieldAnalyzer performs tests only on compilation and its not quite common to have a public fields exposed on types.

ReadonlyFieldAnalyzer does not depend on any compilation and its a common scenario.

@dmgandini dmgandini closed this Mar 2, 2015
@dmgandini dmgandini reopened this Mar 2, 2015
carloscds pushed a commit that referenced this pull request Mar 2, 2015
…ThroughTheSolution

Detect read-only not private fields and fix adding the "readonly" modifier #177
@carloscds carloscds merged commit 812bfb3 into code-cracker:master Mar 2, 2015
@giggio
Copy link
Copy Markdown
Member

giggio commented Mar 3, 2015

@dmgandini The diagnostic id is wrong, number 74 was assigned to another issue. @carloscds be careful to check the wiki. I have updated the wiki so fix this: https://github.com/code-cracker/code-cracker/wiki/DiagnosticIds/_compare/47cbc9af8941a664f3ffb85c9d599b4976b37ec1...d1353edefb9a428e43955defd731309bf04346cf

@giggio
Copy link
Copy Markdown
Member

giggio commented Mar 3, 2015

I am not sure if the best implementation here is to the analyzis manually. Probably it would be better to use SemanticModel.AnalyzeDataFlow. I will open an issue to review this.

@giggio
Copy link
Copy Markdown
Member

giggio commented Mar 3, 2015

@dmgandini AnalyzeDataFlow is not working for out/ref parameters. So I will leave it as is by now.

Another issue: I have disabled the analyzer for another reason: as it runs very late on the compilation stage (only when the compilation ends), it might happen that a field no longer can be made readonly, and the diagnostic remains. This is a problem, as the user might run the code fix, and that might actually break the code.
I am going to open a bug to work on the code fix for that specific case. The diagnostic actually has to run again before the code fix is done, and maybe not offer a fix at all if the user has changed something and the compilation end event did not run yet.
BTW, any idea on how to solve this problem?

Also, I have changed the registration of the compilation end to happen on the compilation start. See this line:

compilationStartContext.RegisterCompilationEndAction(compilationEndContext =>

This is because the way things were made it would not run always, leaving the old diagnostic hanging longer.
I also changed the compilation not to happen on syntax trees, but on specific syntax nodes (class, structure and field), so the analyzer itself does not need to search, the search is done in a much more faster way by the Roslyn compiler itself, which just calls us when we need. Most of the code is untouched, I did small changes, even though the document was mostly reformatted.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants