Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save tiesmaster/139a2d710ad8f919ffb1f82b37d830ff to your computer and use it in GitHub Desktop.
Save tiesmaster/139a2d710ad8f919ffb1f82b37d830ff to your computer and use it in GitHub Desktop.
<Query Kind="Statements">
<NuGetReference>Microsoft.CodeAnalysis</NuGetReference>
<NuGetReference>Microsoft.CodeAnalysis.CSharp</NuGetReference>
<Namespace>Microsoft.CodeAnalysis</Namespace>
<Namespace>Microsoft.CodeAnalysis.CSharp.Syntax</Namespace>
<Namespace>Microsoft.CodeAnalysis.MSBuild</Namespace>
<Namespace>Microsoft.CodeAnalysis.CSharp</Namespace>
<Namespace>Microsoft.CodeAnalysis.Formatting</Namespace>
<Namespace>Microsoft.CodeAnalysis.Text</Namespace>
</Query>
// possible answer to: http://stackoverflow.com/q/39741244
// create tree, and semantic model
var tree = CSharpSyntaxTree.ParseText(
@"public class Thing
{
public int Item { get; }
public Thing(int item)
{
Item = Item; // note incorrect assignment: rhs should be item, the passed-in arg, hence analyzer should warn
}
public Thing(Thing other)
{
Item = other.Item; // correct assignment, should NOT trigger analyzer
}
}")
//.DumpSyntaxTree("full tree")
;
var root = tree.GetRoot();
var mscorlib = MetadataReference.CreateFromFile(typeof(object).Assembly.Location);
var compilation = CSharpCompilation.Create("SO-39741244", syntaxTrees: new[] { tree }, references: new[] { mscorlib });
var model = compilation.GetSemanticModel(tree);
var incorrectAssignment = root.DescendantNodes().OfType<AssignmentExpressionSyntax>().First()
.DumpSyntaxNode("incorrect assignment")
;
var correctAssignment = root.DescendantNodes().OfType<AssignmentExpressionSyntax>().Last()
.DumpSyntaxNode("correct assignment")
;
var incorrectLhs = incorrectAssignment.Left.GetFirstToken().DumpTrace("incorrect lhs");
var incorrectRhs = incorrectAssignment.Right.GetFirstToken().DumpTrace("incorrect rhs");
var correctLhs = correctAssignment.Left.GetFirstToken().DumpTrace("correct lhs");
var correctRhs = correctAssignment.Right.GetLastToken().DumpTrace("correct rhs");
Action<string, SyntaxToken, SyntaxToken> compareTokens = (description, token1, token2) =>
{
description.Dump();
(token1 == token2).Dump("token1 == token2");
token1.Equals(token2).Dump("token1.Equals(token2)");
object.Equals(token1, token2).Dump("object.Equals(token1, token2)");
object.ReferenceEquals(token1, token2).Dump("object.ReferenceEquals(token1, token2)");
token1.IsEquivalentTo(token2).Dump("token1.IsEquivalentTo(token2)");
SyntaxFactory.AreEquivalent(token1, token2).Dump("SyntaxFactory.AreEquivalent(token1, token2)");
};
//compareTokens("incorrectLhs, incorrectRhs", incorrectLhs, incorrectRhs);
//compareTokens("correctLhs, correctRhs", correctLhs, correctRhs);
Action<string, AssignmentExpressionSyntax> checkForIncorrectAssignment = (description, assignmentNode) =>
{
"".Dump(description);
if (!assignmentNode.IsKind(SyntaxKind.SimpleAssignmentExpression))
{
"".Dump("Bailing, assignment expression is not simple");
return;
}
var lhs = assignmentNode.Left;
if (!lhs.IsKind(SyntaxKind.IdentifierName))
{
"".Dump("Bailing, lhs is not identifier name");
return;
}
var rhs = assignmentNode.Right;
if (!rhs.IsKind(SyntaxKind.IdentifierName))
{
"".Dump("Bailing, rhs is not identifier name");
return;
}
if (SyntaxFactory.AreEquivalent(lhs, rhs))
{
"".Dump("!!! REPORT");
}
else
{
"".Dump("Bailing, rhs is not identical to lhs");
lhs.GetFirstToken().Dump();
rhs.GetFirstToken().Dump();
}
};
checkForIncorrectAssignment("incorrectAssignment", incorrectAssignment);
checkForIncorrectAssignment("correctAssignment", correctAssignment);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment