Roslyn #5
نویسنده: وحید نصیری
تاریخ: ۱۳۹۴/۰۶/۳۰ ۱۵:۴۰
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
public struct Optional<T>
{
public bool HasValue { get; }
public T Value { get; }
} class ConsoleWriteLineWalker : CSharpSyntaxWalker
{
public ConsoleWriteLineWalker()
{
Arguments = new List<ExpressionSyntax>();
}
public List<ExpressionSyntax> Arguments { get; }
public override void VisitInvocationExpression(InvocationExpressionSyntax node)
{
var member = node.Expression as MemberAccessExpressionSyntax;
var type = member?.Expression as IdentifierNameSyntax;
if (type != null && type.Identifier.Text == "Console" && member.Name.Identifier.Text == "WriteLine")
{
if (node.ArgumentList.Arguments.Count == 1)
{
var arg = node.ArgumentList.Arguments.Single().Expression;
Arguments.Add(arg);
return;
}
}
base.VisitInvocationExpression(node);
}
} static void getConstantValue()
{
// Get the syntax tree.
var code = @"
using System;
class Foo
{
void Bar(int x)
{
Console.WriteLine(3.14);
Console.WriteLine(""qux"");
Console.WriteLine('c');
Console.WriteLine(null);
Console.WriteLine(x * 2 + 1);
}
}
";
var tree = CSharpSyntaxTree.ParseText(code);
var root = tree.GetRoot();
// Get the semantic model from the compilation.
var mscorlib = MetadataReference.CreateFromFile(typeof(object).Assembly.Location);
var comp = CSharpCompilation.Create("Demo").AddSyntaxTrees(tree).AddReferences(mscorlib);
var model = comp.GetSemanticModel(tree);
// Traverse the tree.
var walker = new ConsoleWriteLineWalker();
walker.Visit(root);
// Analyze the constant argument (if any).
foreach (var arg in walker.Arguments)
{
var val = model.GetConstantValue(arg);
if (val.HasValue)
{
Console.WriteLine(arg + " has constant value " + (val.Value ?? "null") + " of type " + (val.Value?.GetType() ?? typeof(object)));
}
else
{
Console.WriteLine(arg + " has no constant value");
}
}
} 3.14 has constant value 3.14 of type System.Double "qux" has constant value qux of type System.String 'c' has constant value c of type System.Char null has constant value null of type System.Object x * 2 + 1 has no constant value
static void workingWithSymbols()
{
// Get the syntax tree.
var code = @"
using System;
class Foo
{
void Bar(int x)
{
// #insideBar
}
}
class Qux
{
protected int Baz { get; set; }
}
";
var tree = CSharpSyntaxTree.ParseText(code);
var root = tree.GetRoot();
// Get the semantic model from the compilation.
var mscorlib = MetadataReference.CreateFromFile(typeof(object).Assembly.Location);
var comp = CSharpCompilation.Create("Demo").AddSyntaxTrees(tree).AddReferences(mscorlib);
var model = comp.GetSemanticModel(tree);
// Traverse enclosing symbol hierarchy.
var cursor = code.IndexOf("#insideBar");
var barSymbol = model.GetEnclosingSymbol(cursor);
for (var symbol = barSymbol; symbol != null; symbol = symbol.ContainingSymbol)
{
Console.WriteLine(symbol);
}
// Analyze accessibility of Baz inside Bar.
var bazProp = ((CompilationUnitSyntax)root)
.Members.OfType<ClassDeclarationSyntax>()
.Single(m => m.Identifier.Text == "Qux")
.Members.OfType<PropertyDeclarationSyntax>()
.Single();
var bazSymbol = model.GetDeclaredSymbol(bazProp);
var canAccess = model.IsAccessible(cursor, bazSymbol);
} Foo.Bar(int) Foo <global namespace> Demo.exe Demo, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
static void bindingSymbols()
{
// Get the syntax tree.
var code = @"
using System;
class Foo
{
private int y;
void Bar(int x)
{
Console.WriteLine(x);
Console.WriteLine(y);
int z = 42;
Console.WriteLine(z);
Console.WriteLine(a);
}
}";
var tree = CSharpSyntaxTree.ParseText(code);
var root = tree.GetRoot();
// Get the semantic model from the compilation.
var mscorlib = MetadataReference.CreateFromFile(typeof(object).Assembly.Location);
var comp = CSharpCompilation.Create("Demo").AddSyntaxTrees(tree).AddReferences(mscorlib);
var model = comp.GetSemanticModel(tree);
// Traverse the tree.
var walker = new ConsoleWriteLineWalker();
walker.Visit(root);
// Bind the arguments.
foreach (var arg in walker.Arguments)
{
var symbol = model.GetSymbolInfo(arg);
if (symbol.Symbol != null)
{
Console.WriteLine(arg + " is bound to " + symbol.Symbol + " of type " + symbol.Symbol.Kind);
}
else
{
Console.WriteLine(arg + " could not be bound");
}
}
} x is bound to int of type Parameter y is bound to Foo.y of type Field z is bound to z of type Local a could not be bound