Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Bu öğreticide Söz Dizimi API'sini bildiğiniz varsayılır. Söz dizimi analizini kullanmaya başlama makalesi yeterli giriş sağlar.
Bu öğreticide Sembol ve Bağlama API'lerini keşfedersiniz. Bu API'ler bir programın anlamsal anlamı hakkında bilgi sağlar. Bunlar, programınızdaki herhangi bir simgeyle temsil edilen türler hakkında sorular sormanıza ve yanıtlamanıza olanak tanır.
.NET Compiler Platform SDK'sını yüklemeniz gerekir:
Yükleme yönergeleri - Visual Studio Yükleyicisi
Visual Studio Yükleyicisi .NET Compiler Platform SDK'sını bulmanın iki farklı yolu vardır:
Visual Studio Yükleyicisi - İş yükleri görünümünü kullanarak yükleme
.NET Compiler Platform SDK'sı, Visual Studio uzantısı geliştirme iş yükünün bir parçası olarak otomatik olarak seçilmez. İsteğe bağlı bir bileşen olarak seçmelisiniz.
- Visual Studio Yükleyicisi çalıştırma
- Değiştir'i seçin
- Visual Studio uzantısı geliştirme iş yükünü denetleyin.
- Özet ağacında Visual Studio uzantısı geliştirme düğümünü açın.
- .NET Compiler Platform SDK kutusunu işaretleyin. Bunu isteğe bağlı bileşenler altında en son bulabilirsiniz.
İsteğe bağlı olarak, DGML düzenleyicisinin görselleştiricide grafikleri görüntülemesini de istersiniz:
- Özet ağacındaKim bileşenler düğümünü açın.
- DGML düzenleyicisi kutusunu işaretleyin
Visual Studio Yükleyicisi - Bağımsız bileşenler sekmesini kullanarak yükleme
- Visual Studio Yükleyicisi çalıştırma
- Değiştir'i seçin
- Tek tek bileşenler sekmesini seçin
- .NET Compiler Platform SDK kutusunu işaretleyin. En üstte Derleyiciler, derleme araçları ve çalışma zamanları bölümünde bulabilirsiniz.
İsteğe bağlı olarak, DGML düzenleyicisinin görselleştiricide grafikleri görüntülemesini de istersiniz:
- DGML düzenleyicisi kutusunu işaretleyin. Bunu Kod araçları bölümünde bulabilirsiniz.
Derlemeleri ve Simgeleri Anlama
.NET Derleyici SDK'sı ile daha fazla çalışırken Söz Dizimi API'siyle Anlam API'sinin arasındaki farkları tanımaya başladınız. Söz Dizimi API'si, bir programın yapısına bakmanızı sağlar. Ancak, genellikle bir programın semantiği veya anlamı hakkında daha zengin bilgiler istersiniz. Visual Basic veya C# kodunun gevşek bir kod dosyası veya parçacığı söz dizimsel olarak yalıtılmış olarak çözümlenebilir, ancak vakumda "bu değişkenin türü nedir" gibi sorular sormak anlamlı değildir. Tür adının anlamı derleme başvurularına, ad alanı içeri aktarmalarına veya diğer kod dosyalarına bağlı olabilir. Bu sorular semantik API,özellikleMicrosoft.CodeAnalysis.Compilation de sınıfı kullanılarak yanıtlandırılır.
örneği Compilation , derleyici tarafından görüldüğü gibi tek bir projeye benzer ve Visual Basic veya C# programını derlemek için gereken her şeyi temsil eder. Derleme derlenecek kaynak dosyaları kümesini, derleme başvurularını ve derleyici seçeneklerini içerir. Bu bağlamdaki diğer tüm bilgileri kullanarak kodun anlamını anlayabilirsiniz. A Compilation , adların ve diğer ifadelerin başvurdığı türler, ad alanları, üyeler ve değişkenler gibi varlıklar olan Sembolleri bulmanıza olanak tanır. Adları ve ifadeleri Simgelerle ilişkilendirme işlemi Bağlama olarak adlandırılır.
gibi Microsoft.CodeAnalysis.SyntaxTree, Compilation dile özgü türevleri olan soyut bir sınıftır. Derleme örneği oluştururken ( veya Microsoft.CodeAnalysis.VisualBasic.VisualBasicCompilation) sınıfında bir fabrika yöntemi Microsoft.CodeAnalysis.CSharp.CSharpCompilation çağırmanız gerekir.
Sembolleri sorgulama
Bu öğreticide, "Merhaba Dünya" programına yeniden göz atacaksınız. Bu kez, bu simgelerin hangi türleri temsil ettiğinizi anlamak için programdaki sembolleri sorgularsınız. Ad alanında türleri sorgular ve bir türdeki kullanılabilir yöntemleri bulmayı öğrenirsiniz.
Bu örneğin tamamlanmış kodunu GitHub depomuzda görebilirsiniz.
Not
Söz Dizimi Ağacı türleri, programın farklı konumlarında geçerli olan farklı söz dizimi öğelerini açıklamak için devralmayı kullanır. Bu API'lerin kullanılması genellikle özellikleri veya koleksiyon üyelerini belirli türetilmiş türlere atama anlamına gelir. Aşağıdaki örneklerde atama ve atamalar, açıkça yazılan değişkenleri kullanan ayrı deyimlerdir. API'nin dönüş türlerini ve döndürülen nesnelerin çalışma zamanı türünü görmek için kodu okuyabilirsiniz. Uygulamada, örtük olarak yazılan değişkenleri kullanmak ve incelenen nesne türünü açıklamak için API adlarına güvenmek daha yaygındır.
Yeni bir C# Tek Başına Kod Çözümleme Aracı projesi oluşturun:
- Visual Studio'da, YeniProje iletişim kutusunu görüntülemek için Dosya> Yeni > Proje'yi seçin.
- Visual C#>Genişletilebilirlik'in altında Tek Başına Kod Çözümleme Aracı'nı seçin.
- Projenize "SemanticQuickStart" adını verin ve Tamam'a tıklayın.
Daha önce gösterilen temel "Merhaba Dünya!" programını analiz edeceksiniz.
Merhaba Dünya programının metnini sınıfınızda Program
sabit olarak ekleyin:
const string programText =
@"using System;
using System.Collections.Generic;
using System.Text;
namespace HelloWorld
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(""Hello, World!"");
}
}
}";
Ardından, sabitteki kod metninin programText
söz dizimi ağacını oluşturmak için aşağıdaki kodu ekleyin. Yönteminize Main
aşağıdaki satırı ekleyin:
SyntaxTree tree = CSharpSyntaxTree.ParseText(programText);
CompilationUnitSyntax root = tree.GetCompilationUnitRoot();
Ardından, önceden oluşturduğunuz ağaçtan bir CSharpCompilation oluşturun. "Merhaba Dünya" örneği ve Console türlerine String dayanır. Derlemenizde bu iki türü bildiren derlemeye başvurmanız gerekir. Söz dizimi ağacınızın derlemesini oluşturmak için aşağıdaki satırı yönteminize Main
ekleyin ve uygun derlemeye başvuru ekleyin:
var compilation = CSharpCompilation.Create("HelloWorld")
.AddReferences(MetadataReference.CreateFromFile(
typeof(string).Assembly.Location))
.AddSyntaxTrees(tree);
yöntemi derlemeye CSharpCompilation.AddReferences başvurular ekler. yöntemi bir MetadataReference.CreateFromFile derlemeyi başvuru olarak yükler.
Anlam modelini sorgulama
Bir sahip Compilation olduktan sonra, içindekiler SyntaxTreeCompilationiçin SemanticModel bir isteyebilirsiniz. Semantik modeli, normalde IntelliSense'ten alabileceğiniz tüm bilgilerin kaynağı olarak düşünebilirsiniz. A SemanticModel , "Bu konumdaki kapsamda hangi adlar var?", "Bu yöntemden hangi üyelere erişilebilir?", "Bu metin bloğunda hangi değişkenler kullanılıyor?" ve "Bu ad/ifade neye başvurur?" gibi soruları yanıtlayabilir. Anlam modelini oluşturmak için şu deyimi ekleyin:
SemanticModel model = compilation.GetSemanticModel(tree);
Ad bağlama
, Compilation 'den SyntaxTreeöğesini SemanticModel oluşturur. Modeli oluşturduktan sonra ilk yönergeyi bulmak using
için sorgulayabilir ve ad alanının sembol bilgilerini System
alabilirsiniz. Semantik modeli oluşturmak ve ilk using deyiminin simgesini almak için yönteminize Main
şu iki satırı ekleyin:
// Use the syntax tree to find "using System;"
UsingDirectiveSyntax usingSystem = root.Usings[0];
NameSyntax systemName = usingSystem.Name;
// Use the semantic model for symbol information:
SymbolInfo nameInfo = model.GetSymbolInfo(systemName);
Yukarıdaki kod, ad alanı için bir Microsoft.CodeAnalysis.SymbolInfo almak üzere ilk using
yönergede adın nasıl bağlanacağını System
gösterir. Yukarıdaki kod, kodun yapısını bulmak için söz dizimi modelini kullandığınızı da gösterir; anlam modelini anlamını anlamak için kullanırsınız. Söz dizimi modeli using deyimindeki dizeyi System
bulur. Anlam modeli, ad alanında System
tanımlanan türler hakkında tüm bilgilere sahiptir.
nesnesinden SymbolInfo özelliğini kullanarak SymbolInfo.Symbol değerini alabilirsinizMicrosoft.CodeAnalysis.ISymbol. Bu özellik, bu ifadenin başvurduğu simgeyi döndürür. Hiçbir şeye (sayısal değişmez değerler gibi) başvurmayen ifadeler için bu özellik şeklindedir null
. SymbolInfo.Symbol null olmadığında, ISymbol.Kind simgenin türünü belirtir. Bu örnekte ISymbol.Kind özelliği bir SymbolKind.Namespaceşeklindedir. Aşağıdaki kodu yönteminize Main
ekleyin. Ad alanının simgesini System
alır ve ardından ad alanında bildirilen System
tüm alt ad alanlarını görüntüler:
var systemSymbol = (INamespaceSymbol?)nameInfo.Symbol;
if (systemSymbol?.GetNamespaceMembers() is not null)
{
foreach (INamespaceSymbol ns in systemSymbol?.GetNamespaceMembers()!)
{
Console.WriteLine(ns);
}
}
Programı çalıştırdığınızda aşağıdaki çıkışı görmeniz gerekir:
System.Collections
System.Configuration
System.Deployment
System.Diagnostics
System.Globalization
System.IO
System.Numerics
System.Reflection
System.Resources
System.Runtime
System.Security
System.StubHelpers
System.Text
System.Threading
Press any key to continue . . .
Not
Çıktı, ad alanının alt ad alanı olan her ad alanını System
içermez. Bu derlemede bulunan ve yalnızca bildirildiği System.String
derlemeye başvuran tüm ad alanlarını görüntüler. Diğer derlemelerde bildirilen ad alanları bu derleme tarafından bilinmemektedir
İfade bağlama
Yukarıdaki kod, bir ada bağlayarak sembol bulmayı gösterir. C# programında ad olmayan bağlanabilen başka ifadeler de vardır. Bu özelliği göstermek için bağlamaya basit bir dize değişmez değerine erişelim.
"Merhaba Dünya" programı, konsolunda görüntülenen "Hello, World!" dizesini içerirMicrosoft.CodeAnalysis.CSharp.Syntax.LiteralExpressionSyntax.
Programda tek dize değişmez değeri bularak "Hello, World!" dizesini bulursunuz. Ardından söz dizimi düğümünü bulduktan sonra söz dizimi modelinden söz dizimi için tür bilgilerini alın. Yönteminize Main
aşağıdaki kodu ekleyin:
// Use the syntax model to find the literal string:
LiteralExpressionSyntax helloWorldString = root.DescendantNodes()
.OfType<LiteralExpressionSyntax>()
.Single();
// Use the semantic model for type information:
TypeInfo literalInfo = model.GetTypeInfo(helloWorldString);
yapısı, Microsoft.CodeAnalysis.TypeInfo değişmez değerin türüyle ilgili anlamsal bilgilere erişim sağlayan bir TypeInfo.Type özellik içerir. Bu örnekte, türü budur string
. Bu özelliği yerel değişkene atayan bir bildirim ekleyin:
var stringTypeSymbol = (INamedTypeSymbol?)literalInfo.Type;
Bu öğreticiyi tamamlamak için türünde bildirilen string
ve döndüren tüm genel yöntemlerin bir dizisini oluşturan bir string
LINQ sorgusu oluşturalım. Bu sorgu karmaşık hale geldiğinden satır satır derleyelim ve ardından tek bir sorgu olarak yeniden oluşturalım. Bu sorgunun kaynağı, türüne göre bildirilen tüm üyelerin string
dizisidir:
var allMembers = stringTypeSymbol?.GetMembers();
Bu kaynak dizisi özellikler ve alanlar da dahil olmak üzere tüm üyeleri içerir, bu nedenle nesne olan Microsoft.CodeAnalysis.IMethodSymbol öğeleri bulmak için yöntemini kullanarak ImmutableArray<T>.OfType filtreleyin:
var methods = allMembers?.OfType<IMethodSymbol>();
Ardından, yalnızca genel olan yöntemleri döndürecek ve bir döndürecek başka bir string
filtre ekleyin:
var publicStringReturningMethods = methods?
.Where(m => SymbolEqualityComparer.Default.Equals(m.ReturnType, stringTypeSymbol) &&
m.DeclaredAccessibility == Accessibility.Public);
Herhangi bir aşırı yüklemeyi kaldırarak yalnızca name özelliğini ve yalnızca benzersiz adları seçin:
var distinctMethods = publicStringReturningMethods?.Select(m => m.Name).Distinct();
Ayrıca LINQ sorgu söz dizimini kullanarak tam sorgu oluşturabilir ve ardından konsolda tüm yöntem adlarını görüntüleyebilirsiniz:
foreach (string name in (from method in stringTypeSymbol?
.GetMembers().OfType<IMethodSymbol>()
where SymbolEqualityComparer.Default.Equals(method.ReturnType, stringTypeSymbol) &&
method.DeclaredAccessibility == Accessibility.Public
select method.Name).Distinct())
{
Console.WriteLine(name);
}
Programı derleyin ve çalıştırın. Aşağıdaki çıkışı görmeniz gerekir:
Join
Substring
Trim
TrimStart
TrimEnd
Normalize
PadLeft
PadRight
ToLower
ToLowerInvariant
ToUpper
ToUpperInvariant
ToString
Insert
Replace
Remove
Format
Copy
Concat
Intern
IsInterned
Press any key to continue . . .
Bu programın parçası olan semboller hakkında bilgi bulmak ve görüntülemek için Anlam API'sini kullandınız.