diff --git a/data/resources/StringResources.de.resx b/data/resources/StringResources.de.resx index bc5f5117f2..25972a7c0c 100644 --- a/data/resources/StringResources.de.resx +++ b/data/resources/StringResources.de.resx @@ -1498,6 +1498,12 @@ Beispiele: "120", "MainClass", "Main.cs, 120". Kursiv + + Hervorhebungsfarben exportieren + + + Hervorhebungsfarben importieren + Wert @@ -2181,11 +2187,14 @@ Wollen Sie die neue Datei zum Projekt ${CurrentProjectName} hinzufügen? Deaktiviert - Markierungen und Liniale + Markierungen Markierungen und Liniale + + Lineale + Verdeckte Definitionen anzeigen (nur geschweifte Klammern) @@ -5393,6 +5402,12 @@ Microsoft.Tools.WindowsInstallerXml.Extensions.NetFxCompiler, WixNetFxExtension< Kommandozeile hier öffnen + + Ziel-Frameworks wählen + + + Konnte die Portable Class Library Tools nicht finden. + Alle Knoten einklappen diff --git a/data/resources/StringResources.nl.resx b/data/resources/StringResources.nl.resx index 5660fe197f..c72858459a 100644 --- a/data/resources/StringResources.nl.resx +++ b/data/resources/StringResources.nl.resx @@ -1501,6 +1501,12 @@ Voorbeelden: "120", "MainClass", "Main.cs, 120". Cursief + + Selectie kleuren expoorteren + + + Selectie kleuren importeren + Waarde @@ -2184,11 +2190,14 @@ Wilt u het nieuwe bestand toevoegen aan project ${CurrentProjectName}? Geen - Markeringen en Linealen + Markeringen Markeringen en Linealen + + Linealen + Toon &verborgen definities(alleen haakjes) @@ -2355,7 +2364,7 @@ Wilt u het nieuwe bestand toevoegen aan project ${CurrentProjectName}? 32 bit Intel-compatibele processor - Doel Framework: + Doel raamwerk: Behandel waarschuwingen als fouten @@ -3046,7 +3055,7 @@ Er kan worden gekozen voor opslag van de instellingen in het .user bestand inpla Bezig met Code Analyse... - Onbekend doel Mono Framework Versie: + Onbekend doel Mono Raamwerk Versie: Code Analyse @@ -4090,7 +4099,7 @@ Alleen letters, getallen, spatie, '.' of '_' zijn toegestaan. Converteer geselecteerde &projecten naar - Wijzig doel framework + Wijzig doel Raamwerk: Versie van geselecteerde projecten wijzigen @@ -4105,7 +4114,7 @@ Alleen letters, getallen, spatie, '.' of '_' zijn toegestaan. <niet wijzigen> - Doel framework + Doel Raamwerk Project opwaarderen @@ -4119,7 +4128,7 @@ Zonder opwaarderen kan het project niet geopend wordenh. Opwaarderen naar MSBuild ${NewToolsVersion} - Deze oplossing werd met een vorige versie van SharpDevelop gemaakt. Door te upgraden kan gebruik gemaakt worden van nieuwe taal of framework mogelijkheden. + Deze oplossing werd met een eerdere versie van SharpDevelop gemaakt. Door te upgraden kan gebruik gemaakt worden van nieuwe taal- of raamwerk mogelijkheden. Momentele ambience niet gevonden. @@ -4427,7 +4436,7 @@ Microsoft.Tools.WindowsInstallerXml.Extenties.NetFxCompiler, WixNetFxExtentieWiX localisatie bestanden - .NET Framework uitbreiding + .NET Raamwerk uitbreiding Geen verschil gevonden. @@ -5383,6 +5392,27 @@ Microsoft.Tools.WindowsInstallerXml.Extenties.NetFxCompiler, WixNetFxExtentie Open hier de commando prompt + + Selecteer doel-raamwerken. + + + Kan Portable Klasse-bibliotheek gereedschap niet vinden. + + + .NET Portable subset + + + Er moeten tenminste twee raamwerken worden geselecteerd. + + + Gekozen profiel: + + + Kies een Portable Bibliotheek profiel. + + + Om de portabele Klassebibliotheek gereedschappen te installeren zonder Visual Studio te installeren, sla het download bestand op (PortableLibraryTools.exe) op uw computer en voer de installatie uit via de commndoregel. Inclusief de /bouwmachine schakeling op de commandoregel. + Alle knooppunten invouwen @@ -6639,6 +6669,12 @@ De hulpbron bestanden zijn hernoemd/verplaatst op de beschreven wijze. Gtk# toepassing + + Bibliotheek, bruikbaar bij Windows, Silverlight, Windows Phone en Xbox. + + + Portable Klassen-bibliotheek + Windows installatie project om een MSI installatie programma te maken. @@ -6790,7 +6826,7 @@ De hulpbron bestanden zijn hernoemd/verplaatst op de beschreven wijze. Ontkoppel - Kan .NET Framework versie van het programma niet krijgen. Ga na of het programma een beheerde assembly is. + Kan .NET Raamwerk versie van het programma niet oproepen. Ga na of het programma een gemanagede assembly is. Kan niet bij proces aanhaken. @@ -6805,7 +6841,7 @@ De hulpbron bestanden zijn hernoemd/verplaatst op de beschreven wijze. Kan SharpDevelop foutopsporing niet starten omdat kernel foutopsporing is aangezet. Om de kernel foutopsporing uit te zetten, dient de schakeling "/debug" uit bestand Boot.ini verwijderd te worden en de computer opnieuw te worden opgestart. - Foutopsporing bij .NET Framework 1.0 programmas is niet ondersteund. + Foutopsporing bij .NET Raamwerk 1.0 programmas is niet ondersteund. Kan actie niet uitvoeren omdat er geen foutopsporing van een proces plaatsvindt. diff --git a/data/resources/StringResources.resx b/data/resources/StringResources.resx index ba1701c8ad..349f8aafef 100644 --- a/data/resources/StringResources.resx +++ b/data/resources/StringResources.resx @@ -2262,11 +2262,14 @@ system. I don't think that it needs translation. None - Markers and Rulers + Markers Markers and Rulers + + Rulers + Show &hidden definitions (brackets only) diff --git a/data/resources/StringResources.tr.resx b/data/resources/StringResources.tr.resx index 522ebaabdd..fc6118ebe1 100644 --- a/data/resources/StringResources.tr.resx +++ b/data/resources/StringResources.tr.resx @@ -608,7 +608,7 @@ {0} arayüz ekle - Taşma operatörü ekle + Aşırı yükleme operatörü ekle ${otherMethod} geçersiz ekleme @@ -1019,7 +1019,7 @@ Oluşturulan stili yenisiyle değiştirmek istiyor musunuz? Temel sınıf kategorisindeki nesne üyelerini göster - Sadece genel üyeler + Sadece public üyeler Kısa Bilgilendirme @@ -1069,7 +1069,7 @@ Olayları kayıt etmek için, Nesneler panelinden bir nesne yada olay seçip, ya Tüm seviyeler - Çevirmeler/Türler + Derlemeler/Türler İçerir @@ -1317,7 +1317,7 @@ Bir ActiveX / COM nesnesi oluşturmak / değiştirmek için, nesne ağacı veya Özellik/Olay erişim yöntemleri - Sadece genel üyeler + Sadece public üyeler Çıktı @@ -1470,7 +1470,7 @@ Bir ActiveX / COM nesnesi oluşturmak / değiştirmek için, nesne ağacı veya <Boş> - Yeni adı girin: + Yeni ad girin: Ad geçersiz. @@ -1498,6 +1498,12 @@ Satır numaraları, sınıf yada dosya adları girebilirsiniz. İtalik + + Renk vurgulamayı dışa aktar + + + Renk vurgulaması al + Değer @@ -1861,7 +1867,7 @@ Yeni dosyayı, ${CurrentProjectName} projesine eklemek istiyor musunuz? İstisnalar - Tanıtıcı istisnaları duraklat + Yakalanan istisnaları duraklat Adımlama @@ -2182,11 +2188,14 @@ Yeni dosyayı, ${CurrentProjectName} projesine eklemek istiyor musunuz? Hiçbiri - İşaretleyiciler ve Cetveller + İşaretleyiciler İşaretleyiciler ve Cetveller + + Cetveller + Gizli tanımları (sadece parentezler) göster @@ -4717,7 +4726,7 @@ Microsoft.Tools.WindowsInstallerXml.Extensions.NetFXCompiler, WixNetFxExtension< parametre - Taşma + Aşırı yükleme Geçerli değişiklikleri kaydetmek istiyor musunuz? @@ -4765,16 +4774,16 @@ Microsoft.Tools.WindowsInstallerXml.Extensions.NetFXCompiler, WixNetFxExtension< Diğer Üyeleri Göster - Gizli Üyeleri Göster + Private Üyeleri Göster Proje Referanslarını Göster - Korunmuş Üyeleri Göster + Protected Üyeleri Göster - Genel Üyeleri Göster + Public Üyeleri Göster Sınıf Görünüm Ayarları @@ -4912,7 +4921,7 @@ Microsoft.Tools.WindowsInstallerXml.Extensions.NetFXCompiler, WixNetFxExtension< İstisnaya müdahale edilemedi. Hata ayıklaması yapılan program daha fazla devam edemez. - İşlenen istisnaya müdahale edilemedi. Hata ayıklama sembolleri istisna kaynağı için mevcut olmayabilir. + Yakalanan istisnaya müdahale edilemedi. Hata ayıklama sembolleri istisna kaynağı için mevcut olmayabilir. İstisna Detaylarını Gizle @@ -4939,10 +4948,10 @@ Microsoft.Tools.WindowsInstallerXml.Extensions.NetFXCompiler, WixNetFxExtension< İstisna - İşlenen istisna + Yakalanan istisna - İşlenmeyen istisna + Bilinmeyen istisna İstisna geçmişi @@ -4984,16 +4993,16 @@ Microsoft.Tools.WindowsInstallerXml.Extensions.NetFXCompiler, WixNetFxExtension< Ad - Genel üyeler dışında + Public üyeler dışında - Genel sabit üyeler dışında + Public Static üyeler dışında - Özel üyeler + Private üyeler - Özel Sabit Üyeler + Private Static Üyeler Hatanın tümünü göster... @@ -5002,7 +5011,7 @@ Microsoft.Tools.WindowsInstallerXml.Extensions.NetFXCompiler, WixNetFxExtension< Değerleri onaltılık göster - Sabit üyeler + Static üyeler Tür @@ -5323,7 +5332,7 @@ Microsoft.Tools.WindowsInstallerXml.Extensions.NetFXCompiler, WixNetFxExtension< Doğrulama: başarılı - Test çevirmeleri yüklenemiyor, kendiliğinden yükleme iptal edildi. + Test derlemeleri yüklenemiyor, kendiliğinden yükleme iptal edildi. Tanimlamaya &git @@ -5332,7 +5341,7 @@ Microsoft.Tools.WindowsInstallerXml.Extensions.NetFXCompiler, WixNetFxExtension< Mevcut seçili projedeki NUnit 'e referans ekle - Test çevirmelerini yeniden yükler + Test derlemelerini yeniden yükler Bütün testleri çalıştır @@ -5359,25 +5368,25 @@ Microsoft.Tools.WindowsInstallerXml.Extensions.NetFXCompiler, WixNetFxExtension< Test durumu '${TestCase}' yürütülemedi. - Çevirme Yükle... + Derleme Yükle... - Referanslı Çevirmeleri Yükle + Referanslı Derlemeleri Yükle - Standart Çevirmeleri Yükle + Standart Derlemeleri Yükle - &Kapat + Kapat Bu hariç hepsini kapat - K&aydet + Kaydet - Farklı Ka&ydet... + Farklı Kaydet... Dosya yolunu/adını kopyala @@ -5388,6 +5397,27 @@ Microsoft.Tools.WindowsInstallerXml.Extensions.NetFXCompiler, WixNetFxExtension< Burada komut istemi aç + + hedef çalışmaçerçevesini seçin + + + Taşınabilir Sınıf Kitaplığı Araçları bulunamadı. + + + .NET Taşınabilir AltSeti + + + İki veya daha fazla çerçevenin seçilmesi gerekir. + + + Seçili profil: + + + Taşınabilir Kitaplık Profili seç + + + Visual Studio yüklemeden Taşınabilir Sınıf Kitaplığı Araçları'nı yüklemek için,bilgisayarınıza dosyayı(PortableLibraryTools.exe)indirip kaydedin ve bir komut istemi penceresinde kurulum programını çalıştırın.Komut satırında /buildmachine anahtarı ekleyin. + Bütün düğümleri daralt @@ -5422,7 +5452,7 @@ Microsoft.Tools.WindowsInstallerXml.Extensions.NetFXCompiler, WixNetFxExtension< Web Referansı Ekle - D&erle + Derle Temizle @@ -5542,10 +5572,10 @@ Microsoft.Tools.WindowsInstallerXml.Extensions.NetFXCompiler, WixNetFxExtension< Tüm web referanslarını sil - Çevirmeler (*.dll)|*.dll + Derlemeler (*.dll)|*.dll - Çevirme + Derleme Sınıf adı @@ -5554,7 +5584,7 @@ Microsoft.Tools.WindowsInstallerXml.Extensions.NetFXCompiler, WixNetFxExtension< Derle - Çevirme oluştur + Derleme oluştur ECMA betiği @@ -5584,7 +5614,7 @@ Microsoft.Tools.WindowsInstallerXml.Extensions.NetFXCompiler, WixNetFxExtension< Çok satırlı - Adalanı + Ad alanı Açıkça görünür @@ -5659,7 +5689,7 @@ Microsoft.Tools.WindowsInstallerXml.Extensions.NetFXCompiler, WixNetFxExtension< Sözcük olmayan karakter değeri - Tok yıldız + Dolu yıldız Boşluk karakteri @@ -6305,7 +6335,7 @@ Kaynak dosyaları buna göre yeniden adlandırıldı/taşındı. Yapılandırma Eleman Koleksiyonundan türeme sınıf. - Nesne Yığını Ayarları + Yapılandırma Elemanı Koleksiyonu ConfigurationSection gerçeklemesi yapan sınıf @@ -6326,10 +6356,10 @@ Kaynak dosyaları buna göre yeniden adlandırıldı/taşındı. Boş Dosya - Yeni bir Kuraldışı Sınıf oluştur. + Yeni bir istisna Sınıf oluştur. - Kuraldışı Durum + İstisna Bir Gtk# uygulaması için pencere @@ -6368,7 +6398,7 @@ Kaynak dosyaları buna göre yeniden adlandırıldı/taşındı. MSBuild dosyası - "My" alanadını uzatan sınıf için bir şablon. + "My" ad alanını uzatan sınıf için bir şablon. "My" uzantılar @@ -6605,7 +6635,7 @@ Kaynak dosyaları buna göre yeniden adlandırıldı/taşındı. Başka uygulamalarda kullanılabilen sınıflar oluşturan bir proje. - Sınıf Kütüphanesi + Sınıf Kitaplığı Komut satırı uygulaması oluşturan proje. @@ -6643,6 +6673,12 @@ Kaynak dosyaları buna göre yeniden adlandırıldı/taşındı. Gtk# Uygulaması + + Windows, Silverlight, Windows Phone ve Xbox kullanılabilir Kitaplığı. + + + Taşınabilir Sınıf Kitaplığı + MSI Installer oluşturabilmek için bir Windows Installer projesi. @@ -6728,7 +6764,7 @@ Kaynak dosyaları buna göre yeniden adlandırıldı/taşındı. Kenarçubuğu Yapılandır... - &Analiz + Analiz Derle @@ -6788,13 +6824,13 @@ Kaynak dosyaları buna göre yeniden adlandırıldı/taşındı. Hata ayıklamaya devam et - İşlemin yürütülmesine devam eder. + İşlemin yürütülmesine devam edilir. Bırak - Programın .NET Framework sürüm numarası bulunamadı. Programın yönetilen çevirici olup olmadığını kontrol edin. + Programın .NET Framework sürüm numarası bulunamadı. Programın yönetilen derleme olup olmadığını kontrol edin. İşleme eklenemiyor. @@ -6827,7 +6863,7 @@ Kaynak dosyaları buna göre yeniden adlandırıldı/taşındı. Önceki derlemeyi çalıştır - Hata ayıklayıcı olmadan çalıştır + Hata ayıklamadan çalıştır Programı normal olarak çalıştırır. @@ -7235,7 +7271,7 @@ Kaynak dosyaları buna göre yeniden adlandırıldı/taşındı. Tüm Yer İmlerini Temizle - Mevcut tampondaki tüm yer imlerini temizle + Mevcut tampondaki tüm yer imlerini temizler Bul... @@ -7326,7 +7362,7 @@ Başlatma hatası: Kurulum - Diyaloglar + İletişim Kutuları Dosyalar diff --git a/src/AddIns/BackendBindings/VBNetBinding/Project/Src/FormattingStrategy/VBNetFormattingStrategy.cs b/src/AddIns/BackendBindings/VBNetBinding/Project/Src/FormattingStrategy/VBNetFormattingStrategy.cs index 5fa9e46fec..3cf7d13709 100644 --- a/src/AddIns/BackendBindings/VBNetBinding/Project/Src/FormattingStrategy/VBNetFormattingStrategy.cs +++ b/src/AddIns/BackendBindings/VBNetBinding/Project/Src/FormattingStrategy/VBNetFormattingStrategy.cs @@ -832,22 +832,14 @@ namespace ICSharpCode.VBNetBinding internal static bool IsBlockEnd(Token current, Token prev) { - if (current.Kind == Tokens.Next) { - if (prev.Kind == Tokens.Resume) - return false; - else - return true; - } + if (current.Kind == Tokens.Next) + return prev.Kind == Tokens.EOL || prev.Kind == Tokens.Colon; if (current.Kind == Tokens.Loop) - return true; + return prev.Kind == Tokens.EOL || prev.Kind == Tokens.Colon; - if (blockTokens.Contains(current.Kind)) { - if (prev.Kind == Tokens.End) - return true; - else - return false; - } + if (blockTokens.Contains(current.Kind)) + return prev.Kind == Tokens.End; return IsSpecialCase(current, prev); } diff --git a/src/AddIns/BackendBindings/VBNetBinding/Test/FormattingStrategy/IndentationTests.cs b/src/AddIns/BackendBindings/VBNetBinding/Test/FormattingStrategy/IndentationTests.cs index 9bf3974b77..da07315820 100644 --- a/src/AddIns/BackendBindings/VBNetBinding/Test/FormattingStrategy/IndentationTests.cs +++ b/src/AddIns/BackendBindings/VBNetBinding/Test/FormattingStrategy/IndentationTests.cs @@ -524,6 +524,54 @@ End Module"; RunFormatTest(code, expected); } + [Test] + public void ForNextOneLine() + { + string expected = @"Module Core + Sub Main + Dim a = 1 + For i = 0 To 10 : Console.WriteLine(i) : Next + Dim b = 2 + End Sub +End Module"; + + string code = @"Module Core +Sub Main +Dim a = 1 +For i = 0 To 10 : Console.WriteLine(i) : Next +Dim b = 2 +End Sub +End Module"; + + RunFormatTest(code, expected); + } + + [Test] + public void RandomNext() + { + string expected = @"Module Core + Public Function GetRandomNumber( _ + Optional ByVal Low As Integer = 1, _ + Optional ByVal High As Integer = 100) As Integer + ' Returns a random number, + ' between the optional Low and High parameters + Return objRandom.Next(Low, High + 1) + End Function +End Module"; + + string code = @"Module Core +Public Function GetRandomNumber( _ +Optional ByVal Low As Integer = 1, _ +Optional ByVal High As Integer = 100) As Integer +' Returns a random number, +' between the optional Low and High parameters +Return objRandom.Next(Low, High + 1) +End Function +End Module"; + + RunFormatTest(code, expected); + } + void RunFormatTest(string code, string expectedCode) { AvalonEditTextEditorAdapter editor = new AvalonEditTextEditorAdapter(new TextEditor()); diff --git a/src/AddIns/Debugger/Debugger.Core/IDStringProvider.cs b/src/AddIns/Debugger/Debugger.Core/IDStringProvider.cs index 36eaaf1d05..75162c8d2f 100644 --- a/src/AddIns/Debugger/Debugger.Core/IDStringProvider.cs +++ b/src/AddIns/Debugger/Debugger.Core/IDStringProvider.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Reflection; using System.Text; +using Debugger.MetaData; namespace Debugger { @@ -42,7 +43,11 @@ namespace Debugger MethodInfo mr = (MethodInfo)member; if (mr.IsGenericMethod) { b.Append("``"); - b.Append(mr.GetGenericArguments().Length); + // DebugMethodInfo does not implement GetGenericArguments + if (mr is DebugMethodInfo) + b.Append(((DebugMethodInfo)mr).GenericParameterCount); + else + b.Append(mr.GetGenericArguments().Length); } parameters = mr.GetParameters(); if (mr.Name == "op_Implicit" || mr.Name == "op_Explicit") { @@ -73,7 +78,7 @@ namespace Debugger return; } if (type.IsGenericType) { - AppendTypeNameWithArguments(b, type.GetElementType(), type.GetGenericArguments()); + AppendTypeNameWithArguments(b, type, type.GetGenericArguments()); } else if (type.HasElementType) { AppendTypeName(b, type.GetElementType()); if (type.IsArray) { diff --git a/src/AddIns/Debugger/Debugger.Core/MetaData/DebugMethodInfo.cs b/src/AddIns/Debugger/Debugger.Core/MetaData/DebugMethodInfo.cs index 37a0fed063..2f8f659726 100644 --- a/src/AddIns/Debugger/Debugger.Core/MetaData/DebugMethodInfo.cs +++ b/src/AddIns/Debugger/Debugger.Core/MetaData/DebugMethodInfo.cs @@ -195,6 +195,13 @@ namespace Debugger.MetaData get { return this.MethodDefSig.GenericParameterCount > 0; } } + /// + /// Gets the number of generic parameters on this method. + /// + public int GenericParameterCount { + get { return this.MethodDefSig.GenericParameterCount; } + } + /// public override RuntimeMethodHandle MethodHandle { get { throw new NotSupportedException(); } diff --git a/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerGenerator/AbstractDesignerGenerator.cs b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerGenerator/AbstractDesignerGenerator.cs index 9a9c4214f8..6c60742d5b 100644 --- a/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerGenerator/AbstractDesignerGenerator.cs +++ b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerGenerator/AbstractDesignerGenerator.cs @@ -317,7 +317,7 @@ namespace ICSharpCode.FormsDesigner /// code that is not supported in a previous version of .NET. (3.5 and below) /// Currently it fixes: /// - remove calls to ISupportInitialize.BeginInit/EndInit, if the interface is not implemented by the type in the target framework. - /// + /// /// When adding new workarounds make sure that the code does not remove too much code! void RemoveUnsupportedCode(CodeTypeDeclaration formClass, CodeMemberMethod initializeComponent) { @@ -339,16 +339,9 @@ namespace ICSharpCode.FormsDesigner CodeMethodInvokeExpression invocation = (CodeMethodInvokeExpression)stmt.Expression; CodeCastExpression expr = invocation.Method.TargetObject as CodeCastExpression; if (expr != null) { - CodeFieldReferenceExpression fieldRef = expr.Expression as CodeFieldReferenceExpression; - if (fieldRef == null || !(fieldRef.TargetObject is CodeThisReferenceExpression)) - continue; if (expr.TargetType.BaseType != "System.ComponentModel.ISupportInitialize") continue; - IField field = this.formClass.DefaultReturnType.GetFields() - .First(f => this.formClass.ProjectContent.Language.NameComparer.Equals(fieldRef.FieldName, f.Name)); - if (field.ReturnType == null) - continue; - IClass fieldType = field.ReturnType.GetUnderlyingClass(); + var fieldType = GetTypeOfControl(expr.Expression, initializeComponent, formClass); if (fieldType == null) continue; if (!fieldType.IsTypeInInheritanceTree(iSupportInitializeInterface)) @@ -361,6 +354,31 @@ namespace ICSharpCode.FormsDesigner } } + /// + /// Tries to find the type of the expression. + /// + IClass GetTypeOfControl(CodeExpression expression, CodeMemberMethod initializeComponentMethod, CodeTypeDeclaration formTypeDeclaration) + { + StringComparer comparer = formClass.ProjectContent.Language.NameComparer; + if (expression is CodeVariableReferenceExpression) { + string name = ((CodeVariableReferenceExpression)expression).VariableName; + var decl = initializeComponentMethod.Statements.OfType().Single(v => comparer.Equals(v.Name, name)); + return formClass.ProjectContent.GetClass(decl.Type.BaseType, 0); + } + if (expression is CodeFieldReferenceExpression && ((CodeFieldReferenceExpression)expression).TargetObject is CodeThisReferenceExpression) { + string name = ((CodeFieldReferenceExpression)expression).FieldName; + var decl = formTypeDeclaration.Members.OfType().FirstOrDefault(f => comparer.Equals(name, f.Name)); + if (decl != null) + return formClass.ProjectContent.GetClass(decl.Type.BaseType, 0); + var field = formClass.DefaultReturnType.GetFields() + .First(f => comparer.Equals(f.Name, name)); + if (field.ReturnType == null) + return null; + return field.ReturnType.GetUnderlyingClass(); + } + return null; + } + /// /// Compares the SharpDevelop.Dom field declaration oldField to /// the CodeDom field declaration newField. diff --git a/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerViewContent.cs b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerViewContent.cs index 29ea7692cc..d4218544ce 100644 --- a/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerViewContent.cs +++ b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerViewContent.cs @@ -159,6 +159,9 @@ namespace ICSharpCode.FormsDesigner { LoggingService.Debug("Forms designer: Load " + file.FileName + "; inMasterLoadOperation=" + this.inMasterLoadOperation); + if (this.typeResolutionService != null) + this.typeResolutionService.ClearCaches(); + if (inMasterLoadOperation) { if (this.sourceCodeStorage.ContainsFile(file)) { diff --git a/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/TypeResolutionService.cs b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/TypeResolutionService.cs index 3b484f99e6..837e3757f0 100644 --- a/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/TypeResolutionService.cs +++ b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/TypeResolutionService.cs @@ -361,6 +361,19 @@ namespace ICSharpCode.FormsDesigner.Services return GetType(name, throwOnError, false); } + #if DEBUG + int count = 0; + #endif + + Dictionary typeCache = new Dictionary(StringComparer.Ordinal); + Dictionary typeCacheIgnoreCase = new Dictionary(StringComparer.OrdinalIgnoreCase); + + public void ClearCaches() + { + typeCacheIgnoreCase.Clear(); + typeCache.Clear(); + } + public Type GetType(string name, bool throwOnError, bool ignoreCase) { if (name == null || name.Length == 0) { @@ -369,9 +382,19 @@ namespace ICSharpCode.FormsDesigner.Services if (IgnoreType(name)) { return null; } + if (ignoreCase) { + Type cachedType; + if (typeCacheIgnoreCase.TryGetValue(name, out cachedType)) + return cachedType; + } else { + Type cachedType; + if (typeCache.TryGetValue(name, out cachedType)) + return cachedType; + } #if DEBUG if (!name.StartsWith("System.")) { - LoggingService.Debug("TypeResolutionService: Looking for " + name); + count++; + LoggingService.Debug(count + " TypeResolutionService: Looking for " + name); } #endif try { @@ -436,6 +459,7 @@ namespace ICSharpCode.FormsDesigner.Services try { Type t = asm.GetType(name, false); if (t != null) { + AddToCache(name, t, ignoreCase); return t; } } catch (FileNotFoundException) { @@ -449,7 +473,7 @@ namespace ICSharpCode.FormsDesigner.Services if (throwOnError && type == null) throw new TypeLoadException(name + " not found by TypeResolutionService"); - + AddToCache(name, type, ignoreCase); return type; } catch (Exception e) { LoggingService.Error(e); @@ -457,6 +481,17 @@ namespace ICSharpCode.FormsDesigner.Services return null; } + void AddToCache(string name, Type type, bool ignoreCase) + { + if (type == null) + return; + if (ignoreCase) { + typeCacheIgnoreCase.Add(name, type); + } else { + typeCache.Add(name, type); + } + } + public void ReferenceAssembly(AssemblyName name) { ICSharpCode.Core.LoggingService.Warn("TODO: Add Assembly reference : " + name); diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/WpfViewContent.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/WpfViewContent.cs index 7914efbefa..44952fcbca 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/WpfViewContent.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/WpfViewContent.cs @@ -60,6 +60,7 @@ namespace ICSharpCode.WpfDesign.AddIn protected override void LoadInternal(OpenedFile file, System.IO.Stream stream) { + wasChangedInDesigner = false; Debug.Assert(file == this.PrimaryFile); _stream = new MemoryStream(); @@ -108,10 +109,11 @@ namespace ICSharpCode.WpfDesign.AddIn } private MemoryStream _stream; + bool wasChangedInDesigner; protected override void SaveInternal(OpenedFile file, System.IO.Stream stream) { - if (IsDirty && designer.DesignContext != null) { + if (wasChangedInDesigner && designer.DesignContext != null) { XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; settings.IndentChars = EditorControlService.GlobalOptions.IndentationString; @@ -120,12 +122,10 @@ namespace ICSharpCode.WpfDesign.AddIn designer.SaveDesigner(xmlWriter); } } else { - if (_stream.CanRead) { - _stream.Position = 0; - using (var reader = new StreamReader(_stream)) { - using (var writer = new StreamWriter(stream)) { - writer.Write(reader.ReadToEnd()); - } + _stream.Position = 0; + using (var reader = new StreamReader(new UnclosableStream(_stream))) { + using (var writer = new StreamWriter(stream)) { + writer.Write(reader.ReadToEnd()); } } } @@ -153,6 +153,7 @@ namespace ICSharpCode.WpfDesign.AddIn void OnUndoStackChanged(object sender, EventArgs e) { + wasChangedInDesigner = true; this.PrimaryFile.MakeDirty(); } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SelectedElementRectangleExtension.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SelectedElementRectangleExtension.cs index aedc0809d3..8d6a4643b5 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SelectedElementRectangleExtension.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SelectedElementRectangleExtension.cs @@ -23,18 +23,18 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions public SelectedElementRectangleExtension() { Rectangle selectionRect = new Rectangle(); - selectionRect.SnapsToDevicePixels = true; - selectionRect.Stroke = new SolidColorBrush(Color.FromRgb(0x47, 0x47, 0x47)); - selectionRect.StrokeThickness = 1.5; - selectionRect.IsHitTestVisible = false; + selectionRect.SnapsToDevicePixels = true; + selectionRect.Stroke = new SolidColorBrush(Color.FromRgb(0x47, 0x47, 0x47)); + selectionRect.StrokeThickness = 1.5; + selectionRect.IsHitTestVisible = false; - RelativePlacement placement = new RelativePlacement(HorizontalAlignment.Stretch, VerticalAlignment.Stretch); - placement.XOffset = -1; - placement.YOffset = -1; - placement.WidthOffset = 2; - placement.HeightOffset = 2; + RelativePlacement placement = new RelativePlacement(HorizontalAlignment.Stretch, VerticalAlignment.Stretch); + placement.XOffset = -1; + placement.YOffset = -1; + placement.WidthOffset = 2; + placement.HeightOffset = 2; - this.AddAdorners(placement, selectionRect); + this.AddAdorners(placement, selectionRect); } } } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SizeDisplayExtension.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SizeDisplayExtension.cs index 25c59064a0..4ebe80bfb7 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SizeDisplayExtension.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SizeDisplayExtension.cs @@ -17,40 +17,40 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions /// /// Display Height/Width on the primary selection /// - [ExtensionFor(typeof(UIElement))] - class SizeDisplayExtension : PrimarySelectionAdornerProvider - { - HeightDisplay _heightDisplay; - WidthDisplay _widthDisplay; - - public HeightDisplay HeightDisplay{ - get { return _heightDisplay; } - } - - public WidthDisplay WidthDisplay{ - get { return _widthDisplay; } - } - - protected override void OnInitialized() - { - base.OnInitialized(); - if (this.ExtendedItem != null) - { - RelativePlacement placementHeight = new RelativePlacement(HorizontalAlignment.Right, VerticalAlignment.Stretch); - placementHeight.XOffset = 10; - _heightDisplay = new HeightDisplay(); - _heightDisplay.DataContext = this.ExtendedItem.Component; + [ExtensionFor(typeof(UIElement))] + class SizeDisplayExtension : PrimarySelectionAdornerProvider + { + HeightDisplay _heightDisplay; + WidthDisplay _widthDisplay; + + public HeightDisplay HeightDisplay{ + get { return _heightDisplay; } + } + + public WidthDisplay WidthDisplay{ + get { return _widthDisplay; } + } + + protected override void OnInitialized() + { + base.OnInitialized(); + if (this.ExtendedItem != null) + { + RelativePlacement placementHeight = new RelativePlacement(HorizontalAlignment.Right, VerticalAlignment.Stretch); + placementHeight.XOffset = 10; + _heightDisplay = new HeightDisplay(); + _heightDisplay.DataContext = this.ExtendedItem.Component; - RelativePlacement placementWidth = new RelativePlacement(HorizontalAlignment.Stretch, VerticalAlignment.Bottom); - placementWidth.YOffset = 10; - _widthDisplay = new WidthDisplay(); - _widthDisplay.DataContext = this.ExtendedItem.Component; + RelativePlacement placementWidth = new RelativePlacement(HorizontalAlignment.Stretch, VerticalAlignment.Bottom); + placementWidth.YOffset = 10; + _widthDisplay = new WidthDisplay(); + _widthDisplay.DataContext = this.ExtendedItem.Component; - this.AddAdorners(placementHeight, _heightDisplay); - this.AddAdorners(placementWidth, _widthDisplay); - _heightDisplay.Visibility=Visibility.Hidden; - _widthDisplay.Visibility=Visibility.Hidden; - } - } - } + this.AddAdorners(placementHeight, _heightDisplay); + this.AddAdorners(placementWidth, _widthDisplay); + _heightDisplay.Visibility=Visibility.Hidden; + _widthDisplay.Visibility=Visibility.Hidden; + } + } + } } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/StackPanelPlacementSupport.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/StackPanelPlacementSupport.cs index acd92c6e0a..88f5094d0d 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/StackPanelPlacementSupport.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/StackPanelPlacementSupport.cs @@ -18,156 +18,157 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions /// Provides for . /// [ExtensionFor(typeof (StackPanel), OverrideExtension = typeof (DefaultPlacementBehavior))] - public class StackPanelPlacementSupport : DefaultPlacementBehavior - { - private StackPanel _stackPanel; - private AdornerPanel _adornerPanel; - private Rectangle _rectangle = new Rectangle(); // Draws a rectangle to indicate the position of insertion. - private readonly List _rects = new List(); // Contains the Rect of all the children of StackPanel. - - - private bool _isItemGettingResized; // Indicates whether any children is getting resized. - private int _indexToInsert; // Postion where to insert the element. + public class StackPanelPlacementSupport : DefaultPlacementBehavior + { + private StackPanel _stackPanel; + private AdornerPanel _adornerPanel; + private Rectangle _rectangle = new Rectangle(); // Draws a rectangle to indicate the position of insertion. + private readonly List _rects = new List(); // Contains the Rect of all the children of StackPanel. + + + private bool _isItemGettingResized; // Indicates whether any children is getting resized. + private int _indexToInsert; // Postion where to insert the element. - protected override void OnInitialized() - { - base.OnInitialized(); - _stackPanel = this.ExtendedItem.View as StackPanel; - var children = this.ExtendedItem.ContentProperty.CollectionElements; - foreach (var child in children) { - Point p = child.View.TranslatePoint(new Point(0, 0), this.ExtendedItem.View); - _rects.Add(new Rect(p, child.View.RenderSize)); - } - } + protected override void OnInitialized() + { + base.OnInitialized(); + _stackPanel = this.ExtendedItem.View as StackPanel; + var children = this.ExtendedItem.ContentProperty.CollectionElements; + foreach (var child in children) { + Point p = child.View.TranslatePoint(new Point(0, 0), this.ExtendedItem.View); + _rects.Add(new Rect(p, child.View.RenderSize)); + } + } - public override void BeginPlacement(PlacementOperation operation) - { - base.BeginPlacement(operation); - if (_rects.Count > 0) - _rects.Clear(); - - /* Add Rect of all children to _rects */ - var children = this.ExtendedItem.ContentProperty.CollectionElements; - foreach (var child in children) { - Point p = child.View.TranslatePoint(new Point(0, 0), this.ExtendedItem.View); - _rects.Add(new Rect(p, child.View.RenderSize)); - } - if (_adornerPanel != null && this.ExtendedItem.Services.DesignPanel.Adorners.Contains(_adornerPanel)) - this.ExtendedItem.Services.DesignPanel.Adorners.Remove(_adornerPanel); - - /* Place the Rectangle */ - _adornerPanel = new AdornerPanel(); - _rectangle = new Rectangle(); - _adornerPanel.SetAdornedElement(this.ExtendedItem.View, this.ExtendedItem); - _adornerPanel.Children.Add(_rectangle); - this.ExtendedItem.Services.DesignPanel.Adorners.Add(_adornerPanel); - } + public override void BeginPlacement(PlacementOperation operation) + { + base.BeginPlacement(operation); + if (_rects.Count > 0) + _rects.Clear(); + + /* Add Rect of all children to _rects */ + var children = this.ExtendedItem.ContentProperty.CollectionElements; + foreach (var child in children) { + Point p = child.View.TranslatePoint(new Point(0, 0), this.ExtendedItem.View); + _rects.Add(new Rect(p, child.View.RenderSize)); + } + if (_adornerPanel != null && this.ExtendedItem.Services.DesignPanel.Adorners.Contains(_adornerPanel)) + this.ExtendedItem.Services.DesignPanel.Adorners.Remove(_adornerPanel); + + /* Place the Rectangle */ + _adornerPanel = new AdornerPanel(); + _rectangle = new Rectangle(); + _adornerPanel.SetAdornedElement(this.ExtendedItem.View, this.ExtendedItem); + _adornerPanel.Children.Add(_rectangle); + this.ExtendedItem.Services.DesignPanel.Adorners.Add(_adornerPanel); + } - public override void EndPlacement(PlacementOperation operation) - { - base.EndPlacement(operation); - if (_adornerPanel != null && this.ExtendedItem.Services.DesignPanel.Adorners.Contains(_adornerPanel)) - this.ExtendedItem.Services.DesignPanel.Adorners.Remove(_adornerPanel); - } + public override void EndPlacement(PlacementOperation operation) + { + base.EndPlacement(operation); + if (_adornerPanel != null && this.ExtendedItem.Services.DesignPanel.Adorners.Contains(_adornerPanel)) + this.ExtendedItem.Services.DesignPanel.Adorners.Remove(_adornerPanel); + } - public override void EnterContainer(PlacementOperation operation) - { - base.EnterContainer(operation); - foreach (var info in operation.PlacedItems) { - info.Item.Properties[FrameworkElement.MarginProperty].Reset(); - info.Item.Properties[FrameworkElement.HorizontalAlignmentProperty].Reset(); - info.Item.Properties[FrameworkElement.VerticalAlignmentProperty].Reset(); - } - _rectangle.Visibility = Visibility.Visible; - } + public override void EnterContainer(PlacementOperation operation) + { + base.EnterContainer(operation); + foreach (var info in operation.PlacedItems) { + info.Item.Properties[FrameworkElement.MarginProperty].Reset(); + info.Item.Properties[FrameworkElement.HorizontalAlignmentProperty].Reset(); + info.Item.Properties[FrameworkElement.VerticalAlignmentProperty].Reset(); + } + _rectangle.Visibility = Visibility.Visible; + } - public override void LeaveContainer(PlacementOperation operation) - { - base.LeaveContainer(operation); - /* Hide the rectangle in case switching to the other container - * otherwise it will show up intersecting with the container */ - _rectangle.Visibility = Visibility.Hidden; - } + public override void LeaveContainer(PlacementOperation operation) + { + base.LeaveContainer(operation); + /* Hide the rectangle in case switching to the other container + * otherwise it will show up intersecting with the container */ + _rectangle.Visibility = Visibility.Hidden; + } - public override void SetPosition(PlacementInformation info) - { - base.SetPosition(info); + public override void SetPosition(PlacementInformation info) + { + base.SetPosition(info); - var resizeExtensions = info.Item.Extensions.OfType(); - if (resizeExtensions != null && resizeExtensions.Count() != 0) { - var resizeExtension = resizeExtensions.First(); - _isItemGettingResized = resizeExtension.IsResizing; - } + var resizeExtensions = info.Item.Extensions.OfType(); + if (resizeExtensions != null && resizeExtensions.Count() != 0) { + var resizeExtension = resizeExtensions.First(); + _isItemGettingResized = resizeExtension.IsResizing; + } - if (_stackPanel != null && !_isItemGettingResized) { - if (_stackPanel.Orientation == Orientation.Vertical) { - var offset = FindHorizontalRectanglePlacementOffset(info.Bounds); - DrawHorizontalRectangle(offset); - } else { - var offset = FindVerticalRectanglePlacementOffset(info.Bounds); - DrawVerticalRectangle(offset); - } + if (_stackPanel != null && !_isItemGettingResized) { + if (_stackPanel.Orientation == Orientation.Vertical) { + var offset = FindHorizontalRectanglePlacementOffset(info.Bounds); + DrawHorizontalRectangle(offset); + } else { + var offset = FindVerticalRectanglePlacementOffset(info.Bounds); + DrawVerticalRectangle(offset); + } - ChangePostionTo(info.Item.View, _indexToInsert); - } - } + ChangePositionTo(info.Item, _indexToInsert); + } + } - private void ChangePostionTo(UIElement element, int index) - { - int elementIndex = 0; - if (_stackPanel.Children.Contains(element)) - elementIndex = _stackPanel.Children.IndexOf(element); - if (index > elementIndex) - index--; - _stackPanel.Children.Remove(element); - _stackPanel.Children.Insert(index, element); - } - - private double FindHorizontalRectanglePlacementOffset(Rect rect) - { - _rects.Sort((r1, r2) => r1.Top.CompareTo(r2.Top)); - var itemCenter = (rect.Top + rect.Bottom)/2; - for (int i = 0; i < _rects.Count; i++) { - var rectCenter = (_rects[i].Top + _rects[i].Bottom)/2; - if (rectCenter >= itemCenter) { - _indexToInsert = i; - return _rects[i].Top; - } - } - _indexToInsert = _rects.Count; - return _rects.Count > 0 ? _rects.Last().Bottom : 0; - } - - private double FindVerticalRectanglePlacementOffset(Rect rect) - { - _rects.Sort((r1, r2) => r1.Left.CompareTo(r2.Left)); - var itemCenter = (rect.Left + rect.Right)/2; - for (int i = 0; i < _rects.Count; i++) { - var rectCenter = (_rects[i].Left + _rects[i].Top)/2; - if (rectCenter >= itemCenter) { - _indexToInsert = i; - return _rects[i].Left; - } - } - _indexToInsert = _rects.Count; - return _rects.Count > 0 ? _rects.Last().Right : 0; - } - - private void DrawHorizontalRectangle(double offset) - { - _rectangle.Height = 2; - _rectangle.Fill = Brushes.Black; - var placement = new RelativePlacement(HorizontalAlignment.Stretch, VerticalAlignment.Top) {YOffset = offset}; - AdornerPanel.SetPlacement(_rectangle, placement); - } - - private void DrawVerticalRectangle(double offset) - { - _rectangle.Width = 2; - _rectangle.Fill = Brushes.Black; - var placement = new RelativePlacement(HorizontalAlignment.Left, VerticalAlignment.Stretch) {XOffset = offset}; - AdornerPanel.SetPlacement(_rectangle, placement); - } - } + private void ChangePositionTo(DesignItem element, int index) + { + if (this.ExtendedItem.ContentProperty == null || !this.ExtendedItem.ContentProperty.IsCollection) + return; + var elements = this.ExtendedItem.ContentProperty.CollectionElements; + int elementIndex = elements.IndexOf(element); + if (elementIndex >= 0 && index > elementIndex) + index--; + elements.Remove(element); + elements.Insert(index, element); + } + + private double FindHorizontalRectanglePlacementOffset(Rect rect) + { + _rects.Sort((r1, r2) => r1.Top.CompareTo(r2.Top)); + var itemCenter = (rect.Top + rect.Bottom)/2; + for (int i = 0; i < _rects.Count; i++) { + var rectCenter = (_rects[i].Top + _rects[i].Bottom)/2; + if (rectCenter >= itemCenter) { + _indexToInsert = i; + return _rects[i].Top; + } + } + _indexToInsert = _rects.Count; + return _rects.Count > 0 ? _rects.Last().Bottom : 0; + } + + private double FindVerticalRectanglePlacementOffset(Rect rect) + { + _rects.Sort((r1, r2) => r1.Left.CompareTo(r2.Left)); + var itemCenter = (rect.Left + rect.Right)/2; + for (int i = 0; i < _rects.Count; i++) { + var rectCenter = (_rects[i].Left + _rects[i].Top)/2; + if (rectCenter >= itemCenter) { + _indexToInsert = i; + return _rects[i].Left; + } + } + _indexToInsert = _rects.Count; + return _rects.Count > 0 ? _rects.Last().Right : 0; + } + + private void DrawHorizontalRectangle(double offset) + { + _rectangle.Height = 2; + _rectangle.Fill = Brushes.Black; + var placement = new RelativePlacement(HorizontalAlignment.Stretch, VerticalAlignment.Top) {YOffset = offset}; + AdornerPanel.SetPlacement(_rectangle, placement); + } + + private void DrawVerticalRectangle(double offset) + { + _rectangle.Width = 2; + _rectangle.Fill = Brushes.Black; + var placement = new RelativePlacement(HorizontalAlignment.Left, VerticalAlignment.Stretch) {XOffset = offset}; + AdornerPanel.SetPlacement(_rectangle, placement); + } + } } diff --git a/src/AddIns/VersionControl/SubversionAddIn/Src/Gui/ProjectBrowserVisitor/OverlayIconManager.cs b/src/AddIns/VersionControl/SubversionAddIn/Src/Gui/ProjectBrowserVisitor/OverlayIconManager.cs index 82fc0b3e7f..8aa35d033e 100644 --- a/src/AddIns/VersionControl/SubversionAddIn/Src/Gui/ProjectBrowserVisitor/OverlayIconManager.cs +++ b/src/AddIns/VersionControl/SubversionAddIn/Src/Gui/ProjectBrowserVisitor/OverlayIconManager.cs @@ -192,7 +192,12 @@ namespace ICSharpCode.Svn } } - return client.SingleStatus(fileName).TextStatus; + try { + return client.SingleStatus(fileName).TextStatus; + } catch (SvnClientException ex) { + LoggingService.Warn(ex); + return StatusKind.None; + } } } diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/TextView.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/TextView.cs index 50db99f9df..693ada3e09 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/TextView.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/TextView.cs @@ -943,7 +943,8 @@ namespace ICSharpCode.AvalonEdit.Rendering // number of pixels clipped from the first visual line(s) clippedPixelsOnTop = scrollOffset.Y - heightTree.GetVisualPosition(firstLineInView); - Debug.Assert(clippedPixelsOnTop >= 0); + // clippedPixelsOnTop should be >= 0, except for floating point inaccurracy. + Debug.Assert(clippedPixelsOnTop >= -ExtensionMethods.Epsilon); newVisualLines = new List(); diff --git a/src/Libraries/ICSharpCode.Decompiler/Ast/AstBuilder.cs b/src/Libraries/ICSharpCode.Decompiler/Ast/AstBuilder.cs index fc288d80fd..a95ddbaf2d 100644 --- a/src/Libraries/ICSharpCode.Decompiler/Ast/AstBuilder.cs +++ b/src/Libraries/ICSharpCode.Decompiler/Ast/AstBuilder.cs @@ -81,6 +81,8 @@ namespace ICSharpCode.Decompiler.Ast return true; if (settings.YieldReturn && YieldReturnDecompiler.IsCompilerGeneratorEnumerator(type)) return true; + if (settings.AsyncAwait && AsyncDecompiler.IsCompilerGeneratedStateMachine(type)) + return true; } else if (type.IsCompilerGenerated()) { if (type.Name.StartsWith("", StringComparison.Ordinal)) return true; @@ -770,6 +772,10 @@ namespace ICSharpCode.Decompiler.Ast SetNewModifier(astMethod); } astMethod.Body = CreateMethodBody(methodDef, astMethod.Parameters); + if (context.CurrentMethodIsAsync) { + astMethod.Modifiers |= Modifiers.Async; + context.CurrentMethodIsAsync = false; + } } ConvertAttributes(astMethod, methodDef); if (methodDef.HasCustomAttributes && astMethod.Parameters.Count > 0) { @@ -1342,6 +1348,7 @@ namespace ICSharpCode.Decompiler.Ast static void ConvertCustomAttributes(AstNode attributedNode, ICustomAttributeProvider customAttributeProvider, string attributeTarget = null) { + EntityDeclaration entityDecl = attributedNode as EntityDeclaration; if (customAttributeProvider.HasCustomAttributes) { var attributes = new List(); foreach (var customAttribute in customAttributeProvider.CustomAttributes.OrderBy(a => a.AttributeType.FullName)) { @@ -1353,6 +1360,15 @@ namespace ICSharpCode.Decompiler.Ast // don't show the ParamArrayAttribute (it's converted to the 'params' modifier) continue; } + // if the method is async, remove [DebuggerStepThrough] and [Async + if (entityDecl != null && entityDecl.HasModifier(Modifiers.Async)) { + if (customAttribute.AttributeType.Name == "DebuggerStepThroughAttribute" && customAttribute.AttributeType.Namespace == "System.Diagnostics") { + continue; + } + if (customAttribute.AttributeType.Name == "AsyncStateMachineAttribute" && customAttribute.AttributeType.Namespace == "System.Runtime.CompilerServices") { + continue; + } + } var attribute = new ICSharpCode.NRefactory.CSharp.Attribute(); attribute.AddAnnotation(customAttribute); diff --git a/src/Libraries/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs b/src/Libraries/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs index 5de5b0ba5a..8ad9047c1c 100644 --- a/src/Libraries/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs +++ b/src/Libraries/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs @@ -58,6 +58,7 @@ namespace ICSharpCode.Decompiler.Ast MethodDefinition oldCurrentMethod = context.CurrentMethod; Debug.Assert(oldCurrentMethod == null || oldCurrentMethod == methodDef); context.CurrentMethod = methodDef; + context.CurrentMethodIsAsync = false; try { AstMethodBodyBuilder builder = new AstMethodBodyBuilder(); builder.methodDef = methodDef; @@ -847,8 +848,11 @@ namespace ICSharpCode.Decompiler.Ast case ILCode.ExpressionTreeParameterDeclarations: args[args.Count - 1].AddAnnotation(new ParameterDeclarationAnnotation(byteCode)); return args[args.Count - 1]; + case ILCode.Await: + return new UnaryOperatorExpression(UnaryOperatorType.Await, arg1); case ILCode.NullableOf: - case ILCode.ValueOf: return arg1; + case ILCode.ValueOf: + return arg1; default: throw new Exception("Unknown OpCode: " + byteCode.Code); } diff --git a/src/Libraries/ICSharpCode.Decompiler/Ast/DecompilerContext.cs b/src/Libraries/ICSharpCode.Decompiler/Ast/DecompilerContext.cs index 4a3f277827..624b1b33fd 100644 --- a/src/Libraries/ICSharpCode.Decompiler/Ast/DecompilerContext.cs +++ b/src/Libraries/ICSharpCode.Decompiler/Ast/DecompilerContext.cs @@ -33,6 +33,7 @@ namespace ICSharpCode.Decompiler public TypeDefinition CurrentType; public MethodDefinition CurrentMethod; public DecompilerSettings Settings = new DecompilerSettings(); + public bool CurrentMethodIsAsync; // public ITypeResolveContext TypeResolveContext; // public IProjectContent ProjectContent; diff --git a/src/Libraries/ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs b/src/Libraries/ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs index 85fef513ee..b17e24656f 100644 --- a/src/Libraries/ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs +++ b/src/Libraries/ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs @@ -114,6 +114,9 @@ namespace ICSharpCode.Decompiler.Ast object GetCurrentLocalDefinition() { AstNode node = nodeStack.Peek(); + if (node is Identifier && node.Parent != null) + node = node.Parent; + var parameterDef = node.Annotation(); if (parameterDef != null) return parameterDef; @@ -126,14 +129,11 @@ namespace ICSharpCode.Decompiler.Ast //if (variable.OriginalVariable != null) // return variable.OriginalVariable; return variable; - } else { - } } var label = node as LabelStatement; - if (label != null) - { + if (label != null) { var method = nodeStack.Select(nd => nd.Annotation()).FirstOrDefault(mr => mr != null); if (method != null) return method.ToString() + label.Label; diff --git a/src/Libraries/ICSharpCode.Decompiler/Ast/Transforms/DelegateConstruction.cs b/src/Libraries/ICSharpCode.Decompiler/Ast/Transforms/DelegateConstruction.cs index 9264000f08..9c5aa97f6e 100644 --- a/src/Libraries/ICSharpCode.Decompiler/Ast/Transforms/DelegateConstruction.cs +++ b/src/Libraries/ICSharpCode.Decompiler/Ast/Transforms/DelegateConstruction.cs @@ -151,6 +151,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms DecompilerContext subContext = context.Clone(); subContext.CurrentMethod = method; + subContext.CurrentMethodIsAsync = false; subContext.ReservedVariableNames.AddRange(currentlyUsedVariableNames); BlockStatement body = AstMethodBodyBuilder.CreateMethodBody(method, subContext, ame.Parameters); TransformationPipeline.RunTransformationsUntil(body, v => v is DelegateConstruction, subContext); diff --git a/src/Libraries/ICSharpCode.Decompiler/DecompilerSettings.cs b/src/Libraries/ICSharpCode.Decompiler/DecompilerSettings.cs index 435124491c..f78194a6f9 100644 --- a/src/Libraries/ICSharpCode.Decompiler/DecompilerSettings.cs +++ b/src/Libraries/ICSharpCode.Decompiler/DecompilerSettings.cs @@ -72,6 +72,21 @@ namespace ICSharpCode.Decompiler } } + bool asyncAwait = true; + + /// + /// Decompile async methods. + /// + public bool AsyncAwait { + get { return asyncAwait; } + set { + if (asyncAwait != value) { + asyncAwait = value; + OnPropertyChanged("AsyncAwait"); + } + } + } + bool automaticProperties = true; /// diff --git a/src/Libraries/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj b/src/Libraries/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj index 846edc60a2..60bead91a6 100644 --- a/src/Libraries/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj +++ b/src/Libraries/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj @@ -101,6 +101,7 @@ + @@ -114,6 +115,8 @@ + + diff --git a/src/Libraries/ICSharpCode.Decompiler/ILAst/AsyncDecompiler.cs b/src/Libraries/ICSharpCode.Decompiler/ILAst/AsyncDecompiler.cs new file mode 100644 index 0000000000..4535c0f82a --- /dev/null +++ b/src/Libraries/ICSharpCode.Decompiler/ILAst/AsyncDecompiler.cs @@ -0,0 +1,653 @@ +// Copyright (c) 2012 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using Mono.Cecil; +using Mono.Cecil.Cil; + +namespace ICSharpCode.Decompiler.ILAst +{ + /// + /// Decompiler step for C# 5 async/await. + /// + class AsyncDecompiler + { + public static bool IsCompilerGeneratedStateMachine(TypeDefinition type) + { + if (!(type.DeclaringType != null && type.IsCompilerGenerated())) + return false; + foreach (TypeReference i in type.Interfaces) { + if (i.Namespace == "System.Runtime.CompilerServices" && i.Name == "IAsyncStateMachine") + return true; + } + return false; + } + + enum AsyncMethodType + { + Void, + Task, + TaskOfT + } + + DecompilerContext context; + + // These fields are set by MatchTaskCreationPattern() + AsyncMethodType methodType; + int initialState; + TypeDefinition stateMachineStruct; + MethodDefinition moveNextMethod; + FieldDefinition builderField; + FieldDefinition stateField; + Dictionary fieldToParameterMap = new Dictionary(); + + // These fields are set by AnalyzeMoveNext() + int finalState = -2; + ILTryCatchBlock mainTryCatch; + ILLabel setResultAndExitLabel; + ILLabel exitLabel; + ILExpression resultExpr; + + #region RunStep1() method + public static void RunStep1(DecompilerContext context, ILBlock method) + { + if (!context.Settings.AsyncAwait) + return; // abort if async decompilation is disabled + var yrd = new AsyncDecompiler(); + yrd.context = context; + if (!yrd.MatchTaskCreationPattern(method)) + return; + #if DEBUG + if (Debugger.IsAttached) { + yrd.Run(); + } else { + #endif + try { + yrd.Run(); + } catch (SymbolicAnalysisFailedException) { + return; + } + #if DEBUG + } + #endif + context.CurrentMethodIsAsync = true; + + method.Body.Clear(); + method.EntryGoto = null; + method.Body.AddRange(yrd.newTopLevelBody); + ILAstOptimizer.RemoveRedundantCode(method); + } + + void Run() + { + AnalyzeMoveNext(); + ValidateCatchBlock(mainTryCatch.CatchBlocks[0]); + AnalyzeStateMachine(mainTryCatch.TryBlock); + // AnalyzeStateMachine invokes ConvertBody + MarkGeneratedVariables(); + YieldReturnDecompiler.TranslateFieldsToLocalAccess(newTopLevelBody, fieldToParameterMap); + } + #endregion + + #region MatchTaskCreationPattern + bool MatchTaskCreationPattern(ILBlock method) + { + if (method.Body.Count < 5) + return false; + // Check the second-to-last instruction (the start call) first, as we can get the most information from that + MethodReference startMethod; + ILExpression loadStartTarget, loadStartArgument; + // call(AsyncTaskMethodBuilder::Start, ldloca(builder), ldloca(stateMachine)) + if (!method.Body[method.Body.Count - 2].Match(ILCode.Call, out startMethod, out loadStartTarget, out loadStartArgument)) + return false; + if (startMethod.Name != "Start" || startMethod.DeclaringType == null || startMethod.DeclaringType.Namespace != "System.Runtime.CompilerServices") + return false; + switch (startMethod.DeclaringType.Name) { + case "AsyncTaskMethodBuilder`1": + methodType = AsyncMethodType.TaskOfT; + break; + case "AsyncTaskMethodBuilder": + methodType = AsyncMethodType.Task; + break; + case "AsyncVoidMethodBuilder": + methodType = AsyncMethodType.Void; + break; + default: + return false; + } + ILVariable stateMachineVar, builderVar; + if (!loadStartTarget.Match(ILCode.Ldloca, out builderVar)) + return false; + if (!loadStartArgument.Match(ILCode.Ldloca, out stateMachineVar)) + return false; + + stateMachineStruct = stateMachineVar.Type.ResolveWithinSameModule(); + if (stateMachineStruct == null || !stateMachineStruct.IsValueType) + return false; + moveNextMethod = stateMachineStruct.Methods.FirstOrDefault(f => f.Name == "MoveNext"); + if (moveNextMethod == null) + return false; + + // Check third-to-last instruction (copy of builder): + // stloc(builder, ldfld(StateMachine::<>t__builder, ldloca(stateMachine))) + ILExpression loadBuilderExpr; + if (!method.Body[method.Body.Count - 3].MatchStloc(builderVar, out loadBuilderExpr)) + return false; + FieldReference builderFieldRef; + ILExpression loadStateMachineForBuilderExpr; + if (!loadBuilderExpr.Match(ILCode.Ldfld, out builderFieldRef, out loadStateMachineForBuilderExpr)) + return false; + if (!loadStateMachineForBuilderExpr.MatchLdloca(stateMachineVar)) + return false; + builderField = builderFieldRef.ResolveWithinSameModule(); + if (builderField == null) + return false; + + // Check the last instruction (ret) + if (methodType == AsyncMethodType.Void) { + if (!method.Body[method.Body.Count - 1].Match(ILCode.Ret)) + return false; + } else { + // ret(call(AsyncTaskMethodBuilder::get_Task, ldflda(StateMachine::<>t__builder, ldloca(stateMachine)))) + ILExpression returnValue; + if (!method.Body[method.Body.Count - 1].Match(ILCode.Ret, out returnValue)) + return false; + MethodReference getTaskMethod; + ILExpression builderExpr; + if (!returnValue.Match(ILCode.Call, out getTaskMethod, out builderExpr)) + return false; + ILExpression loadStateMachineForBuilderExpr2; + FieldReference builderField2; + if (!builderExpr.Match(ILCode.Ldflda, out builderField2, out loadStateMachineForBuilderExpr2)) + return false; + if (builderField2.ResolveWithinSameModule() != builderField || !loadStateMachineForBuilderExpr2.MatchLdloca(stateMachineVar)) + return false; + } + + // Check the last field assignment - this should be the state field + ILExpression initialStateExpr; + if (!MatchStFld(method.Body[method.Body.Count - 4], stateMachineVar, out stateField, out initialStateExpr)) + return false; + if (!initialStateExpr.Match(ILCode.Ldc_I4, out initialState)) + return false; + if (initialState != -1) + return false; + + // Check the second-to-last field assignment - this should be the builder field + FieldDefinition builderField3; + ILExpression builderInitialization; + if (!MatchStFld(method.Body[method.Body.Count - 5], stateMachineVar, out builderField3, out builderInitialization)) + return false; + MethodReference createMethodRef; + if (builderField3 != builderField || !builderInitialization.Match(ILCode.Call, out createMethodRef)) + return false; + if (createMethodRef.Name != "Create") + return false; + + for (int i = 0; i < method.Body.Count - 5; i++) { + FieldDefinition field; + ILExpression fieldInit; + if (!MatchStFld(method.Body[i], stateMachineVar, out field, out fieldInit)) + return false; + ILVariable v; + if (!fieldInit.Match(ILCode.Ldloc, out v)) + return false; + if (!v.IsParameter) + return false; + fieldToParameterMap[field] = v; + } + + return true; + } + + static bool MatchStFld(ILNode stfld, ILVariable stateMachineVar, out FieldDefinition field, out ILExpression expr) + { + field = null; + FieldReference fieldRef; + ILExpression ldloca; + if (!stfld.Match(ILCode.Stfld, out fieldRef, out ldloca, out expr)) + return false; + field = fieldRef.ResolveWithinSameModule(); + return field != null && ldloca.MatchLdloca(stateMachineVar); + } + #endregion + + #region Analyze MoveNext + void AnalyzeMoveNext() + { + ILBlock ilMethod = CreateILAst(moveNextMethod); + + if (ilMethod.Body.Count != 6) + throw new SymbolicAnalysisFailedException(); + + mainTryCatch = ilMethod.Body[0] as ILTryCatchBlock; + if (mainTryCatch == null || mainTryCatch.CatchBlocks.Count != 1) + throw new SymbolicAnalysisFailedException(); + if (mainTryCatch.FaultBlock != null || mainTryCatch.FinallyBlock != null) + throw new SymbolicAnalysisFailedException(); + + setResultAndExitLabel = ilMethod.Body[1] as ILLabel; + if (setResultAndExitLabel == null) + throw new SymbolicAnalysisFailedException(); + + if (!MatchStateAssignment(ilMethod.Body[2], out finalState)) + throw new SymbolicAnalysisFailedException(); + + // call(AsyncTaskMethodBuilder`1::SetResult, ldflda(StateMachine::<>t__builder, ldloc(this)), ldloc(<>t__result)) + MethodReference setResultMethod; + ILExpression builderExpr; + if (methodType == AsyncMethodType.TaskOfT) { + if (!ilMethod.Body[3].Match(ILCode.Call, out setResultMethod, out builderExpr, out resultExpr)) + throw new SymbolicAnalysisFailedException(); + } else { + if (!ilMethod.Body[3].Match(ILCode.Call, out setResultMethod, out builderExpr)) + throw new SymbolicAnalysisFailedException(); + } + if (!(setResultMethod.Name == "SetResult" && IsBuilderFieldOnThis(builderExpr))) + throw new SymbolicAnalysisFailedException(); + + exitLabel = ilMethod.Body[4] as ILLabel; + if (exitLabel == null) + throw new SymbolicAnalysisFailedException(); + } + + /// + /// Creates ILAst for the specified method, optimized up to before the 'YieldReturn' step. + /// + ILBlock CreateILAst(MethodDefinition method) + { + if (method == null || !method.HasBody) + throw new SymbolicAnalysisFailedException(); + + ILBlock ilMethod = new ILBlock(); + ILAstBuilder astBuilder = new ILAstBuilder(); + ilMethod.Body = astBuilder.Build(method, true, context); + ILAstOptimizer optimizer = new ILAstOptimizer(); + optimizer.Optimize(context, ilMethod, ILAstOptimizationStep.YieldReturn); + return ilMethod; + } + + void ValidateCatchBlock(ILTryCatchBlock.CatchBlock catchBlock) + { + if (catchBlock.ExceptionType == null || catchBlock.ExceptionType.Name != "Exception") + throw new SymbolicAnalysisFailedException(); + if (catchBlock.Body.Count != 3) + throw new SymbolicAnalysisFailedException(); + int stateID; + if (!(MatchStateAssignment(catchBlock.Body[0], out stateID) && stateID == finalState)) + throw new SymbolicAnalysisFailedException(); + MethodReference setExceptionMethod; + ILExpression builderExpr, exceptionExpr; + if (!catchBlock.Body[1].Match(ILCode.Call, out setExceptionMethod, out builderExpr, out exceptionExpr)) + throw new SymbolicAnalysisFailedException(); + if (!(setExceptionMethod.Name == "SetException" && IsBuilderFieldOnThis(builderExpr) && exceptionExpr.MatchLdloc(catchBlock.ExceptionVariable))) + throw new SymbolicAnalysisFailedException(); + + ILLabel label; + if (!(catchBlock.Body[2].Match(ILCode.Leave, out label) && label == exitLabel)) + throw new SymbolicAnalysisFailedException(); + } + + bool IsBuilderFieldOnThis(ILExpression builderExpr) + { + // ldflda(StateMachine::<>t__builder, ldloc(this)) + FieldReference fieldRef; + ILExpression target; + return builderExpr.Match(ILCode.Ldflda, out fieldRef, out target) + && fieldRef.ResolveWithinSameModule() == builderField + && target.MatchThis(); + } + + bool MatchStateAssignment(ILNode stfld, out int stateID) + { + // stfld(StateMachine::<>1__state, ldloc(this), ldc.i4(-2)) + stateID = 0; + FieldReference fieldRef; + ILExpression target, val; + if (stfld.Match(ILCode.Stfld, out fieldRef, out target, out val)) { + return fieldRef.ResolveWithinSameModule() == stateField + && target.MatchThis() + && val.Match(ILCode.Ldc_I4, out stateID); + } + return false; + } + #endregion + + #region AnalyzeStateMachine + ILVariable doFinallyBodies; + List newTopLevelBody; + + void AnalyzeStateMachine(ILBlock block) + { + var body = block.Body; + if (body.Count == 0) + throw new SymbolicAnalysisFailedException(); + if (DetectDoFinallyBodies(body)) { + body.RemoveAt(0); + if (body.Count == 0) + throw new SymbolicAnalysisFailedException(); + } + StateRangeAnalysis rangeAnalysis = new StateRangeAnalysis(body[0], StateRangeAnalysisMode.AsyncMoveNext, stateField); + int bodyLength = block.Body.Count; + int pos = rangeAnalysis.AssignStateRanges(body, bodyLength); + rangeAnalysis.EnsureLabelAtPos(body, ref pos, ref bodyLength); + + var labelStateRangeMapping = rangeAnalysis.CreateLabelRangeMapping(body, pos, bodyLength); + newTopLevelBody = ConvertBody(body, pos, bodyLength, labelStateRangeMapping); + newTopLevelBody.Insert(0, MakeGoTo(labelStateRangeMapping, initialState)); + newTopLevelBody.Add(setResultAndExitLabel); + if (methodType == AsyncMethodType.TaskOfT) { + newTopLevelBody.Add(new ILExpression(ILCode.Ret, null, resultExpr)); + } else { + newTopLevelBody.Add(new ILExpression(ILCode.Ret, null)); + } + } + + bool DetectDoFinallyBodies(List body) + { + ILVariable v; + ILExpression initExpr; + if (!body[0].Match(ILCode.Stloc, out v, out initExpr)) + return false; + int initialValue; + if (!(initExpr.Match(ILCode.Ldc_I4, out initialValue) && initialValue == 1)) + return false; + doFinallyBodies = v; + return true; + } + #endregion + + #region ConvertBody + ILExpression MakeGoTo(LabelRangeMapping mapping, int state) + { + foreach (var pair in mapping) { + if (pair.Value.Contains(state)) + return new ILExpression(ILCode.Br, pair.Key); + } + throw new SymbolicAnalysisFailedException(); + } + + List ConvertBody(List body, int startPos, int bodyLength, LabelRangeMapping mapping) + { + List newBody = new List(); + // Copy all instructions from the old body to newBody. + for (int pos = startPos; pos < bodyLength; pos++) { + ILTryCatchBlock tryCatchBlock = body[pos] as ILTryCatchBlock; + ILExpression expr = body[pos] as ILExpression; + if (expr != null && expr.Code == ILCode.Leave && expr.Operand == exitLabel) { + ILVariable awaiterVar; + FieldDefinition awaiterField; + int targetStateID; + HandleAwait(newBody, out awaiterVar, out awaiterField, out targetStateID); + MarkAsGeneratedVariable(awaiterVar); + newBody.Add(new ILExpression(ILCode.Await, null, new ILExpression(ILCode.Ldloca, awaiterVar))); + newBody.Add(MakeGoTo(mapping, targetStateID)); + } else if (tryCatchBlock != null) { + ILTryCatchBlock newTryCatchBlock = new ILTryCatchBlock(); + var tryBody = tryCatchBlock.TryBlock.Body; + if (tryBody.Count == 0) + throw new SymbolicAnalysisFailedException(); + StateRangeAnalysis rangeAnalysis = new StateRangeAnalysis(tryBody[0], StateRangeAnalysisMode.AsyncMoveNext, stateField); + int tryBodyLength = tryBody.Count; + int posInTryBody = rangeAnalysis.AssignStateRanges(tryBody, tryBodyLength); + rangeAnalysis.EnsureLabelAtPos(tryBody, ref posInTryBody, ref tryBodyLength); + + var mappingInTryBlock = rangeAnalysis.CreateLabelRangeMapping(tryBody, posInTryBody, tryBodyLength); + var newTryBody = ConvertBody(tryBody, posInTryBody, tryBodyLength, mappingInTryBlock); + newTryBody.Insert(0, MakeGoTo(mappingInTryBlock, initialState)); + + // If there's a label at the beginning of the state dispatcher, copy that + if (posInTryBody > 0 && tryBody.FirstOrDefault() is ILLabel) + newTryBody.Insert(0, tryBody.First()); + + newTryCatchBlock.TryBlock = new ILBlock(newTryBody); + newTryCatchBlock.CatchBlocks = new List(tryCatchBlock.CatchBlocks); + newTryCatchBlock.FaultBlock = tryCatchBlock.FaultBlock; + if (tryCatchBlock.FinallyBlock != null) + newTryCatchBlock.FinallyBlock = new ILBlock(ConvertFinally(tryCatchBlock.FinallyBlock.Body)); + + newBody.Add(newTryCatchBlock); + } else { + newBody.Add(body[pos]); + } + } + return newBody; + } + + List ConvertFinally(List body) + { + List newBody = new List(body); + ILLabel endFinallyLabel; + ILExpression ceqExpr; + if (newBody.Count > 0 && newBody[0].Match(ILCode.Brtrue, out endFinallyLabel, out ceqExpr)) { + ILExpression loadDoFinallyBodies, loadZero; + object unused; + if (ceqExpr.Match(ILCode.Ceq, out unused, out loadDoFinallyBodies, out loadZero)) { + int num; + if (loadDoFinallyBodies.MatchLdloc(doFinallyBodies) && loadZero.Match(ILCode.Ldc_I4, out num) && num == 0) { + newBody.RemoveAt(0); + } + } else if (ceqExpr.Match(ILCode.LogicNot, out loadDoFinallyBodies)) { + if (loadDoFinallyBodies.MatchLdloc(doFinallyBodies)) { + newBody.RemoveAt(0); + } + } + } + return newBody; + } + + void HandleAwait(List newBody, out ILVariable awaiterVar, out FieldDefinition awaiterField, out int targetStateID) + { + // Handle the instructions prior to the exit out of the method to detect what is being awaited. + // (analyses the last instructions in newBody and removes the analyzed instructions from newBody) + + if (doFinallyBodies != null) { + // stloc(<>t__doFinallyBodies, ldc.i4(0)) + ILExpression dfbInitExpr; + if (!newBody.LastOrDefault().MatchStloc(doFinallyBodies, out dfbInitExpr)) + throw new SymbolicAnalysisFailedException(); + int val; + if (!(dfbInitExpr.Match(ILCode.Ldc_I4, out val) && val == 0)) + throw new SymbolicAnalysisFailedException(); + newBody.RemoveAt(newBody.Count - 1); // remove doFinallyBodies assignment + } + + // call(AsyncTaskMethodBuilder::AwaitUnsafeOnCompleted, ldflda(StateMachine::<>t__builder, ldloc(this)), ldloca(CS$0$0001), ldloc(this)) + ILExpression callAwaitUnsafeOnCompleted = newBody.LastOrDefault() as ILExpression; + newBody.RemoveAt(newBody.Count - 1); // remove AwaitUnsafeOnCompleted call + if (callAwaitUnsafeOnCompleted == null || callAwaitUnsafeOnCompleted.Code != ILCode.Call) + throw new SymbolicAnalysisFailedException(); + if (((MethodReference)callAwaitUnsafeOnCompleted.Operand).Name != "AwaitUnsafeOnCompleted") + throw new SymbolicAnalysisFailedException(); + if (callAwaitUnsafeOnCompleted.Arguments.Count != 3) + throw new SymbolicAnalysisFailedException(); + if (!callAwaitUnsafeOnCompleted.Arguments[1].Match(ILCode.Ldloca, out awaiterVar)) + throw new SymbolicAnalysisFailedException(); + + // stfld(StateMachine::<>u__$awaiter6, ldloc(this), ldloc(CS$0$0001)) + FieldReference awaiterFieldRef; + ILExpression loadThis, loadAwaiterVar; + if (!newBody.LastOrDefault().Match(ILCode.Stfld, out awaiterFieldRef, out loadThis, out loadAwaiterVar)) + throw new SymbolicAnalysisFailedException(); + newBody.RemoveAt(newBody.Count - 1); // remove awaiter field assignment + awaiterField = awaiterFieldRef.ResolveWithinSameModule(); + if (!(awaiterField != null && loadThis.MatchThis() && loadAwaiterVar.MatchLdloc(awaiterVar))) + throw new SymbolicAnalysisFailedException(); + + // stfld(StateMachine::<>1__state, ldloc(this), ldc.i4(0)) + if (!MatchStateAssignment(newBody.LastOrDefault(), out targetStateID)) + throw new SymbolicAnalysisFailedException(); + newBody.RemoveAt(newBody.Count - 1); // remove awaiter field assignment + } + #endregion + + #region MarkGeneratedVariables + int smallestGeneratedVariableIndex = int.MaxValue; + + void MarkAsGeneratedVariable(ILVariable v) + { + if (v.OriginalVariable != null && v.OriginalVariable.Index >= 0) { + smallestGeneratedVariableIndex = Math.Min(smallestGeneratedVariableIndex, v.OriginalVariable.Index); + } + } + + void MarkGeneratedVariables() + { + var expressions = new ILBlock(newTopLevelBody).GetSelfAndChildrenRecursive(); + foreach (var v in expressions.Select(e => e.Operand).OfType()) { + if (v.OriginalVariable != null && v.OriginalVariable.Index >= smallestGeneratedVariableIndex) + v.IsGenerated = true; + } + } + #endregion + + #region RunStep2() method + public static void RunStep2(DecompilerContext context, ILBlock method) + { + if (context.CurrentMethodIsAsync) { + Step2(method.Body); + ILAstOptimizer.RemoveRedundantCode(method); + // Repeat the inlining/copy propagation optimization because the conversion of field access + // to local variables can open up additional inlining possibilities. + ILInlining inlining = new ILInlining(method); + inlining.InlineAllVariables(); + inlining.CopyPropagation(); + } + } + + static void Step2(List body) + { + for (int pos = 0; pos < body.Count; pos++) { + ILTryCatchBlock tc = body[pos] as ILTryCatchBlock; + if (tc != null) { + Step2(tc.TryBlock.Body); + } else { + Step2(body, ref pos); + } + } + } + + static bool Step2(List body, ref int pos) + { + // stloc(CS$0$0001, callvirt(class System.Threading.Tasks.Task`1::GetAwaiter, awaiterExpr) + // brtrue(IL_7C, call(valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter`1::get_IsCompleted, ldloca(CS$0$0001))) + // await(ldloca(CS$0$0001)) + // ... + // IL_7C: + // arg_8B_0 = call(valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter`1::GetResult, ldloca(CS$0$0001)) + // initobj(valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter`1, ldloca(CS$0$0001)) + + ILExpression loadAwaiter; + ILVariable awaiterVar; + if (!body[pos].Match(ILCode.Await, out loadAwaiter)) + return false; + if (!loadAwaiter.Match(ILCode.Ldloca, out awaiterVar)) + return false; + + ILVariable stackVar; + ILExpression stackExpr; + while (pos >= 1 && body[pos - 1].Match(ILCode.Stloc, out stackVar, out stackExpr)) + pos--; + + // stloc(CS$0$0001, callvirt(class System.Threading.Tasks.Task`1::GetAwaiter, awaiterExpr) + ILExpression getAwaiterCall; + if (!(pos >= 2 && body[pos - 2].MatchStloc(awaiterVar, out getAwaiterCall))) + return false; + MethodReference getAwaiterMethod; + ILExpression awaitedExpr; + if (!(getAwaiterCall.Match(ILCode.Call, out getAwaiterMethod, out awaitedExpr) || getAwaiterCall.Match(ILCode.Callvirt, out getAwaiterMethod, out awaitedExpr))) + return false; + + if (awaitedExpr.Code == ILCode.AddressOf) { + // remove 'AddressOf()' when calling GetAwaiter() on a value type + awaitedExpr = awaitedExpr.Arguments[0]; + } + + // brtrue(IL_7C, call(valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter`1::get_IsCompleted, ldloca(CS$0$0001))) + ILLabel label; + ILExpression getIsCompletedCall; + if (!(pos >= 1 && body[pos - 1].Match(ILCode.Brtrue, out label, out getIsCompletedCall))) + return false; + + int labelPos = body.IndexOf(label); + if (labelPos < pos) + return false; + for (int i = pos + 1; i < labelPos; i++) { + // validate that we aren't deleting any unexpected instructions - + // between the await and the label, there should only be the stack, awaiter and state logic + ILExpression expr = body[i] as ILExpression; + if (expr == null) + return false; + switch (expr.Code) { + case ILCode.Stloc: + case ILCode.Initobj: + case ILCode.Stfld: + case ILCode.Await: + // e.g. + // stloc(CS$0$0001, ldfld(StateMachine::<>u__$awaitere, ldloc(this))) + // initobj(valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter`1, ldloca(CS$0$0002_66)) + // stfld('d__d'::<>u__$awaitere, ldloc(this), ldloc(CS$0$0002_66)) + // stfld('d__d'::<>1__state, ldloc(this), ldc.i4(-1)) + break; + default: + return false; + } + } + if (labelPos + 1 >= body.Count) + return false; + ILExpression resultAssignment = body[labelPos + 1] as ILExpression; + ILVariable resultVar; + ILExpression getResultCall; + bool isResultAssignment = resultAssignment.Match(ILCode.Stloc, out resultVar, out getResultCall); + if (!isResultAssignment) + getResultCall = resultAssignment; + if (!(getResultCall.Operand is MethodReference && ((MethodReference)getResultCall.Operand).Name == "GetResult")) + return false; + + pos -= 2; // also delete 'stloc', 'brtrue' and 'await' + body.RemoveRange(pos, labelPos - pos); + Debug.Assert(body[pos] == label); + + pos++; + if (isResultAssignment) { + Debug.Assert(body[pos] == resultAssignment); + resultAssignment.Arguments[0] = new ILExpression(ILCode.Await, null, awaitedExpr); + } else { + body[pos] = new ILExpression(ILCode.Await, null, awaitedExpr); + } + + // if the awaiter variable is cleared out in the next instruction, remove that instruction + if (IsVariableReset(body.ElementAtOrDefault(pos + 1), awaiterVar)) { + body.RemoveAt(pos + 1); + } + + return true; + } + + static bool IsVariableReset(ILNode expr, ILVariable variable) + { + object unused; + ILExpression ldloca; + return expr.Match(ILCode.Initobj, out unused, out ldloca) && ldloca.MatchLdloca(variable); + } + #endregion + } +} diff --git a/src/Libraries/ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs b/src/Libraries/ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs index 051662f357..bf85ca94f4 100644 --- a/src/Libraries/ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs +++ b/src/Libraries/ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs @@ -35,6 +35,7 @@ namespace ICSharpCode.Decompiler.ILAst InlineVariables, CopyPropagation, YieldReturn, + AsyncAwait, PropertyAccessInstructions, SplitToMovableBlocks, TypeInference, @@ -107,6 +108,10 @@ namespace ICSharpCode.Decompiler.ILAst if (abortBeforeStep == ILAstOptimizationStep.YieldReturn) return; YieldReturnDecompiler.Run(context, method); + AsyncDecompiler.RunStep1(context, method); + + if (abortBeforeStep == ILAstOptimizationStep.AsyncAwait) return; + AsyncDecompiler.RunStep2(context, method); if (abortBeforeStep == ILAstOptimizationStep.PropertyAccessInstructions) return; IntroducePropertyAccessInstructions(method); @@ -256,7 +261,7 @@ namespace ICSharpCode.Decompiler.ILAst /// Ignore arguments of 'leave' /// /// - void RemoveRedundantCode(ILBlock method) + internal static void RemoveRedundantCode(ILBlock method) { Dictionary labelRefCount = new Dictionary(); foreach (ILLabel target in method.GetSelfAndChildrenRecursive(e => e.IsBranch()).SelectMany(e => e.GetBranchTargets())) { @@ -286,7 +291,13 @@ namespace ICSharpCode.Decompiler.ILAst prevExpr.ILRanges.AddRange(((ILExpression)body[i]).ILRanges); // Ignore pop } else { - newBody.Add(body[i]); + ILLabel label = body[i] as ILLabel; + if (label != null) { + if (labelRefCount.GetOrDefault(label) > 0) + newBody.Add(label); + } else { + newBody.Add(body[i]); + } } } block.Body = newBody; diff --git a/src/Libraries/ICSharpCode.Decompiler/ILAst/ILCodes.cs b/src/Libraries/ICSharpCode.Decompiler/ILAst/ILCodes.cs index cbf5486988..5ca063b752 100644 --- a/src/Libraries/ICSharpCode.Decompiler/ILAst/ILCodes.cs +++ b/src/Libraries/ICSharpCode.Decompiler/ILAst/ILCodes.cs @@ -333,7 +333,11 @@ namespace ICSharpCode.Decompiler.ILAst /// The last child of this node is the call constructing the expression tree, all other children are the /// assignments to the ParameterExpression variables. /// - ExpressionTreeParameterDeclarations + ExpressionTreeParameterDeclarations, + /// + /// C# 5 await + /// + Await } public static class ILCodeUtil diff --git a/src/Libraries/ICSharpCode.Decompiler/ILAst/PatternMatching.cs b/src/Libraries/ICSharpCode.Decompiler/ILAst/PatternMatching.cs index cc4e5ee5f5..31fcf62b15 100644 --- a/src/Libraries/ICSharpCode.Decompiler/ILAst/PatternMatching.cs +++ b/src/Libraries/ICSharpCode.Decompiler/ILAst/PatternMatching.cs @@ -155,5 +155,17 @@ namespace ICSharpCode.Decompiler.ILAst ILVariable v; return node.Match(ILCode.Ldloc, out v) && v == expectedVar; } + + public static bool MatchLdloca(this ILNode node, ILVariable expectedVar) + { + ILVariable v; + return node.Match(ILCode.Ldloca, out v) && v == expectedVar; + } + + public static bool MatchStloc(this ILNode node, ILVariable expectedVar, out ILExpression expr) + { + ILVariable v; + return node.Match(ILCode.Stloc, out v, out expr) && v == expectedVar; + } } } diff --git a/src/Libraries/ICSharpCode.Decompiler/ILAst/StateRange.cs b/src/Libraries/ICSharpCode.Decompiler/ILAst/StateRange.cs new file mode 100644 index 0000000000..4a55e1d0b6 --- /dev/null +++ b/src/Libraries/ICSharpCode.Decompiler/ILAst/StateRange.cs @@ -0,0 +1,310 @@ +// Copyright (c) 2012 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using Mono.Cecil; + +namespace ICSharpCode.Decompiler.ILAst +{ + struct Interval + { + public readonly int Start, End; + + public Interval(int start, int end) + { + Debug.Assert(start <= end || (start == 0 && end == -1)); + this.Start = start; + this.End = end; + } + + public override string ToString() + { + return string.Format("({0} to {1})", Start, End); + } + } + + class StateRange + { + readonly List data = new List(); + + public StateRange() + { + } + + public StateRange(int start, int end) + { + this.data.Add(new Interval(start, end)); + } + + public bool IsEmpty { + get { return data.Count == 0; } + } + + public bool Contains(int val) + { + foreach (Interval v in data) { + if (v.Start <= val && val <= v.End) + return true; + } + return false; + } + + public void UnionWith(StateRange other) + { + data.AddRange(other.data); + } + + /// + /// Unions this state range with (other intersect (minVal to maxVal)) + /// + public void UnionWith(StateRange other, int minVal, int maxVal) + { + foreach (Interval v in other.data) { + int start = Math.Max(v.Start, minVal); + int end = Math.Min(v.End, maxVal); + if (start <= end) + data.Add(new Interval(start, end)); + } + } + + /// + /// Merges overlapping interval ranges. + /// + public void Simplify() + { + if (data.Count < 2) + return; + data.Sort((a, b) => a.Start.CompareTo(b.Start)); + Interval prev = data[0]; + int prevIndex = 0; + for (int i = 1; i < data.Count; i++) { + Interval next = data[i]; + Debug.Assert(prev.Start <= next.Start); + if (next.Start <= prev.End + 1) { // intervals overlapping or touching + prev = new Interval(prev.Start, Math.Max(prev.End, next.End)); + data[prevIndex] = prev; + data[i] = new Interval(0, -1); // mark as deleted + } else { + prev = next; + prevIndex = i; + } + } + data.RemoveAll(i => i.Start > i.End); // remove all entries that were marked as deleted + } + + public override string ToString() + { + return string.Join(",", data); + } + + public Interval ToEnclosingInterval() + { + if (data.Count == 0) + throw new SymbolicAnalysisFailedException(); + return new Interval(data[0].Start, data[data.Count - 1].End); + } + } + + enum StateRangeAnalysisMode + { + IteratorMoveNext, + IteratorDispose, + AsyncMoveNext + } + + class StateRangeAnalysis + { + readonly StateRangeAnalysisMode mode; + readonly FieldDefinition stateField; + internal DefaultDictionary ranges; + SymbolicEvaluationContext evalContext; + + internal Dictionary finallyMethodToStateInterval; // used only for IteratorDispose + + /// + /// Initializes the state range logic: + /// Clears 'ranges' and sets 'ranges[entryPoint]' to the full range (int.MinValue to int.MaxValue) + /// + public StateRangeAnalysis(ILNode entryPoint, StateRangeAnalysisMode mode, FieldDefinition stateField) + { + this.mode = mode; + this.stateField = stateField; + if (mode == StateRangeAnalysisMode.IteratorDispose) { + finallyMethodToStateInterval = new Dictionary(); + } + + ranges = new DefaultDictionary(n => new StateRange()); + ranges[entryPoint] = new StateRange(int.MinValue, int.MaxValue); + evalContext = new SymbolicEvaluationContext(stateField); + } + + public int AssignStateRanges(List body, int bodyLength) + { + if (bodyLength == 0) + return 0; + for (int i = 0; i < bodyLength; i++) { + StateRange nodeRange = ranges[body[i]]; + nodeRange.Simplify(); + + ILLabel label = body[i] as ILLabel; + if (label != null) { + ranges[body[i + 1]].UnionWith(nodeRange); + continue; + } + + ILTryCatchBlock tryFinally = body[i] as ILTryCatchBlock; + if (tryFinally != null) { + if (mode == StateRangeAnalysisMode.IteratorDispose) { + if (tryFinally.CatchBlocks.Count != 0 || tryFinally.FaultBlock != null || tryFinally.FinallyBlock == null) + throw new SymbolicAnalysisFailedException(); + ranges[tryFinally.TryBlock].UnionWith(nodeRange); + if (tryFinally.TryBlock.Body.Count != 0) { + ranges[tryFinally.TryBlock.Body[0]].UnionWith(nodeRange); + AssignStateRanges(tryFinally.TryBlock.Body, tryFinally.TryBlock.Body.Count); + } + continue; + } else if (mode == StateRangeAnalysisMode.AsyncMoveNext) { + return i; + } else { + throw new SymbolicAnalysisFailedException(); + } + } + + ILExpression expr = body[i] as ILExpression; + if (expr == null) + throw new SymbolicAnalysisFailedException(); + switch (expr.Code) { + case ILCode.Switch: + { + SymbolicValue val = evalContext.Eval(expr.Arguments[0]); + if (val.Type != SymbolicValueType.State) + goto default; + ILLabel[] targetLabels = (ILLabel[])expr.Operand; + for (int j = 0; j < targetLabels.Length; j++) { + int state = j - val.Constant; + ranges[targetLabels[j]].UnionWith(nodeRange, state, state); + } + StateRange nextRange = ranges[body[i + 1]]; + nextRange.UnionWith(nodeRange, int.MinValue, -1 - val.Constant); + nextRange.UnionWith(nodeRange, targetLabels.Length - val.Constant, int.MaxValue); + break; + } + case ILCode.Br: + case ILCode.Leave: + ranges[(ILLabel)expr.Operand].UnionWith(nodeRange); + break; + case ILCode.Brtrue: + { + SymbolicValue val = evalContext.Eval(expr.Arguments[0]); + if (val.Type == SymbolicValueType.StateEquals) { + ranges[(ILLabel)expr.Operand].UnionWith(nodeRange, val.Constant, val.Constant); + StateRange nextRange = ranges[body[i + 1]]; + nextRange.UnionWith(nodeRange, int.MinValue, val.Constant - 1); + nextRange.UnionWith(nodeRange, val.Constant + 1, int.MaxValue); + break; + } else if (val.Type == SymbolicValueType.StateInEquals) { + ranges[body[i + 1]].UnionWith(nodeRange, val.Constant, val.Constant); + StateRange targetRange = ranges[(ILLabel)expr.Operand]; + targetRange.UnionWith(nodeRange, int.MinValue, val.Constant - 1); + targetRange.UnionWith(nodeRange, val.Constant + 1, int.MaxValue); + break; + } else { + goto default; + } + } + case ILCode.Nop: + ranges[body[i + 1]].UnionWith(nodeRange); + break; + case ILCode.Ret: + break; + case ILCode.Stloc: + { + SymbolicValue val = evalContext.Eval(expr.Arguments[0]); + if (val.Type == SymbolicValueType.State && val.Constant == 0) { + evalContext.AddStateVariable((ILVariable)expr.Operand); + goto case ILCode.Nop; + } else { + goto default; + } + } + case ILCode.Call: + // in some cases (e.g. foreach over array) the C# compiler produces a finally method outside of try-finally blocks + if (mode == StateRangeAnalysisMode.IteratorDispose) { + MethodDefinition mdef = (expr.Operand as MethodReference).ResolveWithinSameModule(); + if (mdef == null || finallyMethodToStateInterval.ContainsKey(mdef)) + throw new SymbolicAnalysisFailedException(); + finallyMethodToStateInterval.Add(mdef, nodeRange.ToEnclosingInterval()); + break; + } else { + goto default; + } + default: + if (mode == StateRangeAnalysisMode.IteratorDispose) { + throw new SymbolicAnalysisFailedException(); + } else { + return i; + } + } + } + return bodyLength; + } + + public void EnsureLabelAtPos(List body, ref int pos, ref int bodyLength) + { + if (pos > 0 && body[pos - 1] is ILLabel) { + pos--; + } else { + // ensure that the first element at body[pos] is a label: + ILLabel newLabel = new ILLabel(); + newLabel.Name = "YieldReturnEntryPoint"; + ranges[newLabel] = ranges[body[pos]]; // give the label the range of the instruction at body[pos] + body.Insert(pos, newLabel); + bodyLength++; + } + } + + public LabelRangeMapping CreateLabelRangeMapping(List body, int pos, int bodyLength) + { + LabelRangeMapping result = new LabelRangeMapping(); + CreateLabelRangeMapping(body, pos, bodyLength, result, false); + return result; + } + + void CreateLabelRangeMapping(List body, int pos, int bodyLength, LabelRangeMapping result, bool onlyInitialLabels) + { + for (int i = pos; i < bodyLength; i++) { + ILLabel label = body[i] as ILLabel; + if (label != null) { + result.Add(new KeyValuePair(label, ranges[label])); + } else { + ILTryCatchBlock tryCatchBlock = body[i] as ILTryCatchBlock; + if (tryCatchBlock != null) { + CreateLabelRangeMapping(tryCatchBlock.TryBlock.Body, 0, tryCatchBlock.TryBlock.Body.Count, result, true); + } else if (onlyInitialLabels) { + break; + } + } + } + } + } + + class LabelRangeMapping : List> {} +} diff --git a/src/Libraries/ICSharpCode.Decompiler/ILAst/SymbolicExecution.cs b/src/Libraries/ICSharpCode.Decompiler/ILAst/SymbolicExecution.cs new file mode 100644 index 0000000000..98255f2f2d --- /dev/null +++ b/src/Libraries/ICSharpCode.Decompiler/ILAst/SymbolicExecution.cs @@ -0,0 +1,148 @@ +// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using Mono.Cecil; + +namespace ICSharpCode.Decompiler.ILAst +{ + /// + /// This exception is thrown when we find something else than we expect from the C# compiler. + /// This aborts the analysis and makes the whole transform fail. + /// + class SymbolicAnalysisFailedException : Exception {} + + enum SymbolicValueType + { + /// + /// Unknown value + /// + Unknown, + /// + /// int: Constant (result of ldc.i4) + /// + IntegerConstant, + /// + /// int: State + Constant + /// + State, + /// + /// This pointer (result of ldarg.0) + /// + This, + /// + /// bool: State == Constant + /// + StateEquals, + /// + /// bool: State != Constant + /// + StateInEquals + } + + struct SymbolicValue + { + public readonly int Constant; + public readonly SymbolicValueType Type; + + public SymbolicValue(SymbolicValueType type, int constant = 0) + { + this.Type = type; + this.Constant = constant; + } + + public override string ToString() + { + return string.Format("[SymbolicValue {0}: {1}]", this.Type, this.Constant); + } + } + + class SymbolicEvaluationContext + { + readonly FieldDefinition stateField; + readonly List stateVariables = new List(); + + public SymbolicEvaluationContext(FieldDefinition stateField) + { + this.stateField = stateField; + } + + public void AddStateVariable(ILVariable v) + { + if (!stateVariables.Contains(v)) + stateVariables.Add(v); + } + + SymbolicValue Failed() + { + return new SymbolicValue(SymbolicValueType.Unknown); + } + + public SymbolicValue Eval(ILExpression expr) + { + SymbolicValue left, right; + switch (expr.Code) { + case ILCode.Sub: + left = Eval(expr.Arguments[0]); + right = Eval(expr.Arguments[1]); + if (left.Type != SymbolicValueType.State && left.Type != SymbolicValueType.IntegerConstant) + return Failed(); + if (right.Type != SymbolicValueType.IntegerConstant) + return Failed(); + return new SymbolicValue(left.Type, unchecked ( left.Constant - right.Constant )); + case ILCode.Ldfld: + if (Eval(expr.Arguments[0]).Type != SymbolicValueType.This) + return Failed(); + if (CecilExtensions.ResolveWithinSameModule(expr.Operand as FieldReference) != stateField) + return Failed(); + return new SymbolicValue(SymbolicValueType.State); + case ILCode.Ldloc: + ILVariable loadedVariable = (ILVariable)expr.Operand; + if (stateVariables.Contains(loadedVariable)) + return new SymbolicValue(SymbolicValueType.State); + else if (loadedVariable.IsParameter && loadedVariable.OriginalParameter.Index < 0) + return new SymbolicValue(SymbolicValueType.This); + else + return Failed(); + case ILCode.Ldc_I4: + return new SymbolicValue(SymbolicValueType.IntegerConstant, (int)expr.Operand); + case ILCode.Ceq: + case ILCode.Cne: + left = Eval(expr.Arguments[0]); + right = Eval(expr.Arguments[1]); + if (left.Type != SymbolicValueType.State || right.Type != SymbolicValueType.IntegerConstant) + return Failed(); + // bool: (state + left.Constant == right.Constant) + // bool: (state == right.Constant - left.Constant) + return new SymbolicValue(expr.Code == ILCode.Ceq ? SymbolicValueType.StateEquals : SymbolicValueType.StateInEquals, unchecked(right.Constant - left.Constant)); + case ILCode.LogicNot: + SymbolicValue val = Eval(expr.Arguments[0]); + if (val.Type == SymbolicValueType.StateEquals) + return new SymbolicValue(SymbolicValueType.StateInEquals, val.Constant); + else if (val.Type == SymbolicValueType.StateInEquals) + return new SymbolicValue(SymbolicValueType.StateEquals, val.Constant); + else + return Failed(); + default: + return Failed(); + } + } + } +} diff --git a/src/Libraries/ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs b/src/Libraries/ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs index 6e8444a1ca..2e46e285bf 100644 --- a/src/Libraries/ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs +++ b/src/Libraries/ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs @@ -790,8 +790,17 @@ namespace ICSharpCode.Decompiler.ILAst case ILCode.YieldBreak: return null; case ILCode.Ret: - if (forceInferChildren && expr.Arguments.Count == 1) - InferTypeForExpression(expr.Arguments[0], context.CurrentMethod.ReturnType); + if (forceInferChildren && expr.Arguments.Count == 1) { + TypeReference returnType = context.CurrentMethod.ReturnType; + if (context.CurrentMethodIsAsync && returnType != null && returnType.Namespace == "System.Threading.Tasks") { + if (returnType.Name == "Task") { + returnType = typeSystem.Void; + } else if (returnType.Name == "Task`1" && returnType.IsGenericInstance) { + returnType = ((GenericInstanceType)returnType).GenericArguments[0]; + } + } + InferTypeForExpression(expr.Arguments[0], returnType); + } return null; case ILCode.YieldReturn: if (forceInferChildren) { @@ -803,6 +812,14 @@ namespace ICSharpCode.Decompiler.ILAst } } return null; + case ILCode.Await: + { + TypeReference taskType = InferTypeForExpression(expr.Arguments[0], null); + if (taskType.Name == "Task`1" && taskType.IsGenericInstance && taskType.Namespace == "System.Threading.Tasks") { + return ((GenericInstanceType)taskType).GenericArguments[0]; + } + return null; + } #endregion case ILCode.Pop: return null; diff --git a/src/Libraries/ICSharpCode.Decompiler/ILAst/YieldReturnDecompiler.cs b/src/Libraries/ICSharpCode.Decompiler/ILAst/YieldReturnDecompiler.cs index 06a211eea8..b4b6183bf8 100644 --- a/src/Libraries/ICSharpCode.Decompiler/ILAst/YieldReturnDecompiler.cs +++ b/src/Libraries/ICSharpCode.Decompiler/ILAst/YieldReturnDecompiler.cs @@ -24,7 +24,7 @@ using Mono.Cecil; namespace ICSharpCode.Decompiler.ILAst { - public class YieldReturnDecompiler + class YieldReturnDecompiler { // For a description on the code generated by the C# compiler for yield return: // http://csharpindepth.com/Articles/Chapter6/IteratorBlockImplementation.aspx @@ -34,11 +34,8 @@ namespace ICSharpCode.Decompiler.ILAst // - Figure out which of the fields is the state field // - Construct an exception table based on states. This allows us to determine, for each state, what the parent try block is. - /// - /// This exception is thrown when we find something else than we expect from the C# compiler. - /// This aborts the analysis and makes the whole transform fail. - /// - class YieldAnalysisFailedException : Exception {} + // See http://community.sharpdevelop.net/blogs/danielgrunwald/archive/2011/03/06/ilspy-yield-return.aspx + // for a description of this step. DecompilerContext context; TypeDefinition enumeratorType; @@ -66,7 +63,7 @@ namespace ICSharpCode.Decompiler.ILAst #endif try { yrd.Run(); - } catch (YieldAnalysisFailedException) { + } catch (SymbolicAnalysisFailedException) { return; } #if DEBUG @@ -211,7 +208,7 @@ namespace ICSharpCode.Decompiler.ILAst } } if (stateField == null) - throw new YieldAnalysisFailedException(); + throw new SymbolicAnalysisFailedException(); } /// @@ -220,7 +217,7 @@ namespace ICSharpCode.Decompiler.ILAst ILBlock CreateILAst(MethodDefinition method) { if (method == null || !method.HasBody) - throw new YieldAnalysisFailedException(); + throw new SymbolicAnalysisFailedException(); ILBlock ilMethod = new ILBlock(); ILAstBuilder astBuilder = new ILAstBuilder(); @@ -269,7 +266,7 @@ namespace ICSharpCode.Decompiler.ILAst } } if (currentField == null) - throw new YieldAnalysisFailedException(); + throw new SymbolicAnalysisFailedException(); } #endregion @@ -322,337 +319,30 @@ namespace ICSharpCode.Decompiler.ILAst disposeMethod = enumeratorType.Methods.FirstOrDefault(m => m.Name == "System.IDisposable.Dispose"); ILBlock ilMethod = CreateILAst(disposeMethod); - finallyMethodToStateInterval = new Dictionary(); - - InitStateRanges(ilMethod.Body[0]); - AssignStateRanges(ilMethod.Body, ilMethod.Body.Count, forDispose: true); + var rangeAnalysis = new StateRangeAnalysis(ilMethod.Body[0], StateRangeAnalysisMode.IteratorDispose, stateField); + rangeAnalysis.AssignStateRanges(ilMethod.Body, ilMethod.Body.Count); + finallyMethodToStateInterval = rangeAnalysis.finallyMethodToStateInterval; // Now look at the finally blocks: foreach (var tryFinally in ilMethod.GetSelfAndChildrenRecursive()) { - Interval interval = ranges[tryFinally.TryBlock.Body[0]].ToEnclosingInterval(); + Interval interval = rangeAnalysis.ranges[tryFinally.TryBlock.Body[0]].ToEnclosingInterval(); var finallyBody = tryFinally.FinallyBlock.Body; if (finallyBody.Count != 2) - throw new YieldAnalysisFailedException(); + throw new SymbolicAnalysisFailedException(); ILExpression call = finallyBody[0] as ILExpression; if (call == null || call.Code != ILCode.Call || call.Arguments.Count != 1) - throw new YieldAnalysisFailedException(); + throw new SymbolicAnalysisFailedException(); if (!call.Arguments[0].MatchThis()) - throw new YieldAnalysisFailedException(); + throw new SymbolicAnalysisFailedException(); if (!finallyBody[1].Match(ILCode.Endfinally)) - throw new YieldAnalysisFailedException(); + throw new SymbolicAnalysisFailedException(); MethodDefinition mdef = GetMethodDefinition(call.Operand as MethodReference); if (mdef == null || finallyMethodToStateInterval.ContainsKey(mdef)) - throw new YieldAnalysisFailedException(); + throw new SymbolicAnalysisFailedException(); finallyMethodToStateInterval.Add(mdef, interval); } - ranges = null; - } - #endregion - - #region Assign StateRanges / Symbolic Execution (used for analysis of Dispose() and MoveNext()) - #region struct Interval / class StateRange - struct Interval - { - public readonly int Start, End; - - public Interval(int start, int end) - { - Debug.Assert(start <= end || (start == 0 && end == -1)); - this.Start = start; - this.End = end; - } - - public override string ToString() - { - return string.Format("({0} to {1})", Start, End); - } - } - - class StateRange - { - readonly List data = new List(); - - public StateRange() - { - } - - public StateRange(int start, int end) - { - this.data.Add(new Interval(start, end)); - } - - public bool Contains(int val) - { - foreach (Interval v in data) { - if (v.Start <= val && val <= v.End) - return true; - } - return false; - } - - public void UnionWith(StateRange other) - { - data.AddRange(other.data); - } - - /// - /// Unions this state range with (other intersect (minVal to maxVal)) - /// - public void UnionWith(StateRange other, int minVal, int maxVal) - { - foreach (Interval v in other.data) { - int start = Math.Max(v.Start, minVal); - int end = Math.Min(v.End, maxVal); - if (start <= end) - data.Add(new Interval(start, end)); - } - } - - /// - /// Merges overlapping interval ranges. - /// - public void Simplify() - { - if (data.Count < 2) - return; - data.Sort((a, b) => a.Start.CompareTo(b.Start)); - Interval prev = data[0]; - int prevIndex = 0; - for (int i = 1; i < data.Count; i++) { - Interval next = data[i]; - Debug.Assert(prev.Start <= next.Start); - if (next.Start <= prev.End + 1) { // intervals overlapping or touching - prev = new Interval(prev.Start, Math.Max(prev.End, next.End)); - data[prevIndex] = prev; - data[i] = new Interval(0, -1); // mark as deleted - } else { - prev = next; - prevIndex = i; - } - } - data.RemoveAll(i => i.Start > i.End); // remove all entries that were marked as deleted - } - - public override string ToString() - { - return string.Join(",", data); - } - - public Interval ToEnclosingInterval() - { - if (data.Count == 0) - throw new YieldAnalysisFailedException(); - return new Interval(data[0].Start, data[data.Count - 1].End); - } - } - #endregion - - DefaultDictionary ranges; - ILVariable rangeAnalysisStateVariable; - - /// - /// Initializes the state range logic: - /// Clears 'ranges' and sets 'ranges[entryPoint]' to the full range (int.MinValue to int.MaxValue) - /// - void InitStateRanges(ILNode entryPoint) - { - ranges = new DefaultDictionary(n => new StateRange()); - ranges[entryPoint] = new StateRange(int.MinValue, int.MaxValue); - rangeAnalysisStateVariable = null; - } - - int AssignStateRanges(List body, int bodyLength, bool forDispose) - { - if (bodyLength == 0) - return 0; - for (int i = 0; i < bodyLength; i++) { - StateRange nodeRange = ranges[body[i]]; - nodeRange.Simplify(); - - ILLabel label = body[i] as ILLabel; - if (label != null) { - ranges[body[i + 1]].UnionWith(nodeRange); - continue; - } - - ILTryCatchBlock tryFinally = body[i] as ILTryCatchBlock; - if (tryFinally != null) { - if (!forDispose || tryFinally.CatchBlocks.Count != 0 || tryFinally.FaultBlock != null || tryFinally.FinallyBlock == null) - throw new YieldAnalysisFailedException(); - ranges[tryFinally.TryBlock].UnionWith(nodeRange); - if (tryFinally.TryBlock.Body.Count != 0) { - ranges[tryFinally.TryBlock.Body[0]].UnionWith(nodeRange); - AssignStateRanges(tryFinally.TryBlock.Body, tryFinally.TryBlock.Body.Count, forDispose); - } - continue; - } - - ILExpression expr = body[i] as ILExpression; - if (expr == null) - throw new YieldAnalysisFailedException(); - switch (expr.Code) { - case ILCode.Switch: - { - SymbolicValue val = Eval(expr.Arguments[0]); - if (val.Type != SymbolicValueType.State) - throw new YieldAnalysisFailedException(); - ILLabel[] targetLabels = (ILLabel[])expr.Operand; - for (int j = 0; j < targetLabels.Length; j++) { - int state = j - val.Constant; - ranges[targetLabels[j]].UnionWith(nodeRange, state, state); - } - StateRange nextRange = ranges[body[i + 1]]; - nextRange.UnionWith(nodeRange, int.MinValue, -1 - val.Constant); - nextRange.UnionWith(nodeRange, targetLabels.Length - val.Constant, int.MaxValue); - break; - } - case ILCode.Br: - case ILCode.Leave: - ranges[(ILLabel)expr.Operand].UnionWith(nodeRange); - break; - case ILCode.Brtrue: - { - SymbolicValue val = Eval(expr.Arguments[0]); - if (val.Type == SymbolicValueType.StateEquals) { - ranges[(ILLabel)expr.Operand].UnionWith(nodeRange, val.Constant, val.Constant); - StateRange nextRange = ranges[body[i + 1]]; - nextRange.UnionWith(nodeRange, int.MinValue, val.Constant - 1); - nextRange.UnionWith(nodeRange, val.Constant + 1, int.MaxValue); - } else if (val.Type == SymbolicValueType.StateInEquals) { - ranges[body[i + 1]].UnionWith(nodeRange, val.Constant, val.Constant); - StateRange targetRange = ranges[(ILLabel)expr.Operand]; - targetRange.UnionWith(nodeRange, int.MinValue, val.Constant - 1); - targetRange.UnionWith(nodeRange, val.Constant + 1, int.MaxValue); - } else { - throw new YieldAnalysisFailedException(); - } - break; - } - case ILCode.Nop: - ranges[body[i + 1]].UnionWith(nodeRange); - break; - case ILCode.Ret: - break; - case ILCode.Stloc: - { - SymbolicValue val = Eval(expr.Arguments[0]); - if (val.Type == SymbolicValueType.State && val.Constant == 0 && rangeAnalysisStateVariable == null) - rangeAnalysisStateVariable = (ILVariable)expr.Operand; - else - throw new YieldAnalysisFailedException(); - goto case ILCode.Nop; - } - case ILCode.Call: - // in some cases (e.g. foreach over array) the C# compiler produces a finally method outside of try-finally blocks - if (forDispose) { - MethodDefinition mdef = GetMethodDefinition(expr.Operand as MethodReference); - if (mdef == null || finallyMethodToStateInterval.ContainsKey(mdef)) - throw new YieldAnalysisFailedException(); - finallyMethodToStateInterval.Add(mdef, nodeRange.ToEnclosingInterval()); - } else { - throw new YieldAnalysisFailedException(); - } - break; - default: - if (forDispose) - throw new YieldAnalysisFailedException(); - else - return i; - } - } - return bodyLength; - } - - enum SymbolicValueType - { - /// - /// int: Constant (result of ldc.i4) - /// - IntegerConstant, - /// - /// int: State + Constant - /// - State, - /// - /// This pointer (result of ldarg.0) - /// - This, - /// - /// bool: State == Constant - /// - StateEquals, - /// - /// bool: State != Constant - /// - StateInEquals - } - - struct SymbolicValue - { - public readonly int Constant; - public readonly SymbolicValueType Type; - - public SymbolicValue(SymbolicValueType type, int constant = 0) - { - this.Type = type; - this.Constant = constant; - } - - public override string ToString() - { - return string.Format("[SymbolicValue {0}: {1}]", this.Type, this.Constant); - } - } - - SymbolicValue Eval(ILExpression expr) - { - SymbolicValue left, right; - switch (expr.Code) { - case ILCode.Sub: - left = Eval(expr.Arguments[0]); - right = Eval(expr.Arguments[1]); - if (left.Type != SymbolicValueType.State && left.Type != SymbolicValueType.IntegerConstant) - throw new YieldAnalysisFailedException(); - if (right.Type != SymbolicValueType.IntegerConstant) - throw new YieldAnalysisFailedException(); - return new SymbolicValue(left.Type, unchecked ( left.Constant - right.Constant )); - case ILCode.Ldfld: - if (Eval(expr.Arguments[0]).Type != SymbolicValueType.This) - throw new YieldAnalysisFailedException(); - if (GetFieldDefinition(expr.Operand as FieldReference) != stateField) - throw new YieldAnalysisFailedException(); - return new SymbolicValue(SymbolicValueType.State); - case ILCode.Ldloc: - ILVariable loadedVariable = (ILVariable)expr.Operand; - if (loadedVariable == rangeAnalysisStateVariable) - return new SymbolicValue(SymbolicValueType.State); - else if (loadedVariable.IsParameter && loadedVariable.OriginalParameter.Index < 0) - return new SymbolicValue(SymbolicValueType.This); - else - throw new YieldAnalysisFailedException(); - case ILCode.Ldc_I4: - return new SymbolicValue(SymbolicValueType.IntegerConstant, (int)expr.Operand); - case ILCode.Ceq: - case ILCode.Cne: - left = Eval(expr.Arguments[0]); - right = Eval(expr.Arguments[1]); - if (left.Type != SymbolicValueType.State || right.Type != SymbolicValueType.IntegerConstant) - throw new YieldAnalysisFailedException(); - // bool: (state + left.Constant == right.Constant) - // bool: (state == right.Constant - left.Constant) - return new SymbolicValue(expr.Code == ILCode.Ceq ? SymbolicValueType.StateEquals : SymbolicValueType.StateInEquals, unchecked(right.Constant - left.Constant)); - case ILCode.LogicNot: - SymbolicValue val = Eval(expr.Arguments[0]); - if (val.Type == SymbolicValueType.StateEquals) - return new SymbolicValue(SymbolicValueType.StateInEquals, val.Constant); - else if (val.Type == SymbolicValueType.StateInEquals) - return new SymbolicValue(SymbolicValueType.StateEquals, val.Constant); - else - throw new YieldAnalysisFailedException(); - default: - throw new YieldAnalysisFailedException(); - } + rangeAnalysis = null; } #endregion @@ -667,10 +357,10 @@ namespace ICSharpCode.Decompiler.ILAst ILBlock ilMethod = CreateILAst(moveNextMethod); if (ilMethod.Body.Count == 0) - throw new YieldAnalysisFailedException(); + throw new SymbolicAnalysisFailedException(); ILExpression lastReturnArg; if (!ilMethod.Body.Last().Match(ILCode.Ret, out lastReturnArg)) - throw new YieldAnalysisFailedException(); + throw new SymbolicAnalysisFailedException(); // There are two possibilities: if (lastReturnArg.Code == ILCode.Ldloc) { @@ -678,14 +368,14 @@ namespace ICSharpCode.Decompiler.ILAst returnVariable = (ILVariable)lastReturnArg.Operand; returnLabel = ilMethod.Body.ElementAtOrDefault(ilMethod.Body.Count - 2) as ILLabel; if (returnLabel == null) - throw new YieldAnalysisFailedException(); + throw new SymbolicAnalysisFailedException(); } else { // b) the compiler directly returns constants returnVariable = null; returnLabel = null; // In this case, the last return must return false. if (lastReturnArg.Code != ILCode.Ldc_I4 || (int)lastReturnArg.Operand != 0) - throw new YieldAnalysisFailedException(); + throw new SymbolicAnalysisFailedException(); } ILTryCatchBlock tryFaultBlock = ilMethod.Body[0] as ILTryCatchBlock; @@ -694,23 +384,23 @@ namespace ICSharpCode.Decompiler.ILAst if (tryFaultBlock != null) { // there are try-finally blocks if (returnVariable == null) // in this case, we must use a return variable - throw new YieldAnalysisFailedException(); + throw new SymbolicAnalysisFailedException(); // must be a try-fault block: if (tryFaultBlock.CatchBlocks.Count != 0 || tryFaultBlock.FinallyBlock != null || tryFaultBlock.FaultBlock == null) - throw new YieldAnalysisFailedException(); + throw new SymbolicAnalysisFailedException(); ILBlock faultBlock = tryFaultBlock.FaultBlock; // Ensure the fault block contains the call to Dispose(). if (faultBlock.Body.Count != 2) - throw new YieldAnalysisFailedException(); + throw new SymbolicAnalysisFailedException(); MethodReference disposeMethodRef; ILExpression disposeArg; if (!faultBlock.Body[0].Match(ILCode.Call, out disposeMethodRef, out disposeArg)) - throw new YieldAnalysisFailedException(); + throw new SymbolicAnalysisFailedException(); if (GetMethodDefinition(disposeMethodRef) != disposeMethod || !disposeArg.MatchThis()) - throw new YieldAnalysisFailedException(); + throw new SymbolicAnalysisFailedException(); if (!faultBlock.Body[1].Match(ILCode.Endfinally)) - throw new YieldAnalysisFailedException(); + throw new SymbolicAnalysisFailedException(); body = tryFaultBlock.TryBlock.Body; bodyLength = body.Count; @@ -734,39 +424,22 @@ namespace ICSharpCode.Decompiler.ILAst bodyLength--; ILExpression store0 = body.ElementAtOrDefault(bodyLength - 1) as ILExpression; if (store0 == null || store0.Code != ILCode.Stloc || store0.Operand != returnVariable) - throw new YieldAnalysisFailedException(); + throw new SymbolicAnalysisFailedException(); if (store0.Arguments[0].Code != ILCode.Ldc_I4 || (int)store0.Arguments[0].Operand != 0) - throw new YieldAnalysisFailedException(); + throw new SymbolicAnalysisFailedException(); bodyLength--; // don't conside the stloc instruction to be part of the body } // verify that the last element in the body is a label pointing to the 'ret(false)' returnFalseLabel = body.ElementAtOrDefault(bodyLength - 1) as ILLabel; if (returnFalseLabel == null) - throw new YieldAnalysisFailedException(); + throw new SymbolicAnalysisFailedException(); - InitStateRanges(body[0]); - int pos = AssignStateRanges(body, bodyLength, forDispose: false); - if (pos > 0 && body[pos - 1] is ILLabel) { - pos--; - } else { - // ensure that the first element at body[pos] is a label: - ILLabel newLabel = new ILLabel(); - newLabel.Name = "YieldReturnEntryPoint"; - ranges[newLabel] = ranges[body[pos]]; // give the label the range of the instruction at body[pos] - - body.Insert(pos, newLabel); - bodyLength++; - } - - List> labels = new List>(); - for (int i = pos; i < bodyLength; i++) { - ILLabel label = body[i] as ILLabel; - if (label != null) { - labels.Add(new KeyValuePair(label, ranges[label])); - } - } + var rangeAnalysis = new StateRangeAnalysis(body[0], StateRangeAnalysisMode.IteratorMoveNext, stateField); + int pos = rangeAnalysis.AssignStateRanges(body, bodyLength); + rangeAnalysis.EnsureLabelAtPos(body, ref pos, ref bodyLength); + var labels = rangeAnalysis.CreateLabelRangeMapping(body, pos, bodyLength); ConvertBody(body, pos, bodyLength, labels); } #endregion @@ -797,7 +470,7 @@ namespace ICSharpCode.Decompiler.ILAst // Handle stores to 'state' or 'current' if (GetFieldDefinition(expr.Operand as FieldReference) == stateField) { if (expr.Arguments[1].Code != ILCode.Ldc_I4) - throw new YieldAnalysisFailedException(); + throw new SymbolicAnalysisFailedException(); currentState = (int)expr.Arguments[1].Operand; stateChanges.Add(new SetState(newBody.Count, currentState)); } else if (GetFieldDefinition(expr.Operand as FieldReference) == currentField) { @@ -809,18 +482,18 @@ namespace ICSharpCode.Decompiler.ILAst // handle store+branch to the returnVariable ILExpression br = body.ElementAtOrDefault(++pos) as ILExpression; if (br == null || !(br.Code == ILCode.Br || br.Code == ILCode.Leave) || br.Operand != returnLabel || expr.Arguments[0].Code != ILCode.Ldc_I4) - throw new YieldAnalysisFailedException(); + throw new SymbolicAnalysisFailedException(); int val = (int)expr.Arguments[0].Operand; if (val == 0) { newBody.Add(MakeGoTo(returnFalseLabel)); } else if (val == 1) { newBody.Add(MakeGoTo(labels, currentState)); } else { - throw new YieldAnalysisFailedException(); + throw new SymbolicAnalysisFailedException(); } } else if (expr != null && expr.Code == ILCode.Ret) { if (expr.Arguments.Count != 1 || expr.Arguments[0].Code != ILCode.Ldc_I4) - throw new YieldAnalysisFailedException(); + throw new SymbolicAnalysisFailedException(); // handle direct return (e.g. in release builds) int val = (int)expr.Arguments[0].Operand; if (val == 0) { @@ -828,24 +501,24 @@ namespace ICSharpCode.Decompiler.ILAst } else if (val == 1) { newBody.Add(MakeGoTo(labels, currentState)); } else { - throw new YieldAnalysisFailedException(); + throw new SymbolicAnalysisFailedException(); } } else if (expr != null && expr.Code == ILCode.Call && expr.Arguments.Count == 1 && expr.Arguments[0].MatchThis()) { MethodDefinition method = GetMethodDefinition(expr.Operand as MethodReference); if (method == null) - throw new YieldAnalysisFailedException(); + throw new SymbolicAnalysisFailedException(); Interval interval; if (method == disposeMethod) { // Explicit call to dispose is used for "yield break;" within the method. ILExpression br = body.ElementAtOrDefault(++pos) as ILExpression; if (br == null || !(br.Code == ILCode.Br || br.Code == ILCode.Leave) || br.Operand != returnFalseLabel) - throw new YieldAnalysisFailedException(); + throw new SymbolicAnalysisFailedException(); newBody.Add(MakeGoTo(returnFalseLabel)); } else if (finallyMethodToStateInterval.TryGetValue(method, out interval)) { // Call to Finally-method int index = stateChanges.FindIndex(ss => ss.NewState >= interval.Start && ss.NewState <= interval.End); if (index < 0) - throw new YieldAnalysisFailedException(); + throw new SymbolicAnalysisFailedException(); ILLabel label = new ILLabel(); label.Name = "JumpOutOfTryFinally" + interval.Start + "_" + interval.End; @@ -883,7 +556,7 @@ namespace ICSharpCode.Decompiler.ILAst if (pair.Value.Contains(state)) return MakeGoTo(pair.Key); } - throw new YieldAnalysisFailedException(); + throw new SymbolicAnalysisFailedException(); } ILBlock ConvertFinallyBlock(MethodDefinition finallyMethod) @@ -907,6 +580,11 @@ namespace ICSharpCode.Decompiler.ILAst #region TranslateFieldsToLocalAccess void TranslateFieldsToLocalAccess() + { + TranslateFieldsToLocalAccess(newBody, fieldToParameterMap); + } + + internal static void TranslateFieldsToLocalAccess(List newBody, Dictionary fieldToParameterMap) { var fieldToLocalMap = new DefaultDictionary(f => new ILVariable { Name = f.Name, Type = f.FieldType }); foreach (ILNode node in newBody) { diff --git a/src/Libraries/ICSharpCode.Decompiler/Properties/AssemblyInfo.cs b/src/Libraries/ICSharpCode.Decompiler/Properties/AssemblyInfo.cs index 9260b6ba55..818b72b10b 100644 --- a/src/Libraries/ICSharpCode.Decompiler/Properties/AssemblyInfo.cs +++ b/src/Libraries/ICSharpCode.Decompiler/Properties/AssemblyInfo.cs @@ -19,8 +19,8 @@ using System.Runtime.InteropServices; // If you need to expose a type to COM, use [ComVisible(true)] on that type. [assembly: ComVisible(false)] -[assembly: AssemblyVersion("2.0.0.1595")] -[assembly: AssemblyInformationalVersion("2.0.0.1595-5773d3d2")] +[assembly: AssemblyVersion("2.1.0.1603")] +[assembly: AssemblyInformationalVersion("2.1.0.1603-1170e2f8")] [assembly: NeutralResourcesLanguage("en-US")] [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2243:AttributeStringLiteralsShouldParseCorrectly", diff --git a/src/Libraries/ICSharpCode.Decompiler/Tests/Async.cs b/src/Libraries/ICSharpCode.Decompiler/Tests/Async.cs new file mode 100644 index 0000000000..ccd1222556 --- /dev/null +++ b/src/Libraries/ICSharpCode.Decompiler/Tests/Async.cs @@ -0,0 +1,144 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +#pragma warning disable 1998 +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; + +public class Async +{ + public async void SimpleVoidMethod() + { + Console.WriteLine("Before"); + await Task.Delay(TimeSpan.FromSeconds(1.0)); + Console.WriteLine("After"); + } + + public async void VoidMethodWithoutAwait() + { + Console.WriteLine("No Await"); + } + + public async Task SimpleVoidTaskMethod() + { + Console.WriteLine("Before"); + await Task.Delay(TimeSpan.FromSeconds(1.0)); + Console.WriteLine("After"); + } + + public async Task TaskMethodWithoutAwait() + { + Console.WriteLine("No Await"); + } + + public async Task SimpleBoolTaskMethod() + { + Console.WriteLine("Before"); + await Task.Delay(TimeSpan.FromSeconds(1.0)); + Console.WriteLine("After"); + return true; + } + + public async void TwoAwaitsWithDifferentAwaiterTypes() + { + Console.WriteLine("Before"); + if (await this.SimpleBoolTaskMethod()) + { + await Task.Delay(TimeSpan.FromSeconds(1.0)); + } + Console.WriteLine("After"); + } + + public async void StreamCopyTo(Stream destination, int bufferSize) + { + byte[] array = new byte[bufferSize]; + int count; + while ((count = await destination.ReadAsync(array, 0, array.Length)) != 0) + { + await destination.WriteAsync(array, 0, count); + } + } + + public async void StreamCopyToWithConfigureAwait(Stream destination, int bufferSize) + { + byte[] array = new byte[bufferSize]; + int count; + while ((count = await destination.ReadAsync(array, 0, array.Length).ConfigureAwait(false)) != 0) + { + await destination.WriteAsync(array, 0, count).ConfigureAwait(false); + } + } + + public async void AwaitInLoopCondition() + { + while (await this.SimpleBoolTaskMethod()) + { + Console.WriteLine("Body"); + } + } + + public async Task AwaitInForEach(IEnumerable> elements) + { + int num = 0; + foreach (Task current in elements) + { + num += await current; + } + return num; + } + + public async Task TaskMethodWithoutAwaitButWithExceptionHandling() + { + try + { + using (new StringWriter()) + { + Console.WriteLine("No Await"); + } + } + catch (Exception) + { + Console.WriteLine("Crash"); + } + } + + public async Task NestedAwait(Task> task) + { + return await(await task); + } + + public async Task AwaitWithStack(Task task) + { + Console.WriteLine("A", 1, await task); + } + + public async Task AwaitWithStack2(Task task) + { + if (await this.SimpleBoolTaskMethod()) + { + Console.WriteLine("A", 1, await task); + } + else + { + int num = 1; + Console.WriteLine("A", 1, num); + } + } +} diff --git a/src/Libraries/ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj b/src/Libraries/ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj index 52a4f950da..69598ac73f 100644 --- a/src/Libraries/ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj +++ b/src/Libraries/ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj @@ -7,7 +7,7 @@ Library ICSharpCode.Decompiler.Tests ICSharpCode.Decompiler.Tests - v4.0 + v4.5 Properties True False @@ -15,6 +15,7 @@ false False 67,169,1058,728,1720,649 + x86 @@ -62,6 +63,7 @@ + diff --git a/src/Libraries/ICSharpCode.Decompiler/Tests/PropertiesAndEvents.cs b/src/Libraries/ICSharpCode.Decompiler/Tests/PropertiesAndEvents.cs index bdc4f7dd1f..9b3d165893 100644 --- a/src/Libraries/ICSharpCode.Decompiler/Tests/PropertiesAndEvents.cs +++ b/src/Libraries/ICSharpCode.Decompiler/Tests/PropertiesAndEvents.cs @@ -24,7 +24,7 @@ public class PropertiesAndEvents public event EventHandler AutomaticEvent; [field: NonSerialized] - public event EventHandler AutomaticEventWithInitializer = delegate + public event EventHandler AutomaticEventWithInitializer = delegate(object sender, EventArgs e) { }; diff --git a/src/Libraries/ICSharpCode.Decompiler/Tests/TestRunner.cs b/src/Libraries/ICSharpCode.Decompiler/Tests/TestRunner.cs index 8160a7376d..52a03a4623 100644 --- a/src/Libraries/ICSharpCode.Decompiler/Tests/TestRunner.cs +++ b/src/Libraries/ICSharpCode.Decompiler/Tests/TestRunner.cs @@ -34,6 +34,12 @@ namespace ICSharpCode.Decompiler.Tests [TestFixture] public class TestRunner { + [Test] + public void Async() + { + TestFile(@"..\..\Tests\Async.cs"); + } + [Test, Ignore("disambiguating overloads is not yet implemented")] public void CallOverloadedMethod() { diff --git a/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/ExpressionFinder.atg b/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/ExpressionFinder.atg index 0f69a3e491..41512e9020 100644 --- a/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/ExpressionFinder.atg +++ b/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/ExpressionFinder.atg @@ -1137,10 +1137,19 @@ MultilineIfRemainder = SelectStatement = "Select" [ "Case" ] Expression StatementTerminator { - "Case" ( + // HACK: '<' is recognized as XML literal, if occurring at the start of an expression + // in the CaseClause however it can only be a less-than-sign and vbc does not allow XML literals. + // we use a simple xmlAllowed flag: + // the flag is only set to false immetiately before the expression is parsed and set to true once '<' + // is recognized as less-than-sign to allow normal behavior of the lexer in later expressions. + "Case" (. xmlAllowed = false; .) ( "Else" | - ( [ "Is" ] ComparisonOperator SimpleExpressionWithSuffix | Expression ) - { "," ( [ "Is" ] ComparisonOperator SimpleExpressionWithSuffix | Expression ) } + ( (. xmlAllowed = true; .) [ "Is" ] ComparisonOperator SimpleExpressionWithSuffix + | (. xmlAllowed = true; .) Expression ) + { "," (. xmlAllowed = false; .) + ( (. xmlAllowed = true; .) [ "Is" ] ComparisonOperator SimpleExpressionWithSuffix + | (. xmlAllowed = true; .) Expression ) + } ) StatementTerminatorAndBlock } diff --git a/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/ExpressionFinder.cs b/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/ExpressionFinder.cs index 4182966fdb..da283225ce 100644 --- a/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/ExpressionFinder.cs +++ b/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/ExpressionFinder.cs @@ -121,6 +121,10 @@ namespace ICSharpCode.NRefactory.Parser.VB set { readXmlIdentifier = value; } } + public bool XmlAllowed { + get { return xmlAllowed; } + } + public bool NextTokenIsStartOfImportsOrAccessExpression { get { return nextTokenIsStartOfImportsOrAccessExpression; } } diff --git a/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Lexer.cs b/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Lexer.cs index 68f5661460..cad5421a4f 100644 --- a/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Lexer.cs +++ b/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Lexer.cs @@ -317,7 +317,7 @@ namespace ICSharpCode.NRefactory.Parser.VB return new Token(Tokens.XmlEndInlineVB, new Location(x, y), new Location(Col, Line)); } #endregion - if (ch == '<' && (ef.NextTokenIsPotentialStartOfExpression || ef.NextTokenIsStartOfImportsOrAccessExpression)) { + if (ch == '<' && ef.XmlAllowed && (ef.NextTokenIsPotentialStartOfExpression || ef.NextTokenIsStartOfImportsOrAccessExpression)) { xmlModeStack.Push(new XmlModeInfo(ef.NextTokenIsStartOfImportsOrAccessExpression)); XmlModeInfo info = xmlModeStack.Peek(); int x = Col - 1; diff --git a/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Parser.cs b/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Parser.cs index a77878718f..cdced2c739 100644 --- a/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Parser.cs +++ b/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Parser.cs @@ -28,7 +28,8 @@ partial class ExpressionFinder { case 6: case 88: case 266: - case 534: + case 365: + case 537: { BitArray a = new BitArray(239); return a; @@ -52,24 +53,24 @@ partial class ExpressionFinder { case 244: case 248: case 297: - case 401: - case 407: - case 478: - case 524: - case 531: - case 539: - case 569: - case 605: - case 654: - case 668: - case 741: + case 404: + case 410: + case 481: + case 527: + case 534: + case 542: + case 572: + case 608: + case 657: + case 671: + case 744: return set[6]; case 12: case 13: - case 570: - case 571: - case 616: - case 626: + case 573: + case 574: + case 619: + case 629: { BitArray a = new BitArray(239); a.Set(1, true); @@ -93,31 +94,31 @@ partial class ExpressionFinder { case 353: case 359: case 364: - case 374: - case 375: - case 398: - case 425: - case 530: - case 536: - case 542: - case 546: - case 554: - case 562: - case 572: - case 581: - case 598: - case 603: - case 611: - case 617: + case 377: + case 378: + case 401: + case 428: + case 533: + case 539: + case 545: + case 549: + case 557: + case 565: + case 575: + case 584: + case 601: + case 606: + case 614: case 620: - case 627: + case 623: case 630: - case 649: + case 633: case 652: - case 676: - case 684: - case 720: - case 740: + case 655: + case 679: + case 687: + case 723: + case 743: { BitArray a = new BitArray(239); a.Set(1, true); @@ -135,23 +136,23 @@ partial class ExpressionFinder { case 273: case 300: case 354: - case 399: - case 458: - case 579: - case 599: - case 618: - case 622: - case 628: - case 650: - case 685: + case 402: + case 461: + case 582: + case 602: + case 621: + case 625: + case 631: + case 653: + case 688: { BitArray a = new BitArray(239); a.Set(113, true); return a; } case 22: - case 547: - case 582: + case 550: + case 585: return set[9]; case 25: { @@ -163,7 +164,7 @@ partial class ExpressionFinder { case 27: return set[10]; case 28: - case 724: + case 727: return set[11]; case 29: return set[12]; @@ -177,28 +178,28 @@ partial class ExpressionFinder { case 267: case 278: case 279: - case 466: - case 467: - case 468: case 469: - case 557: - case 558: - case 591: - case 592: - case 679: - case 680: - case 733: - case 734: + case 470: + case 471: + case 472: + case 560: + case 561: + case 594: + case 595: + case 682: + case 683: + case 736: + case 737: return set[14]; case 33: case 34: - case 525: - case 526: - case 532: - case 533: - case 559: - case 560: - case 673: + case 528: + case 529: + case 535: + case 536: + case 562: + case 563: + case 676: return set[15]; case 35: case 37: @@ -210,27 +211,27 @@ partial class ExpressionFinder { case 221: case 309: case 334: - case 424: - case 442: - case 453: - case 481: - case 535: - case 553: - case 561: - case 633: + case 427: + case 445: + case 456: + case 484: + case 538: + case 556: + case 564: case 636: - case 658: + case 639: case 661: - case 663: - case 675: - case 688: - case 690: - case 713: + case 664: + case 666: + case 678: + case 691: + case 693: case 716: case 719: - case 725: + case 722: case 728: - case 746: + case 731: + case 749: return set[16]; case 38: case 41: @@ -241,8 +242,8 @@ partial class ExpressionFinder { case 97: case 101: case 163: - case 390: - case 485: + case 393: + case 488: return set[19]; case 42: { @@ -260,17 +261,17 @@ partial class ExpressionFinder { case 46: case 167: case 188: - case 394: - case 429: - case 479: + case 397: + case 432: case 482: - case 502: - case 565: - case 596: - case 648: - case 694: - case 723: - case 732: + case 485: + case 505: + case 568: + case 599: + case 651: + case 697: + case 726: + case 735: { BitArray a = new BitArray(239); a.Set(38, true); @@ -282,7 +283,7 @@ partial class ExpressionFinder { case 49: case 179: case 186: - case 396: + case 399: { BitArray a = new BitArray(239); a.Set(22, true); @@ -292,36 +293,36 @@ partial class ExpressionFinder { case 51: case 52: case 54: - case 392: - case 393: - case 414: - case 415: - case 421: - case 422: - case 493: - case 494: - case 707: - case 708: + case 395: + case 396: + case 417: + case 418: + case 424: + case 425: + case 496: + case 497: + case 710: + case 711: return set[22]; case 53: case 169: case 170: case 172: case 181: - case 416: - case 423: - case 431: - case 440: - case 444: - case 489: + case 419: + case 426: + case 434: + case 443: + case 447: case 492: - case 496: - case 498: + case 495: case 499: - case 509: - case 516: - case 523: - case 709: + case 501: + case 502: + case 512: + case 519: + case 526: + case 712: { BitArray a = new BitArray(239); a.Set(22, true); @@ -359,20 +360,21 @@ partial class ExpressionFinder { case 352: case 358: case 369: - case 371: case 372: - case 378: - case 395: - case 397: - case 417: - case 441: - case 471: - case 487: - case 488: + case 374: + case 375: + case 381: + case 398: + case 400: + case 420: + case 444: + case 474: case 490: case 491: - case 552: - case 632: + case 493: + case 494: + case 555: + case 635: return set[23]; case 57: case 78: @@ -448,7 +450,7 @@ partial class ExpressionFinder { return a; } case 71: - case 445: + case 448: { BitArray a = new BitArray(239); a.Set(40, true); @@ -467,7 +469,7 @@ partial class ExpressionFinder { case 284: case 285: case 336: - case 742: + case 745: { BitArray a = new BitArray(239); a.Set(20, true); @@ -499,7 +501,7 @@ partial class ExpressionFinder { } case 84: case 100: - case 519: + case 522: { BitArray a = new BitArray(239); a.Set(22, true); @@ -546,7 +548,7 @@ partial class ExpressionFinder { return a; } case 96: - case 689: + case 692: { BitArray a = new BitArray(239); a.Set(26, true); @@ -603,8 +605,8 @@ partial class ExpressionFinder { return a; } case 111: - case 454: - case 459: + case 457: + case 462: { BitArray a = new BitArray(239); a.Set(210, true); @@ -636,8 +638,8 @@ partial class ExpressionFinder { return a; } case 116: - case 604: - case 623: + case 607: + case 626: { BitArray a = new BitArray(239); a.Set(186, true); @@ -759,7 +761,7 @@ partial class ExpressionFinder { return a; } case 135: - case 641: + case 644: { BitArray a = new BitArray(239); a.Set(98, true); @@ -838,8 +840,8 @@ partial class ExpressionFinder { return set[32]; case 161: case 162: - case 483: - case 484: + case 486: + case 487: return set[33]; case 164: return set[34]; @@ -850,10 +852,10 @@ partial class ExpressionFinder { return set[35]; case 175: case 253: - case 461: + case 464: return set[36]; case 176: - case 377: + case 380: { BitArray a = new BitArray(239); a.Set(135, true); @@ -863,13 +865,13 @@ partial class ExpressionFinder { case 184: case 189: case 255: - case 426: - case 455: - case 477: + case 429: + case 458: case 480: - case 593: - case 594: - case 646: + case 483: + case 596: + case 597: + case 649: { BitArray a = new BitArray(239); a.Set(37, true); @@ -975,10 +977,10 @@ partial class ExpressionFinder { case 245: return set[45]; case 252: - case 556: - case 667: - case 678: - case 686: + case 559: + case 670: + case 681: + case 689: { BitArray a = new BitArray(239); a.Set(127, true); @@ -997,21 +999,21 @@ partial class ExpressionFinder { return set[49]; case 269: case 270: - case 383: + case 386: return set[50]; case 272: case 277: - case 367: - case 659: - case 660: + case 366: case 662: - case 697: - case 714: - case 715: + case 663: + case 665: + case 700: case 717: - case 726: - case 727: + case 718: + case 720: case 729: + case 730: + case 732: { BitArray a = new BitArray(239); a.Set(1, true); @@ -1031,7 +1033,7 @@ partial class ExpressionFinder { case 287: case 329: case 344: - case 406: + case 409: return set[52]; case 290: case 291: @@ -1043,8 +1045,8 @@ partial class ExpressionFinder { case 342: return set[53]; case 292: - case 384: case 387: + case 390: { BitArray a = new BitArray(239); a.Set(1, true); @@ -1152,14 +1154,16 @@ partial class ExpressionFinder { case 362: case 363: return set[66]; - case 365: - case 366: - return set[67]; + case 367: case 368: + return set[67]; case 370: return set[68]; + case 371: case 373: - case 379: + return set[69]; + case 376: + case 382: { BitArray a = new BitArray(239); a.Set(1, true); @@ -1167,7 +1171,7 @@ partial class ExpressionFinder { a.Set(214, true); return a; } - case 376: + case 379: { BitArray a = new BitArray(239); a.Set(111, true); @@ -1175,7 +1179,7 @@ partial class ExpressionFinder { a.Set(113, true); return a; } - case 380: + case 383: { BitArray a = new BitArray(239); a.Set(1, true); @@ -1183,63 +1187,63 @@ partial class ExpressionFinder { a.Set(135, true); return a; } - case 381: - case 382: - case 456: - case 457: - return set[69]; + case 384: case 385: - case 386: + case 459: + case 460: + return set[70]; case 388: case 389: - return set[70]; case 391: + case 392: return set[71]; - case 400: + case 394: + return set[72]; + case 403: { BitArray a = new BitArray(239); a.Set(211, true); a.Set(233, true); return a; } - case 402: - case 403: - case 408: - case 409: - return set[72]; - case 404: - case 410: - return set[73]; case 405: - case 413: - case 420: - return set[74]; + case 406: case 411: case 412: - case 418: - case 419: - case 704: - case 705: + return set[73]; + case 407: + case 413: + return set[74]; + case 408: + case 416: + case 423: return set[75]; - case 427: - case 428: + case 414: + case 415: + case 421: + case 422: + case 707: + case 708: return set[76]; case 430: - case 432: - case 433: - case 595: - case 647: + case 431: return set[77]; - case 434: + case 433: case 435: - return set[78]; case 436: + case 598: + case 650: + return set[78]; case 437: - return set[79]; case 438: - return set[80]; + return set[79]; case 439: - case 443: + case 440: + return set[80]; + case 441: + return set[81]; + case 442: + case 446: { BitArray a = new BitArray(239); a.Set(20, true); @@ -1247,87 +1251,87 @@ partial class ExpressionFinder { a.Set(38, true); return a; } - case 446: - case 447: + case 449: + case 450: + case 454: + return set[82]; case 451: - return set[81]; - case 448: { BitArray a = new BitArray(239); a.Set(22, true); a.Set(39, true); return a; } - case 449: - case 450: - return set[82]; case 452: + case 453: + return set[83]; + case 455: { BitArray a = new BitArray(239); a.Set(21, true); return a; } - case 460: - return set[83]; - case 462: - case 475: - return set[84]; case 463: - case 476: - return set[85]; - case 464: + return set[84]; case 465: + case 478: + return set[85]; + case 466: + case 479: + return set[86]; + case 467: + case 468: { BitArray a = new BitArray(239); a.Set(10, true); return a; } - case 470: + case 473: { BitArray a = new BitArray(239); a.Set(12, true); return a; } - case 472: + case 475: { BitArray a = new BitArray(239); a.Set(13, true); return a; } - case 473: - return set[86]; - case 474: + case 476: return set[87]; - case 486: + case 477: return set[88]; - case 495: - case 497: + case 489: return set[89]; + case 498: case 500: - case 501: - case 563: - case 564: - case 692: - case 693: return set[90]; case 503: case 504: - case 505: - case 510: - case 511: case 566: + case 567: case 695: - case 722: - case 731: + case 696: return set[91]; case 506: - case 512: - case 521: - return set[92]; case 507: case 508: case 513: case 514: + case 569: + case 698: + case 725: + case 734: + return set[92]; + case 509: + case 515: + case 524: + return set[93]; + case 510: + case 511: + case 516: + case 517: { BitArray a = new BitArray(239); a.Set(22, true); @@ -1335,18 +1339,18 @@ partial class ExpressionFinder { a.Set(63, true); return a; } - case 515: - case 517: - case 522: - return set[93]; case 518: case 520: + case 525: return set[94]; - case 527: - case 540: - case 541: - case 597: - case 674: + case 521: + case 523: + return set[95]; + case 530: + case 543: + case 544: + case 600: + case 677: { BitArray a = new BitArray(239); a.Set(1, true); @@ -1354,28 +1358,28 @@ partial class ExpressionFinder { a.Set(63, true); return a; } - case 528: - case 529: - case 601: - case 602: - return set[95]; - case 537: - case 538: - case 545: + case 531: + case 532: + case 604: + case 605: + return set[96]; + case 540: + case 541: + case 548: { BitArray a = new BitArray(239); a.Set(115, true); return a; } - case 543: - case 544: - return set[96]; - case 548: - case 549: + case 546: + case 547: return set[97]; - case 550: case 551: - case 610: + case 552: + return set[98]; + case 553: + case 554: + case 613: { BitArray a = new BitArray(239); a.Set(1, true); @@ -1383,15 +1387,15 @@ partial class ExpressionFinder { a.Set(21, true); return a; } - case 555: + case 558: { BitArray a = new BitArray(239); a.Set(103, true); return a; } - case 567: - case 568: - case 580: + case 570: + case 571: + case 583: { BitArray a = new BitArray(239); a.Set(84, true); @@ -1399,84 +1403,84 @@ partial class ExpressionFinder { a.Set(209, true); return a; } - case 573: - case 574: - return set[98]; - case 575: case 576: - return set[99]; case 577: + return set[99]; case 578: - case 589: + case 579: return set[100]; - case 583: - case 584: + case 580: + case 581: + case 592: return set[101]; - case 585: case 586: - case 711: - return set[102]; case 587: - return set[103]; + return set[102]; case 588: - return set[104]; + case 589: + case 714: + return set[103]; case 590: - case 600: + return set[104]; + case 591: + return set[105]; + case 593: + case 603: { BitArray a = new BitArray(239); a.Set(172, true); return a; } - case 606: - case 607: - return set[105]; - case 608: - return set[106]; case 609: - case 640: + case 610: + return set[106]; + case 611: return set[107]; case 612: - case 613: - case 614: - case 631: + case 643: return set[108]; case 615: - case 619: - case 629: + case 616: + case 617: + case 634: + return set[109]; + case 618: + case 622: + case 632: { BitArray a = new BitArray(239); a.Set(128, true); a.Set(198, true); return a; } - case 621: - return set[109]; case 624: return set[110]; - case 625: + case 627: return set[111]; - case 634: - case 635: - case 637: - case 703: - case 706: + case 628: return set[112]; + case 637: case 638: - case 639: + case 640: + case 706: + case 709: return set[113]; + case 641: case 642: - case 644: - case 653: + return set[114]; + case 645: + case 647: + case 656: { BitArray a = new BitArray(239); a.Set(119, true); return a; } - case 643: - return set[114]; - case 645: + case 646: return set[115]; - case 651: + case 648: + return set[116]; + case 654: { BitArray a = new BitArray(239); a.Set(56, true); @@ -1484,11 +1488,11 @@ partial class ExpressionFinder { a.Set(193, true); return a; } - case 655: - case 656: - return set[116]; - case 657: - case 664: + case 658: + case 659: + return set[117]; + case 660: + case 667: { BitArray a = new BitArray(239); a.Set(1, true); @@ -1496,111 +1500,111 @@ partial class ExpressionFinder { a.Set(136, true); return a; } - case 665: + case 668: { BitArray a = new BitArray(239); a.Set(101, true); return a; } - case 666: - return set[117]; case 669: - case 670: + return set[118]; + case 672: + case 673: { BitArray a = new BitArray(239); a.Set(149, true); return a; } - case 671: - case 677: - case 743: + case 674: + case 680: + case 746: { BitArray a = new BitArray(239); a.Set(3, true); return a; } - case 672: - return set[118]; - case 681: - case 682: + case 675: return set[119]; - case 683: - case 691: + case 684: + case 685: return set[120]; - case 687: + case 686: + case 694: return set[121]; - case 696: - case 698: + case 690: return set[122]; case 699: - case 710: - return set[123]; - case 700: case 701: - return set[124]; + return set[123]; case 702: + case 713: + return set[124]; + case 703: + case 704: return set[125]; - case 712: + case 705: + return set[126]; + case 715: { BitArray a = new BitArray(239); a.Set(136, true); return a; } - case 718: + case 721: { BitArray a = new BitArray(239); a.Set(140, true); return a; } - case 721: - case 730: + case 724: + case 733: { BitArray a = new BitArray(239); a.Set(169, true); return a; } - case 735: - return set[126]; - case 736: + case 738: + return set[127]; + case 739: { BitArray a = new BitArray(239); a.Set(160, true); return a; } - case 737: + case 740: { BitArray a = new BitArray(239); a.Set(137, true); return a; } - case 738: - case 739: - return set[127]; - case 744: + case 741: + case 742: + return set[128]; + case 747: { BitArray a = new BitArray(239); a.Set(11, true); return a; } - case 745: - return set[128]; - case 747: + case 748: + return set[129]; + case 750: { BitArray a = new BitArray(239); a.Set(173, true); return a; } - case 748: - return set[129]; - case 749: + case 751: + return set[130]; + case 752: { BitArray a = new BitArray(239); a.Set(67, true); a.Set(213, true); return a; - } - case 750: - return set[130]; + } + case 753: + return set[131]; default: throw new InvalidOperationException(); } } @@ -1614,6 +1618,7 @@ partial class ExpressionFinder { bool wasQualifierTokenAtStart = false; bool nextTokenIsPotentialStartOfExpression = false; bool readXmlIdentifier = false; + bool xmlAllowed = true; bool identifierExpected = false; bool nextTokenIsStartOfImportsOrAccessExpression = false; bool isMissingModifier = false; @@ -1657,7 +1662,7 @@ partial class ExpressionFinder { if (la == null) { currentState = 1; break; } if (la.kind == 173) { stateStack.Push(1); - goto case 747; + goto case 750; } else { goto case 2; } @@ -1666,7 +1671,7 @@ partial class ExpressionFinder { if (la == null) { currentState = 2; break; } if (la.kind == 137) { stateStack.Push(2); - goto case 737; + goto case 740; } else { goto case 3; } @@ -1675,7 +1680,7 @@ partial class ExpressionFinder { if (la == null) { currentState = 3; break; } if (la.kind == 40) { stateStack.Push(3); - goto case 445; + goto case 448; } else { goto case 4; } @@ -1694,7 +1699,7 @@ partial class ExpressionFinder { case 5: { if (la == null) { currentState = 5; break; } if (la.kind == 160) { - currentState = 733; + currentState = 736; break; } else { if (set[4].Get(la.kind)) { @@ -1713,26 +1718,26 @@ partial class ExpressionFinder { if (la == null) { currentState = 7; break; } if (la.kind == 40) { stateStack.Push(7); - goto case 445; + goto case 448; } else { goto case 8; } } case 8: { if (la == null) { currentState = 8; break; } - if (set[131].Get(la.kind)) { + if (set[132].Get(la.kind)) { currentState = 8; break; } else { if (la.kind == 84 || la.kind == 155 || la.kind == 209) { - goto case 567; + goto case 570; } else { if (la.kind == 103) { - currentState = 556; + currentState = 559; break; } else { if (la.kind == 115) { - goto case 537; + goto case 540; } else { if (la.kind == 142) { goto case 9; @@ -1767,7 +1772,7 @@ partial class ExpressionFinder { case 13: { if (la == null) { currentState = 13; break; } if (la.kind == 37) { - currentState = 730; + currentState = 733; break; } else { goto case 14; @@ -1784,7 +1789,7 @@ partial class ExpressionFinder { case 16: { if (la == null) { currentState = 16; break; } if (la.kind == 140) { - currentState = 725; + currentState = 728; break; } else { goto case 17; @@ -1854,7 +1859,7 @@ partial class ExpressionFinder { if (la == null) { currentState = 27; break; } if (la.kind == 40) { stateStack.Push(26); - goto case 445; + goto case 448; } else { isMissingModifier = true; goto case 28; @@ -1862,8 +1867,8 @@ partial class ExpressionFinder { } case 28: { if (la == null) { currentState = 28; break; } - if (set[132].Get(la.kind)) { - currentState = 724; + if (set[133].Get(la.kind)) { + currentState = 727; break; } else { isMissingModifier = false; @@ -1874,15 +1879,15 @@ partial class ExpressionFinder { if (la == null) { currentState = 29; break; } if (la.kind == 84 || la.kind == 155 || la.kind == 209) { stateStack.Push(17); - goto case 567; + goto case 570; } else { if (la.kind == 103) { stateStack.Push(17); - goto case 555; + goto case 558; } else { if (la.kind == 115) { stateStack.Push(17); - goto case 537; + goto case 540; } else { if (la.kind == 142) { stateStack.Push(17); @@ -1903,11 +1908,11 @@ partial class ExpressionFinder { case 30: { if (la == null) { currentState = 30; break; } if (la.kind == 119) { - currentState = 531; + currentState = 534; break; } else { if (la.kind == 186) { - currentState = 524; + currentState = 527; break; } else { if (la.kind == 127 || la.kind == 210) { @@ -1936,7 +1941,7 @@ partial class ExpressionFinder { case 34: { if (la == null) { currentState = 34; break; } if (la.kind == 37) { - currentState = 500; + currentState = 503; break; } else { if (la.kind == 63) { @@ -1966,7 +1971,7 @@ partial class ExpressionFinder { currentState = 38; break; } else { - if (set[133].Get(la.kind)) { + if (set[134].Get(la.kind)) { currentState = 38; break; } else { @@ -2035,7 +2040,7 @@ partial class ExpressionFinder { case 44: { if (la == null) { currentState = 44; break; } if (la.kind == 169) { - currentState = 495; + currentState = 498; break; } else { if (set[22].Get(la.kind)) { @@ -2069,7 +2074,7 @@ partial class ExpressionFinder { if (la == null) { currentState = 48; break; } if (set[23].Get(la.kind)) { activeArgument = 0; - goto case 491; + goto case 494; } else { if (la.kind == 22) { activeArgument = 0; @@ -2389,7 +2394,7 @@ partial class ExpressionFinder { } case 77: { if (la == null) { currentState = 77; break; } - if (set[134].Get(la.kind)) { + if (set[135].Get(la.kind)) { currentState = 76; break; } else { @@ -3752,7 +3757,7 @@ partial class ExpressionFinder { currentState = 165; break; } else { - if (set[135].Get(la.kind)) { + if (set[136].Get(la.kind)) { currentState = 161; break; } else { @@ -3849,39 +3854,39 @@ partial class ExpressionFinder { } case 174: { if (la == null) { currentState = 174; break; } - if (set[136].Get(la.kind)) { + if (set[137].Get(la.kind)) { currentState = 175; break; } else { if (la.kind == 37) { - currentState = 487; + currentState = 490; break; } else { - if (set[137].Get(la.kind)) { + if (set[138].Get(la.kind)) { currentState = 175; break; } else { - if (set[133].Get(la.kind)) { + if (set[134].Get(la.kind)) { currentState = 175; break; } else { - if (set[135].Get(la.kind)) { - currentState = 483; + if (set[136].Get(la.kind)) { + currentState = 486; break; } else { if (la.kind == 129) { - currentState = 480; + currentState = 483; break; } else { if (la.kind == 237) { - currentState = 477; + currentState = 480; break; } else { - if (set[83].Get(la.kind)) { + if (set[84].Get(la.kind)) { stateStack.Push(175); nextTokenIsPotentialStartOfExpression = true; PushContext(Context.Xml, la, t); - goto case 460; + goto case 463; } else { if (la.kind == 127 || la.kind == 210) { stateStack.Push(175); @@ -3962,7 +3967,7 @@ partial class ExpressionFinder { } case 183: { if (la == null) { currentState = 183; break; } - if (set[138].Get(la.kind)) { + if (set[139].Get(la.kind)) { currentState = 189; break; } else { @@ -4154,7 +4159,7 @@ partial class ExpressionFinder { } case 205: { if (la == null) { currentState = 205; break; } - if (set[123].Get(la.kind)) { + if (set[124].Get(la.kind)) { currentState = stateStack.Pop(); break; } else { @@ -4512,7 +4517,7 @@ partial class ExpressionFinder { if (la == null) { currentState = 252; break; } if (la.kind == 210) { stateStack.Push(253); - goto case 454; + goto case 457; } else { if (la.kind == 127) { stateStack.Push(253); @@ -4536,7 +4541,7 @@ partial class ExpressionFinder { } case 255: { stateStack.Push(256); - goto case 426; + goto case 429; } case 256: { nextTokenIsPotentialStartOfExpression = true; @@ -4549,7 +4554,7 @@ partial class ExpressionFinder { } else { if (la.kind == 1 || la.kind == 21 || la.kind == 63) { if (la.kind == 63) { - currentState = 424; + currentState = 427; break; } else { goto case 258; @@ -4589,8 +4594,8 @@ partial class ExpressionFinder { } case 264: { if (la == null) { currentState = 264; break; } - if (set[139].Get(la.kind)) { - if (set[69].Get(la.kind)) { + if (set[140].Get(la.kind)) { + if (set[70].Get(la.kind)) { if (set[50].Get(la.kind)) { stateStack.Push(262); goto case 269; @@ -4646,23 +4651,23 @@ partial class ExpressionFinder { case 270: { if (la == null) { currentState = 270; break; } if (la.kind == 88 || la.kind == 105 || la.kind == 204) { - currentState = 401; + currentState = 404; break; } else { if (la.kind == 211 || la.kind == 233) { - currentState = 397; + currentState = 400; break; } else { if (la.kind == 56 || la.kind == 193) { - currentState = 395; + currentState = 398; break; } else { if (la.kind == 189) { - currentState = 390; + currentState = 393; break; } else { if (la.kind == 135) { - currentState = 372; + currentState = 375; break; } else { if (la.kind == 197) { @@ -4706,7 +4711,7 @@ partial class ExpressionFinder { currentState = 298; break; } else { - if (set[140].Get(la.kind)) { + if (set[141].Get(la.kind)) { if (la.kind == 132) { currentState = 295; break; @@ -4745,7 +4750,7 @@ partial class ExpressionFinder { currentState = 271; break; } else { - if (set[141].Get(la.kind)) { + if (set[142].Get(la.kind)) { if (la.kind == 73) { currentState = 55; break; @@ -5433,6 +5438,7 @@ partial class ExpressionFinder { break; } case 362: { + xmlAllowed = false; nextTokenIsPotentialStartOfExpression = true; goto case 363; } @@ -5443,7 +5449,17 @@ partial class ExpressionFinder { break; } else { if (set[67].Get(la.kind)) { - goto case 365; + if (set[68].Get(la.kind)) { + xmlAllowed = true; + goto case 370; + } else { + if (set[23].Get(la.kind)) { + xmlAllowed = true; + goto case 369; + } else { + goto case 365; + } + } } else { Error(la); goto case 364; @@ -5455,47 +5471,60 @@ partial class ExpressionFinder { goto case 261; } case 365: { - nextTokenIsPotentialStartOfExpression = true; + Error(la); goto case 366; } case 366: { if (la == null) { currentState = 366; break; } - if (set[142].Get(la.kind)) { - if (la.kind == 144) { - currentState = 368; - break; - } else { - goto case 368; - } + if (la.kind == 22) { + currentState = 367; + break; + } else { + goto case 364; + } + } + case 367: { + xmlAllowed = false; + nextTokenIsPotentialStartOfExpression = true; + goto case 368; + } + case 368: { + if (la == null) { currentState = 368; break; } + if (set[68].Get(la.kind)) { + xmlAllowed = true; + goto case 370; } else { if (set[23].Get(la.kind)) { - stateStack.Push(367); - goto case 55; + xmlAllowed = true; + goto case 369; } else { - Error(la); - goto case 367; + goto case 365; } } } - case 367: { - if (la == null) { currentState = 367; break; } - if (la.kind == 22) { - currentState = 365; + case 369: { + stateStack.Push(366); + goto case 55; + } + case 370: { + if (la == null) { currentState = 370; break; } + if (la.kind == 144) { + currentState = 371; break; } else { - goto case 364; + goto case 371; } } - case 368: { - stateStack.Push(369); - goto case 370; + case 371: { + stateStack.Push(372); + goto case 373; } - case 369: { - stateStack.Push(367); + case 372: { + stateStack.Push(366); goto case 75; } - case 370: { - if (la == null) { currentState = 370; break; } + case 373: { + if (la == null) { currentState = 373; break; } if (la.kind == 20) { goto case 73; } else { @@ -5506,7 +5535,7 @@ partial class ExpressionFinder { goto case 71; } else { if (la.kind == 39) { - currentState = 371; + currentState = 374; break; } else { if (la.kind == 42) { @@ -5523,109 +5552,109 @@ partial class ExpressionFinder { } } } - case 371: { + case 374: { wasNormalAttribute = false; currentState = stateStack.Pop(); goto switchlbl; } - case 372: { - stateStack.Push(373); + case 375: { + stateStack.Push(376); goto case 55; } - case 373: { - if (la == null) { currentState = 373; break; } + case 376: { + if (la == null) { currentState = 376; break; } if (la.kind == 214) { - currentState = 381; + currentState = 384; break; } else { - goto case 374; + goto case 377; } } - case 374: { - if (la == null) { currentState = 374; break; } + case 377: { + if (la == null) { currentState = 377; break; } if (la.kind == 1 || la.kind == 21) { - goto case 375; + goto case 378; } else { goto case 6; } } - case 375: { - stateStack.Push(376); + case 378: { + stateStack.Push(379); goto case 261; } - case 376: { - if (la == null) { currentState = 376; break; } + case 379: { + if (la == null) { currentState = 379; break; } if (la.kind == 111 || la.kind == 112) { if (la.kind == 111) { - currentState = 380; + currentState = 383; break; } else { if (la.kind == 112) { - currentState = 378; + currentState = 381; break; } else { Error(la); - goto case 375; + goto case 378; } } } else { Expect(113, la); // "End" - currentState = 377; + currentState = 380; break; } } - case 377: { - if (la == null) { currentState = 377; break; } + case 380: { + if (la == null) { currentState = 380; break; } Expect(135, la); // "If" currentState = stateStack.Pop(); break; } - case 378: { - stateStack.Push(379); + case 381: { + stateStack.Push(382); goto case 55; } - case 379: { - if (la == null) { currentState = 379; break; } + case 382: { + if (la == null) { currentState = 382; break; } if (la.kind == 214) { - currentState = 375; + currentState = 378; break; } else { - goto case 375; + goto case 378; } } - case 380: { - if (la == null) { currentState = 380; break; } + case 383: { + if (la == null) { currentState = 383; break; } if (la.kind == 135) { - currentState = 378; + currentState = 381; break; } else { - goto case 375; + goto case 378; } } - case 381: { + case 384: { nextTokenIsPotentialStartOfExpression = true; - goto case 382; + goto case 385; } - case 382: { - if (la == null) { currentState = 382; break; } + case 385: { + if (la == null) { currentState = 385; break; } if (set[50].Get(la.kind)) { - goto case 383; + goto case 386; } else { - goto case 374; + goto case 377; } } - case 383: { - stateStack.Push(384); + case 386: { + stateStack.Push(387); goto case 269; } - case 384: { - if (la == null) { currentState = 384; break; } + case 387: { + if (la == null) { currentState = 387; break; } if (la.kind == 21) { - currentState = 388; + currentState = 391; break; } else { if (la.kind == 111) { - currentState = 385; + currentState = 388; break; } else { currentState = stateStack.Pop(); @@ -5633,99 +5662,99 @@ partial class ExpressionFinder { } } } - case 385: { + case 388: { nextTokenIsPotentialStartOfExpression = true; - goto case 386; + goto case 389; } - case 386: { - if (la == null) { currentState = 386; break; } + case 389: { + if (la == null) { currentState = 389; break; } if (set[50].Get(la.kind)) { - stateStack.Push(387); + stateStack.Push(390); goto case 269; } else { - goto case 387; + goto case 390; } } - case 387: { - if (la == null) { currentState = 387; break; } + case 390: { + if (la == null) { currentState = 390; break; } if (la.kind == 21) { - currentState = 385; + currentState = 388; break; } else { currentState = stateStack.Pop(); goto switchlbl; } } - case 388: { + case 391: { nextTokenIsPotentialStartOfExpression = true; - goto case 389; + goto case 392; } - case 389: { - if (la == null) { currentState = 389; break; } + case 392: { + if (la == null) { currentState = 392; break; } if (set[50].Get(la.kind)) { - goto case 383; + goto case 386; } else { - goto case 384; + goto case 387; } } - case 390: { - stateStack.Push(391); + case 393: { + stateStack.Push(394); goto case 101; } - case 391: { - if (la == null) { currentState = 391; break; } + case 394: { + if (la == null) { currentState = 394; break; } if (la.kind == 37) { - currentState = 392; + currentState = 395; break; } else { currentState = stateStack.Pop(); goto switchlbl; } } - case 392: { + case 395: { PushContext(Context.Expression, la, t); nextTokenIsPotentialStartOfExpression = true; - goto case 393; + goto case 396; } - case 393: { - if (la == null) { currentState = 393; break; } + case 396: { + if (la == null) { currentState = 396; break; } if (set[21].Get(la.kind)) { - stateStack.Push(394); + stateStack.Push(397); goto case 47; } else { - goto case 394; + goto case 397; } } - case 394: { + case 397: { PopContext(); goto case 46; } - case 395: { - stateStack.Push(396); + case 398: { + stateStack.Push(399); goto case 55; } - case 396: { - if (la == null) { currentState = 396; break; } + case 399: { + if (la == null) { currentState = 399; break; } Expect(22, la); // "," currentState = 55; break; } - case 397: { - stateStack.Push(398); + case 400: { + stateStack.Push(401); goto case 55; } - case 398: { - stateStack.Push(399); + case 401: { + stateStack.Push(402); goto case 261; } - case 399: { - if (la == null) { currentState = 399; break; } + case 402: { + if (la == null) { currentState = 402; break; } Expect(113, la); // "End" - currentState = 400; + currentState = 403; break; } - case 400: { - if (la == null) { currentState = 400; break; } + case 403: { + if (la == null) { currentState = 403; break; } if (la.kind == 233) { goto case 102; } else { @@ -5736,362 +5765,362 @@ partial class ExpressionFinder { } } } - case 401: { + case 404: { PushContext(Context.Identifier, la, t); SetIdentifierExpected(la); - stateStack.Push(402); + stateStack.Push(405); goto case 205; } - case 402: { + case 405: { PopContext(); - goto case 403; + goto case 406; } - case 403: { - if (la == null) { currentState = 403; break; } + case 406: { + if (la == null) { currentState = 406; break; } if (la.kind == 33) { - currentState = 404; + currentState = 407; break; } else { - goto case 404; + goto case 407; } } - case 404: { - if (la == null) { currentState = 404; break; } + case 407: { + if (la == null) { currentState = 407; break; } if (la.kind == 37) { - currentState = 421; + currentState = 424; break; } else { if (la.kind == 63) { - currentState = 418; + currentState = 421; break; } else { - goto case 405; + goto case 408; } } } - case 405: { - if (la == null) { currentState = 405; break; } + case 408: { + if (la == null) { currentState = 408; break; } if (la.kind == 20) { - currentState = 417; + currentState = 420; break; } else { - goto case 406; + goto case 409; } } - case 406: { - if (la == null) { currentState = 406; break; } + case 409: { + if (la == null) { currentState = 409; break; } if (la.kind == 22) { - currentState = 407; + currentState = 410; break; } else { currentState = stateStack.Pop(); goto switchlbl; } } - case 407: { + case 410: { PushContext(Context.Identifier, la, t); SetIdentifierExpected(la); - stateStack.Push(408); + stateStack.Push(411); goto case 205; } - case 408: { + case 411: { PopContext(); - goto case 409; + goto case 412; } - case 409: { - if (la == null) { currentState = 409; break; } + case 412: { + if (la == null) { currentState = 412; break; } if (la.kind == 33) { - currentState = 410; + currentState = 413; break; } else { - goto case 410; + goto case 413; } } - case 410: { - if (la == null) { currentState = 410; break; } + case 413: { + if (la == null) { currentState = 413; break; } if (la.kind == 37) { - currentState = 414; + currentState = 417; break; } else { if (la.kind == 63) { - currentState = 411; + currentState = 414; break; } else { - goto case 405; + goto case 408; } } } - case 411: { + case 414: { PushContext(Context.Type, la, t); - goto case 412; + goto case 415; } - case 412: { - if (la == null) { currentState = 412; break; } + case 415: { + if (la == null) { currentState = 415; break; } if (la.kind == 162) { - stateStack.Push(413); + stateStack.Push(416); goto case 85; } else { if (set[16].Get(la.kind)) { - stateStack.Push(413); + stateStack.Push(416); goto case 37; } else { Error(la); - goto case 413; + goto case 416; } } } - case 413: { + case 416: { PopContext(); - goto case 405; + goto case 408; } - case 414: { + case 417: { nextTokenIsPotentialStartOfExpression = true; - goto case 415; + goto case 418; } - case 415: { - if (la == null) { currentState = 415; break; } + case 418: { + if (la == null) { currentState = 418; break; } if (set[23].Get(la.kind)) { - stateStack.Push(416); + stateStack.Push(419); goto case 55; } else { - goto case 416; + goto case 419; } } - case 416: { - if (la == null) { currentState = 416; break; } + case 419: { + if (la == null) { currentState = 419; break; } if (la.kind == 22) { - currentState = 414; + currentState = 417; break; } else { Expect(38, la); // ")" - currentState = 410; + currentState = 413; break; } } - case 417: { - stateStack.Push(406); + case 420: { + stateStack.Push(409); goto case 55; } - case 418: { + case 421: { PushContext(Context.Type, la, t); - goto case 419; + goto case 422; } - case 419: { - if (la == null) { currentState = 419; break; } + case 422: { + if (la == null) { currentState = 422; break; } if (la.kind == 162) { - stateStack.Push(420); + stateStack.Push(423); goto case 85; } else { if (set[16].Get(la.kind)) { - stateStack.Push(420); + stateStack.Push(423); goto case 37; } else { Error(la); - goto case 420; + goto case 423; } } } - case 420: { + case 423: { PopContext(); - goto case 405; + goto case 408; } - case 421: { + case 424: { nextTokenIsPotentialStartOfExpression = true; - goto case 422; + goto case 425; } - case 422: { - if (la == null) { currentState = 422; break; } + case 425: { + if (la == null) { currentState = 425; break; } if (set[23].Get(la.kind)) { - stateStack.Push(423); + stateStack.Push(426); goto case 55; } else { - goto case 423; + goto case 426; } } - case 423: { - if (la == null) { currentState = 423; break; } + case 426: { + if (la == null) { currentState = 426; break; } if (la.kind == 22) { - currentState = 421; + currentState = 424; break; } else { Expect(38, la); // ")" - currentState = 404; + currentState = 407; break; } } - case 424: { + case 427: { PushContext(Context.Type, la, t); - stateStack.Push(425); + stateStack.Push(428); goto case 37; } - case 425: { + case 428: { PopContext(); goto case 258; } - case 426: { - if (la == null) { currentState = 426; break; } + case 429: { + if (la == null) { currentState = 429; break; } Expect(37, la); // "(" - currentState = 427; + currentState = 430; break; } - case 427: { + case 430: { PushContext(Context.Default, la, t); SetIdentifierExpected(la); - goto case 428; + goto case 431; } - case 428: { - if (la == null) { currentState = 428; break; } - if (set[77].Get(la.kind)) { - stateStack.Push(429); - goto case 430; + case 431: { + if (la == null) { currentState = 431; break; } + if (set[78].Get(la.kind)) { + stateStack.Push(432); + goto case 433; } else { - goto case 429; + goto case 432; } } - case 429: { + case 432: { PopContext(); goto case 46; } - case 430: { - stateStack.Push(431); + case 433: { + stateStack.Push(434); PushContext(Context.Parameter, la, t); - goto case 432; + goto case 435; } - case 431: { - if (la == null) { currentState = 431; break; } + case 434: { + if (la == null) { currentState = 434; break; } if (la.kind == 22) { - currentState = 430; + currentState = 433; break; } else { currentState = stateStack.Pop(); goto switchlbl; } } - case 432: { + case 435: { SetIdentifierExpected(la); - goto case 433; + goto case 436; } - case 433: { - if (la == null) { currentState = 433; break; } + case 436: { + if (la == null) { currentState = 436; break; } if (la.kind == 40) { - stateStack.Push(432); - goto case 445; + stateStack.Push(435); + goto case 448; } else { - goto case 434; + goto case 437; } } - case 434: { + case 437: { SetIdentifierExpected(la); - goto case 435; + goto case 438; } - case 435: { - if (la == null) { currentState = 435; break; } + case 438: { + if (la == null) { currentState = 438; break; } if (set[143].Get(la.kind)) { - currentState = 434; + currentState = 437; break; } else { PushContext(Context.Identifier, la, t); SetIdentifierExpected(la); - stateStack.Push(436); + stateStack.Push(439); goto case 205; } } - case 436: { + case 439: { PopContext(); - goto case 437; + goto case 440; } - case 437: { - if (la == null) { currentState = 437; break; } + case 440: { + if (la == null) { currentState = 440; break; } if (la.kind == 33) { - currentState = 438; + currentState = 441; break; } else { - goto case 438; + goto case 441; } } - case 438: { - if (la == null) { currentState = 438; break; } + case 441: { + if (la == null) { currentState = 441; break; } if (la.kind == 37) { - currentState = 444; + currentState = 447; break; } else { if (la.kind == 63) { - currentState = 442; + currentState = 445; break; } else { - goto case 439; + goto case 442; } } } - case 439: { - if (la == null) { currentState = 439; break; } + case 442: { + if (la == null) { currentState = 442; break; } if (la.kind == 20) { - currentState = 441; + currentState = 444; break; } else { - goto case 440; + goto case 443; } } - case 440: { + case 443: { PopContext(); currentState = stateStack.Pop(); goto switchlbl; } - case 441: { - stateStack.Push(440); + case 444: { + stateStack.Push(443); goto case 55; } - case 442: { + case 445: { PushContext(Context.Type, la, t); - stateStack.Push(443); + stateStack.Push(446); goto case 37; } - case 443: { + case 446: { PopContext(); - goto case 439; + goto case 442; } - case 444: { - if (la == null) { currentState = 444; break; } + case 447: { + if (la == null) { currentState = 447; break; } if (la.kind == 22) { - currentState = 444; + currentState = 447; break; } else { Expect(38, la); // ")" - currentState = 438; + currentState = 441; break; } } - case 445: { - if (la == null) { currentState = 445; break; } + case 448: { + if (la == null) { currentState = 448; break; } Expect(40, la); // "<" - currentState = 446; + currentState = 449; break; } - case 446: { + case 449: { wasNormalAttribute = true; PushContext(Context.Attribute, la, t); - goto case 447; + goto case 450; } - case 447: { - stateStack.Push(448); - goto case 451; + case 450: { + stateStack.Push(451); + goto case 454; } - case 448: { - if (la == null) { currentState = 448; break; } + case 451: { + if (la == null) { currentState = 451; break; } if (la.kind == 22) { - currentState = 447; + currentState = 450; break; } else { Expect(39, la); // ">" - currentState = 449; + currentState = 452; break; } } - case 449: { + case 452: { PopContext(); - goto case 450; + goto case 453; } - case 450: { - if (la == null) { currentState = 450; break; } + case 453: { + if (la == null) { currentState = 453; break; } if (la.kind == 1) { goto case 25; } else { @@ -6099,302 +6128,302 @@ partial class ExpressionFinder { goto switchlbl; } } - case 451: { - if (la == null) { currentState = 451; break; } + case 454: { + if (la == null) { currentState = 454; break; } if (la.kind == 65 || la.kind == 155) { - currentState = 452; + currentState = 455; break; } else { goto case 37; } } - case 452: { - if (la == null) { currentState = 452; break; } + case 455: { + if (la == null) { currentState = 455; break; } Expect(21, la); // ":" - currentState = 453; + currentState = 456; break; } - case 453: { + case 456: { wasNormalAttribute = false; goto case 37; } - case 454: { - if (la == null) { currentState = 454; break; } + case 457: { + if (la == null) { currentState = 457; break; } Expect(210, la); // "Sub" - currentState = 455; + currentState = 458; break; } - case 455: { - stateStack.Push(456); - goto case 426; + case 458: { + stateStack.Push(459); + goto case 429; } - case 456: { + case 459: { nextTokenIsPotentialStartOfExpression = true; - goto case 457; + goto case 460; } - case 457: { - if (la == null) { currentState = 457; break; } + case 460: { + if (la == null) { currentState = 460; break; } if (set[50].Get(la.kind)) { goto case 269; } else { if (la.kind == 1 || la.kind == 21) { - stateStack.Push(458); + stateStack.Push(461); goto case 261; } else { goto case 6; } } } - case 458: { - if (la == null) { currentState = 458; break; } + case 461: { + if (la == null) { currentState = 461; break; } Expect(113, la); // "End" - currentState = 459; + currentState = 462; break; } - case 459: { - if (la == null) { currentState = 459; break; } + case 462: { + if (la == null) { currentState = 462; break; } Expect(210, la); // "Sub" currentState = stateStack.Pop(); break; } - case 460: { - if (la == null) { currentState = 460; break; } + case 463: { + if (la == null) { currentState = 463; break; } if (la.kind == 17 || la.kind == 18 || la.kind == 19) { - currentState = 473; + currentState = 476; break; } else { if (la.kind == 10) { - stateStack.Push(462); - goto case 464; + stateStack.Push(465); + goto case 467; } else { Error(la); - goto case 461; + goto case 464; } } } - case 461: { + case 464: { PopContext(); currentState = stateStack.Pop(); goto switchlbl; } - case 462: { - if (la == null) { currentState = 462; break; } + case 465: { + if (la == null) { currentState = 465; break; } if (la.kind == 17) { - currentState = 463; + currentState = 466; break; } else { - goto case 461; + goto case 464; } } - case 463: { - if (la == null) { currentState = 463; break; } + case 466: { + if (la == null) { currentState = 466; break; } if (la.kind == 16) { - currentState = 462; + currentState = 465; break; } else { - goto case 462; + goto case 465; } } - case 464: { + case 467: { PushContext(Context.Xml, la, t); - goto case 465; + goto case 468; } - case 465: { - if (la == null) { currentState = 465; break; } + case 468: { + if (la == null) { currentState = 468; break; } Expect(10, la); // XmlOpenTag - currentState = 466; + currentState = 469; break; } - case 466: { - if (la == null) { currentState = 466; break; } + case 469: { + if (la == null) { currentState = 469; break; } if (set[144].Get(la.kind)) { if (set[145].Get(la.kind)) { - currentState = 466; + currentState = 469; break; } else { if (la.kind == 12) { - stateStack.Push(466); - goto case 470; + stateStack.Push(469); + goto case 473; } else { Error(la); - goto case 466; + goto case 469; } } } else { if (la.kind == 14) { - currentState = 467; + currentState = 470; break; } else { if (la.kind == 11) { - currentState = 468; + currentState = 471; break; } else { Error(la); - goto case 467; + goto case 470; } } } } - case 467: { + case 470: { PopContext(); currentState = stateStack.Pop(); goto switchlbl; } - case 468: { - if (la == null) { currentState = 468; break; } + case 471: { + if (la == null) { currentState = 471; break; } if (set[146].Get(la.kind)) { if (set[147].Get(la.kind)) { - currentState = 468; + currentState = 471; break; } else { if (la.kind == 12) { - stateStack.Push(468); - goto case 470; + stateStack.Push(471); + goto case 473; } else { if (la.kind == 10) { - stateStack.Push(468); - goto case 464; + stateStack.Push(471); + goto case 467; } else { Error(la); - goto case 468; + goto case 471; } } } } else { Expect(15, la); // XmlOpenEndTag - currentState = 469; + currentState = 472; break; } } - case 469: { - if (la == null) { currentState = 469; break; } + case 472: { + if (la == null) { currentState = 472; break; } if (set[148].Get(la.kind)) { if (set[149].Get(la.kind)) { - currentState = 469; + currentState = 472; break; } else { if (la.kind == 12) { - stateStack.Push(469); - goto case 470; + stateStack.Push(472); + goto case 473; } else { Error(la); - goto case 469; + goto case 472; } } } else { Expect(11, la); // XmlCloseTag - currentState = 467; + currentState = 470; break; } } - case 470: { - if (la == null) { currentState = 470; break; } + case 473: { + if (la == null) { currentState = 473; break; } Expect(12, la); // XmlStartInlineVB - currentState = 471; + currentState = 474; break; } - case 471: { - stateStack.Push(472); + case 474: { + stateStack.Push(475); goto case 55; } - case 472: { - if (la == null) { currentState = 472; break; } + case 475: { + if (la == null) { currentState = 475; break; } Expect(13, la); // XmlEndInlineVB currentState = stateStack.Pop(); break; } - case 473: { - if (la == null) { currentState = 473; break; } + case 476: { + if (la == null) { currentState = 476; break; } if (la.kind == 16) { - currentState = 474; + currentState = 477; break; } else { - goto case 474; + goto case 477; } } - case 474: { - if (la == null) { currentState = 474; break; } + case 477: { + if (la == null) { currentState = 477; break; } if (la.kind == 17 || la.kind == 19) { - currentState = 473; + currentState = 476; break; } else { if (la.kind == 10) { - stateStack.Push(475); - goto case 464; + stateStack.Push(478); + goto case 467; } else { - goto case 461; + goto case 464; } } } - case 475: { - if (la == null) { currentState = 475; break; } + case 478: { + if (la == null) { currentState = 478; break; } if (la.kind == 17) { - currentState = 476; + currentState = 479; break; } else { - goto case 461; + goto case 464; } } - case 476: { - if (la == null) { currentState = 476; break; } + case 479: { + if (la == null) { currentState = 479; break; } if (la.kind == 16) { - currentState = 475; + currentState = 478; break; } else { - goto case 475; + goto case 478; } } - case 477: { - if (la == null) { currentState = 477; break; } + case 480: { + if (la == null) { currentState = 480; break; } Expect(37, la); // "(" - currentState = 478; + currentState = 481; break; } - case 478: { + case 481: { readXmlIdentifier = true; - stateStack.Push(479); + stateStack.Push(482); goto case 205; } - case 479: { - if (la == null) { currentState = 479; break; } + case 482: { + if (la == null) { currentState = 482; break; } Expect(38, la); // ")" currentState = 175; break; } - case 480: { - if (la == null) { currentState = 480; break; } + case 483: { + if (la == null) { currentState = 483; break; } Expect(37, la); // "(" - currentState = 481; + currentState = 484; break; } - case 481: { + case 484: { PushContext(Context.Type, la, t); - stateStack.Push(482); + stateStack.Push(485); goto case 37; } - case 482: { + case 485: { PopContext(); - goto case 479; + goto case 482; } - case 483: { + case 486: { nextTokenIsStartOfImportsOrAccessExpression = true; wasQualifierTokenAtStart = true; - goto case 484; + goto case 487; } - case 484: { - if (la == null) { currentState = 484; break; } + case 487: { + if (la == null) { currentState = 487; break; } if (la.kind == 10) { - currentState = 485; + currentState = 488; break; } else { - goto case 485; + goto case 488; } } - case 485: { - stateStack.Push(486); + case 488: { + stateStack.Push(489); goto case 101; } - case 486: { - if (la == null) { currentState = 486; break; } + case 489: { + if (la == null) { currentState = 489; break; } if (la.kind == 11) { currentState = 175; break; @@ -6402,235 +6431,235 @@ partial class ExpressionFinder { goto case 175; } } - case 487: { + case 490: { activeArgument = 0; - goto case 488; + goto case 491; } - case 488: { - stateStack.Push(489); + case 491: { + stateStack.Push(492); goto case 55; } - case 489: { - if (la == null) { currentState = 489; break; } + case 492: { + if (la == null) { currentState = 492; break; } if (la.kind == 22) { - currentState = 490; + currentState = 493; break; } else { - goto case 479; + goto case 482; } } - case 490: { + case 493: { activeArgument++; - goto case 488; + goto case 491; } - case 491: { - stateStack.Push(492); + case 494: { + stateStack.Push(495); goto case 55; } - case 492: { - if (la == null) { currentState = 492; break; } + case 495: { + if (la == null) { currentState = 495; break; } if (la.kind == 22) { - currentState = 493; + currentState = 496; break; } else { currentState = stateStack.Pop(); goto switchlbl; } } - case 493: { + case 496: { activeArgument++; nextTokenIsPotentialStartOfExpression = true; - goto case 494; + goto case 497; } - case 494: { - if (la == null) { currentState = 494; break; } + case 497: { + if (la == null) { currentState = 497; break; } if (set[23].Get(la.kind)) { - goto case 491; + goto case 494; } else { - goto case 492; + goto case 495; } } - case 495: { - if (la == null) { currentState = 495; break; } + case 498: { + if (la == null) { currentState = 498; break; } if (set[16].Get(la.kind)) { PushContext(Context.Type, la, t); - stateStack.Push(499); + stateStack.Push(502); goto case 37; } else { - goto case 496; + goto case 499; } } - case 496: { - if (la == null) { currentState = 496; break; } + case 499: { + if (la == null) { currentState = 499; break; } if (la.kind == 22) { - currentState = 497; + currentState = 500; break; } else { goto case 45; } } - case 497: { - if (la == null) { currentState = 497; break; } + case 500: { + if (la == null) { currentState = 500; break; } if (set[16].Get(la.kind)) { PushContext(Context.Type, la, t); - stateStack.Push(498); + stateStack.Push(501); goto case 37; } else { - goto case 496; + goto case 499; } } - case 498: { + case 501: { PopContext(); - goto case 496; + goto case 499; } - case 499: { + case 502: { PopContext(); - goto case 496; + goto case 499; } - case 500: { + case 503: { SetIdentifierExpected(la); - goto case 501; + goto case 504; } - case 501: { - if (la == null) { currentState = 501; break; } + case 504: { + if (la == null) { currentState = 504; break; } if (set[150].Get(la.kind)) { if (la.kind == 169) { - currentState = 503; + currentState = 506; break; } else { - if (set[77].Get(la.kind)) { - stateStack.Push(502); - goto case 430; + if (set[78].Get(la.kind)) { + stateStack.Push(505); + goto case 433; } else { Error(la); - goto case 502; + goto case 505; } } } else { - goto case 502; + goto case 505; } } - case 502: { - if (la == null) { currentState = 502; break; } + case 505: { + if (la == null) { currentState = 505; break; } Expect(38, la); // ")" currentState = 34; break; } - case 503: { - stateStack.Push(502); - goto case 504; + case 506: { + stateStack.Push(505); + goto case 507; } - case 504: { + case 507: { SetIdentifierExpected(la); - goto case 505; + goto case 508; } - case 505: { - if (la == null) { currentState = 505; break; } + case 508: { + if (la == null) { currentState = 508; break; } if (la.kind == 138 || la.kind == 178) { - currentState = 506; + currentState = 509; break; } else { - goto case 506; + goto case 509; } } - case 506: { + case 509: { PushContext(Context.Identifier, la, t); SetIdentifierExpected(la); - stateStack.Push(507); - goto case 521; + stateStack.Push(510); + goto case 524; } - case 507: { + case 510: { PopContext(); - goto case 508; + goto case 511; } - case 508: { - if (la == null) { currentState = 508; break; } + case 511: { + if (la == null) { currentState = 511; break; } if (la.kind == 63) { - currentState = 522; + currentState = 525; break; } else { - goto case 509; + goto case 512; } } - case 509: { - if (la == null) { currentState = 509; break; } + case 512: { + if (la == null) { currentState = 512; break; } if (la.kind == 22) { - currentState = 510; + currentState = 513; break; } else { currentState = stateStack.Pop(); goto switchlbl; } } - case 510: { + case 513: { SetIdentifierExpected(la); - goto case 511; + goto case 514; } - case 511: { - if (la == null) { currentState = 511; break; } + case 514: { + if (la == null) { currentState = 514; break; } if (la.kind == 138 || la.kind == 178) { - currentState = 512; + currentState = 515; break; } else { - goto case 512; + goto case 515; } } - case 512: { + case 515: { PushContext(Context.Identifier, la, t); SetIdentifierExpected(la); - stateStack.Push(513); - goto case 521; + stateStack.Push(516); + goto case 524; } - case 513: { + case 516: { PopContext(); - goto case 514; + goto case 517; } - case 514: { - if (la == null) { currentState = 514; break; } + case 517: { + if (la == null) { currentState = 517; break; } if (la.kind == 63) { - currentState = 515; + currentState = 518; break; } else { - goto case 509; + goto case 512; } } - case 515: { + case 518: { PushContext(Context.Type, la, t); - stateStack.Push(516); - goto case 517; + stateStack.Push(519); + goto case 520; } - case 516: { + case 519: { PopContext(); - goto case 509; + goto case 512; } - case 517: { - if (la == null) { currentState = 517; break; } - if (set[94].Get(la.kind)) { - goto case 520; + case 520: { + if (la == null) { currentState = 520; break; } + if (set[95].Get(la.kind)) { + goto case 523; } else { if (la.kind == 35) { - currentState = 518; + currentState = 521; break; } else { goto case 6; } } } - case 518: { - stateStack.Push(519); - goto case 520; + case 521: { + stateStack.Push(522); + goto case 523; } - case 519: { - if (la == null) { currentState = 519; break; } + case 522: { + if (la == null) { currentState = 522; break; } if (la.kind == 22) { - currentState = 518; + currentState = 521; break; } else { goto case 82; } } - case 520: { - if (la == null) { currentState = 520; break; } + case 523: { + if (la == null) { currentState = 523; break; } if (set[16].Get(la.kind)) { currentState = 38; break; @@ -6650,8 +6679,8 @@ partial class ExpressionFinder { } } } - case 521: { - if (la == null) { currentState = 521; break; } + case 524: { + if (la == null) { currentState = 524; break; } if (la.kind == 2) { goto case 145; } else { @@ -6758,515 +6787,515 @@ partial class ExpressionFinder { } } } - case 522: { + case 525: { PushContext(Context.Type, la, t); - stateStack.Push(523); - goto case 517; + stateStack.Push(526); + goto case 520; } - case 523: { + case 526: { PopContext(); - goto case 509; + goto case 512; } - case 524: { + case 527: { PushContext(Context.Identifier, la, t); SetIdentifierExpected(la); - stateStack.Push(525); + stateStack.Push(528); goto case 205; } - case 525: { + case 528: { PopContext(); - goto case 526; + goto case 529; } - case 526: { - if (la == null) { currentState = 526; break; } + case 529: { + if (la == null) { currentState = 529; break; } if (la.kind == 37) { - stateStack.Push(527); - goto case 426; + stateStack.Push(530); + goto case 429; } else { - goto case 527; + goto case 530; } } - case 527: { - if (la == null) { currentState = 527; break; } + case 530: { + if (la == null) { currentState = 530; break; } if (la.kind == 63) { - currentState = 528; + currentState = 531; break; } else { goto case 23; } } - case 528: { + case 531: { PushContext(Context.Type, la, t); - goto case 529; + goto case 532; } - case 529: { - if (la == null) { currentState = 529; break; } + case 532: { + if (la == null) { currentState = 532; break; } if (la.kind == 40) { - stateStack.Push(529); - goto case 445; + stateStack.Push(532); + goto case 448; } else { - stateStack.Push(530); + stateStack.Push(533); goto case 37; } } - case 530: { + case 533: { PopContext(); goto case 23; } - case 531: { + case 534: { PushContext(Context.Identifier, la, t); SetIdentifierExpected(la); - stateStack.Push(532); + stateStack.Push(535); goto case 205; } - case 532: { + case 535: { PopContext(); - goto case 533; + goto case 536; } - case 533: { - if (la == null) { currentState = 533; break; } + case 536: { + if (la == null) { currentState = 536; break; } if (la.kind == 37 || la.kind == 63) { if (la.kind == 63) { - currentState = 535; + currentState = 538; break; } else { if (la.kind == 37) { stateStack.Push(23); - goto case 426; + goto case 429; } else { - goto case 534; + goto case 537; } } } else { goto case 23; } } - case 534: { + case 537: { Error(la); goto case 23; } - case 535: { + case 538: { PushContext(Context.Type, la, t); - stateStack.Push(536); + stateStack.Push(539); goto case 37; } - case 536: { + case 539: { PopContext(); goto case 23; } - case 537: { + case 540: { PushContext(Context.TypeDeclaration, la, t); - goto case 538; + goto case 541; } - case 538: { - if (la == null) { currentState = 538; break; } + case 541: { + if (la == null) { currentState = 541; break; } Expect(115, la); // "Enum" - currentState = 539; + currentState = 542; break; } - case 539: { + case 542: { PushContext(Context.Identifier, la, t); SetIdentifierExpected(la); - stateStack.Push(540); + stateStack.Push(543); goto case 205; } - case 540: { + case 543: { PopContext(); - goto case 541; + goto case 544; } - case 541: { - if (la == null) { currentState = 541; break; } + case 544: { + if (la == null) { currentState = 544; break; } if (la.kind == 63) { - currentState = 553; + currentState = 556; break; } else { - goto case 542; + goto case 545; } } - case 542: { - stateStack.Push(543); + case 545: { + stateStack.Push(546); goto case 23; } - case 543: { + case 546: { SetIdentifierExpected(la); - goto case 544; + goto case 547; } - case 544: { - if (la == null) { currentState = 544; break; } - if (set[97].Get(la.kind)) { - goto case 548; + case 547: { + if (la == null) { currentState = 547; break; } + if (set[98].Get(la.kind)) { + goto case 551; } else { Expect(113, la); // "End" - currentState = 545; + currentState = 548; break; } } - case 545: { - if (la == null) { currentState = 545; break; } + case 548: { + if (la == null) { currentState = 548; break; } Expect(115, la); // "Enum" - currentState = 546; + currentState = 549; break; } - case 546: { - stateStack.Push(547); + case 549: { + stateStack.Push(550); goto case 23; } - case 547: { + case 550: { PopContext(); currentState = stateStack.Pop(); goto switchlbl; } - case 548: { + case 551: { SetIdentifierExpected(la); - goto case 549; + goto case 552; } - case 549: { - if (la == null) { currentState = 549; break; } + case 552: { + if (la == null) { currentState = 552; break; } if (la.kind == 40) { - stateStack.Push(548); - goto case 445; + stateStack.Push(551); + goto case 448; } else { PushContext(Context.Identifier, la, t); SetIdentifierExpected(la); - stateStack.Push(550); + stateStack.Push(553); goto case 205; } } - case 550: { + case 553: { PopContext(); - goto case 551; + goto case 554; } - case 551: { - if (la == null) { currentState = 551; break; } + case 554: { + if (la == null) { currentState = 554; break; } if (la.kind == 20) { - currentState = 552; + currentState = 555; break; } else { - goto case 542; + goto case 545; } } - case 552: { - stateStack.Push(542); + case 555: { + stateStack.Push(545); goto case 55; } - case 553: { + case 556: { PushContext(Context.Type, la, t); - stateStack.Push(554); + stateStack.Push(557); goto case 37; } - case 554: { + case 557: { PopContext(); - goto case 542; + goto case 545; } - case 555: { - if (la == null) { currentState = 555; break; } + case 558: { + if (la == null) { currentState = 558; break; } Expect(103, la); // "Delegate" - currentState = 556; + currentState = 559; break; } - case 556: { - if (la == null) { currentState = 556; break; } + case 559: { + if (la == null) { currentState = 559; break; } if (la.kind == 210) { - currentState = 557; + currentState = 560; break; } else { if (la.kind == 127) { - currentState = 557; + currentState = 560; break; } else { Error(la); - goto case 557; + goto case 560; } } } - case 557: { + case 560: { PushContext(Context.Identifier, la, t); SetIdentifierExpected(la); - goto case 558; + goto case 561; } - case 558: { - if (la == null) { currentState = 558; break; } - currentState = 559; + case 561: { + if (la == null) { currentState = 561; break; } + currentState = 562; break; } - case 559: { + case 562: { PopContext(); - goto case 560; + goto case 563; } - case 560: { - if (la == null) { currentState = 560; break; } + case 563: { + if (la == null) { currentState = 563; break; } if (la.kind == 37) { - currentState = 563; + currentState = 566; break; } else { if (la.kind == 63) { - currentState = 561; + currentState = 564; break; } else { goto case 23; } } } - case 561: { + case 564: { PushContext(Context.Type, la, t); - stateStack.Push(562); + stateStack.Push(565); goto case 37; } - case 562: { + case 565: { PopContext(); goto case 23; } - case 563: { + case 566: { SetIdentifierExpected(la); - goto case 564; + goto case 567; } - case 564: { - if (la == null) { currentState = 564; break; } + case 567: { + if (la == null) { currentState = 567; break; } if (set[150].Get(la.kind)) { if (la.kind == 169) { - currentState = 566; + currentState = 569; break; } else { - if (set[77].Get(la.kind)) { - stateStack.Push(565); - goto case 430; + if (set[78].Get(la.kind)) { + stateStack.Push(568); + goto case 433; } else { Error(la); - goto case 565; + goto case 568; } } } else { - goto case 565; + goto case 568; } } - case 565: { - if (la == null) { currentState = 565; break; } + case 568: { + if (la == null) { currentState = 568; break; } Expect(38, la); // ")" - currentState = 560; + currentState = 563; break; } - case 566: { - stateStack.Push(565); - goto case 504; + case 569: { + stateStack.Push(568); + goto case 507; } - case 567: { + case 570: { PushContext(Context.TypeDeclaration, la, t); - goto case 568; + goto case 571; } - case 568: { - if (la == null) { currentState = 568; break; } + case 571: { + if (la == null) { currentState = 571; break; } if (la.kind == 155) { - currentState = 569; + currentState = 572; break; } else { if (la.kind == 84) { - currentState = 569; + currentState = 572; break; } else { if (la.kind == 209) { - currentState = 569; + currentState = 572; break; } else { Error(la); - goto case 569; + goto case 572; } } } } - case 569: { + case 572: { PushContext(Context.Identifier, la, t); SetIdentifierExpected(la); - stateStack.Push(570); + stateStack.Push(573); goto case 205; } - case 570: { + case 573: { PopContext(); - goto case 571; + goto case 574; } - case 571: { - if (la == null) { currentState = 571; break; } + case 574: { + if (la == null) { currentState = 574; break; } if (la.kind == 37) { - currentState = 721; + currentState = 724; break; } else { - goto case 572; + goto case 575; } } - case 572: { - stateStack.Push(573); + case 575: { + stateStack.Push(576); goto case 23; } - case 573: { + case 576: { SetIdentifierExpected(la); isMissingModifier = true; - goto case 574; + goto case 577; } - case 574: { - if (la == null) { currentState = 574; break; } + case 577: { + if (la == null) { currentState = 577; break; } if (la.kind == 140) { isMissingModifier = false; - goto case 718; + goto case 721; } else { - goto case 575; + goto case 578; } } - case 575: { + case 578: { SetIdentifierExpected(la); isMissingModifier = true; - goto case 576; + goto case 579; } - case 576: { - if (la == null) { currentState = 576; break; } + case 579: { + if (la == null) { currentState = 579; break; } if (la.kind == 136) { isMissingModifier = false; - goto case 712; + goto case 715; } else { - goto case 577; + goto case 580; } } - case 577: { + case 580: { SetIdentifierExpected(la); isMissingModifier = true; - goto case 578; + goto case 581; } - case 578: { - if (la == null) { currentState = 578; break; } - if (set[101].Get(la.kind)) { - goto case 583; + case 581: { + if (la == null) { currentState = 581; break; } + if (set[102].Get(la.kind)) { + goto case 586; } else { isMissingModifier = false; - goto case 579; + goto case 582; } } - case 579: { - if (la == null) { currentState = 579; break; } + case 582: { + if (la == null) { currentState = 582; break; } Expect(113, la); // "End" - currentState = 580; + currentState = 583; break; } - case 580: { - if (la == null) { currentState = 580; break; } + case 583: { + if (la == null) { currentState = 583; break; } if (la.kind == 155) { - currentState = 581; + currentState = 584; break; } else { if (la.kind == 84) { - currentState = 581; + currentState = 584; break; } else { if (la.kind == 209) { - currentState = 581; + currentState = 584; break; } else { Error(la); - goto case 581; + goto case 584; } } } } - case 581: { - stateStack.Push(582); + case 584: { + stateStack.Push(585); goto case 23; } - case 582: { + case 585: { PopContext(); currentState = stateStack.Pop(); goto switchlbl; } - case 583: { + case 586: { SetIdentifierExpected(la); isMissingModifier = true; - goto case 584; + goto case 587; } - case 584: { - if (la == null) { currentState = 584; break; } + case 587: { + if (la == null) { currentState = 587; break; } if (la.kind == 40) { - stateStack.Push(583); - goto case 445; + stateStack.Push(586); + goto case 448; } else { isMissingModifier = true; - goto case 585; + goto case 588; } } - case 585: { + case 588: { SetIdentifierExpected(la); - goto case 586; + goto case 589; } - case 586: { - if (la == null) { currentState = 586; break; } - if (set[132].Get(la.kind)) { - currentState = 711; + case 589: { + if (la == null) { currentState = 589; break; } + if (set[133].Get(la.kind)) { + currentState = 714; break; } else { isMissingModifier = false; SetIdentifierExpected(la); - goto case 587; + goto case 590; } } - case 587: { - if (la == null) { currentState = 587; break; } + case 590: { + if (la == null) { currentState = 590; break; } if (la.kind == 84 || la.kind == 155 || la.kind == 209) { - stateStack.Push(577); - goto case 567; + stateStack.Push(580); + goto case 570; } else { if (la.kind == 103) { - stateStack.Push(577); - goto case 555; + stateStack.Push(580); + goto case 558; } else { if (la.kind == 115) { - stateStack.Push(577); - goto case 537; + stateStack.Push(580); + goto case 540; } else { if (la.kind == 142) { - stateStack.Push(577); + stateStack.Push(580); goto case 9; } else { - if (set[104].Get(la.kind)) { - stateStack.Push(577); + if (set[105].Get(la.kind)) { + stateStack.Push(580); PushContext(Context.Member, la, t); SetIdentifierExpected(la); - goto case 588; + goto case 591; } else { Error(la); - goto case 577; + goto case 580; } } } } } } - case 588: { - if (la == null) { currentState = 588; break; } - if (set[122].Get(la.kind)) { - stateStack.Push(589); - goto case 696; + case 591: { + if (la == null) { currentState = 591; break; } + if (set[123].Get(la.kind)) { + stateStack.Push(592); + goto case 699; } else { if (la.kind == 127 || la.kind == 210) { - stateStack.Push(589); - goto case 678; + stateStack.Push(592); + goto case 681; } else { if (la.kind == 101) { - stateStack.Push(589); - goto case 665; + stateStack.Push(592); + goto case 668; } else { if (la.kind == 119) { - stateStack.Push(589); - goto case 653; + stateStack.Push(592); + goto case 656; } else { if (la.kind == 98) { - stateStack.Push(589); - goto case 641; + stateStack.Push(592); + goto case 644; } else { if (la.kind == 186) { - stateStack.Push(589); - goto case 604; + stateStack.Push(592); + goto case 607; } else { if (la.kind == 172) { - stateStack.Push(589); - goto case 590; + stateStack.Push(592); + goto case 593; } else { Error(la); - goto case 589; + goto case 592; } } } @@ -7275,716 +7304,716 @@ partial class ExpressionFinder { } } } - case 589: { + case 592: { PopContext(); currentState = stateStack.Pop(); goto switchlbl; } - case 590: { - if (la == null) { currentState = 590; break; } + case 593: { + if (la == null) { currentState = 593; break; } Expect(172, la); // "Operator" - currentState = 591; + currentState = 594; break; } - case 591: { + case 594: { PushContext(Context.Identifier, la, t); SetIdentifierExpected(la); - goto case 592; + goto case 595; } - case 592: { - if (la == null) { currentState = 592; break; } - currentState = 593; + case 595: { + if (la == null) { currentState = 595; break; } + currentState = 596; break; } - case 593: { + case 596: { PopContext(); - goto case 594; + goto case 597; } - case 594: { - if (la == null) { currentState = 594; break; } + case 597: { + if (la == null) { currentState = 597; break; } Expect(37, la); // "(" - currentState = 595; + currentState = 598; break; } - case 595: { - stateStack.Push(596); - goto case 430; + case 598: { + stateStack.Push(599); + goto case 433; } - case 596: { - if (la == null) { currentState = 596; break; } + case 599: { + if (la == null) { currentState = 599; break; } Expect(38, la); // ")" - currentState = 597; + currentState = 600; break; } - case 597: { - if (la == null) { currentState = 597; break; } + case 600: { + if (la == null) { currentState = 600; break; } if (la.kind == 63) { - currentState = 601; + currentState = 604; break; } else { - goto case 598; + goto case 601; } } - case 598: { - stateStack.Push(599); + case 601: { + stateStack.Push(602); goto case 261; } - case 599: { - if (la == null) { currentState = 599; break; } + case 602: { + if (la == null) { currentState = 602; break; } Expect(113, la); // "End" - currentState = 600; + currentState = 603; break; } - case 600: { - if (la == null) { currentState = 600; break; } + case 603: { + if (la == null) { currentState = 603; break; } Expect(172, la); // "Operator" currentState = 23; break; } - case 601: { + case 604: { PushContext(Context.Type, la, t); - goto case 602; + goto case 605; } - case 602: { - if (la == null) { currentState = 602; break; } + case 605: { + if (la == null) { currentState = 605; break; } if (la.kind == 40) { - stateStack.Push(602); - goto case 445; + stateStack.Push(605); + goto case 448; } else { - stateStack.Push(603); + stateStack.Push(606); goto case 37; } } - case 603: { + case 606: { PopContext(); - goto case 598; + goto case 601; } - case 604: { - if (la == null) { currentState = 604; break; } + case 607: { + if (la == null) { currentState = 607; break; } Expect(186, la); // "Property" - currentState = 605; + currentState = 608; break; } - case 605: { + case 608: { PushContext(Context.Identifier, la, t); SetIdentifierExpected(la); - stateStack.Push(606); + stateStack.Push(609); goto case 205; } - case 606: { + case 609: { PopContext(); - goto case 607; + goto case 610; } - case 607: { - if (la == null) { currentState = 607; break; } + case 610: { + if (la == null) { currentState = 610; break; } if (la.kind == 37) { - stateStack.Push(608); - goto case 426; + stateStack.Push(611); + goto case 429; } else { - goto case 608; + goto case 611; } } - case 608: { - if (la == null) { currentState = 608; break; } + case 611: { + if (la == null) { currentState = 611; break; } if (la.kind == 63) { - currentState = 638; + currentState = 641; break; } else { - goto case 609; + goto case 612; } } - case 609: { - if (la == null) { currentState = 609; break; } + case 612: { + if (la == null) { currentState = 612; break; } if (la.kind == 136) { - currentState = 633; + currentState = 636; break; } else { - goto case 610; + goto case 613; } } - case 610: { - if (la == null) { currentState = 610; break; } + case 613: { + if (la == null) { currentState = 613; break; } if (la.kind == 20) { - currentState = 632; + currentState = 635; break; } else { - goto case 611; + goto case 614; } } - case 611: { - stateStack.Push(612); + case 614: { + stateStack.Push(615); goto case 23; } - case 612: { + case 615: { PopContext(); - goto case 613; + goto case 616; } - case 613: { - if (la == null) { currentState = 613; break; } + case 616: { + if (la == null) { currentState = 616; break; } if (la.kind == 40) { - stateStack.Push(613); - goto case 445; + stateStack.Push(616); + goto case 448; } else { - goto case 614; + goto case 617; } } - case 614: { - if (la == null) { currentState = 614; break; } + case 617: { + if (la == null) { currentState = 617; break; } if (set[151].Get(la.kind)) { - currentState = 631; + currentState = 634; break; } else { if (la.kind == 128 || la.kind == 198) { PushContext(Context.Member, la, t); - goto case 615; + goto case 618; } else { currentState = stateStack.Pop(); goto switchlbl; } } } - case 615: { - if (la == null) { currentState = 615; break; } + case 618: { + if (la == null) { currentState = 618; break; } if (la.kind == 128) { - currentState = 616; + currentState = 619; break; } else { if (la.kind == 198) { - currentState = 616; + currentState = 619; break; } else { Error(la); - goto case 616; + goto case 619; } } } - case 616: { - if (la == null) { currentState = 616; break; } + case 619: { + if (la == null) { currentState = 619; break; } if (la.kind == 37) { - stateStack.Push(617); - goto case 426; + stateStack.Push(620); + goto case 429; } else { - goto case 617; + goto case 620; } } - case 617: { - stateStack.Push(618); + case 620: { + stateStack.Push(621); goto case 261; } - case 618: { - if (la == null) { currentState = 618; break; } + case 621: { + if (la == null) { currentState = 621; break; } Expect(113, la); // "End" - currentState = 619; + currentState = 622; break; } - case 619: { - if (la == null) { currentState = 619; break; } + case 622: { + if (la == null) { currentState = 622; break; } if (la.kind == 128) { - currentState = 620; + currentState = 623; break; } else { if (la.kind == 198) { - currentState = 620; + currentState = 623; break; } else { Error(la); - goto case 620; + goto case 623; } } } - case 620: { - stateStack.Push(621); + case 623: { + stateStack.Push(624); goto case 23; } - case 621: { - if (la == null) { currentState = 621; break; } - if (set[110].Get(la.kind)) { - goto case 624; + case 624: { + if (la == null) { currentState = 624; break; } + if (set[111].Get(la.kind)) { + goto case 627; } else { - goto case 622; + goto case 625; } } - case 622: { - if (la == null) { currentState = 622; break; } + case 625: { + if (la == null) { currentState = 625; break; } Expect(113, la); // "End" - currentState = 623; + currentState = 626; break; } - case 623: { - if (la == null) { currentState = 623; break; } + case 626: { + if (la == null) { currentState = 626; break; } Expect(186, la); // "Property" currentState = 23; break; } - case 624: { - if (la == null) { currentState = 624; break; } + case 627: { + if (la == null) { currentState = 627; break; } if (la.kind == 40) { - stateStack.Push(624); - goto case 445; + stateStack.Push(627); + goto case 448; } else { - goto case 625; + goto case 628; } } - case 625: { - if (la == null) { currentState = 625; break; } + case 628: { + if (la == null) { currentState = 628; break; } if (set[151].Get(la.kind)) { - currentState = 625; + currentState = 628; break; } else { if (la.kind == 128) { - currentState = 626; + currentState = 629; break; } else { if (la.kind == 198) { - currentState = 626; + currentState = 629; break; } else { Error(la); - goto case 626; + goto case 629; } } } } - case 626: { - if (la == null) { currentState = 626; break; } + case 629: { + if (la == null) { currentState = 629; break; } if (la.kind == 37) { - stateStack.Push(627); - goto case 426; + stateStack.Push(630); + goto case 429; } else { - goto case 627; + goto case 630; } } - case 627: { - stateStack.Push(628); + case 630: { + stateStack.Push(631); goto case 261; } - case 628: { - if (la == null) { currentState = 628; break; } + case 631: { + if (la == null) { currentState = 631; break; } Expect(113, la); // "End" - currentState = 629; + currentState = 632; break; } - case 629: { - if (la == null) { currentState = 629; break; } + case 632: { + if (la == null) { currentState = 632; break; } if (la.kind == 128) { - currentState = 630; + currentState = 633; break; } else { if (la.kind == 198) { - currentState = 630; + currentState = 633; break; } else { Error(la); - goto case 630; + goto case 633; } } } - case 630: { - stateStack.Push(622); + case 633: { + stateStack.Push(625); goto case 23; } - case 631: { + case 634: { SetIdentifierExpected(la); - goto case 614; + goto case 617; } - case 632: { - stateStack.Push(611); + case 635: { + stateStack.Push(614); goto case 55; } - case 633: { + case 636: { PushContext(Context.Type, la, t); - stateStack.Push(634); + stateStack.Push(637); goto case 37; } - case 634: { + case 637: { PopContext(); - goto case 635; + goto case 638; } - case 635: { - if (la == null) { currentState = 635; break; } + case 638: { + if (la == null) { currentState = 638; break; } if (la.kind == 22) { - currentState = 636; + currentState = 639; break; } else { - goto case 610; + goto case 613; } } - case 636: { + case 639: { PushContext(Context.Type, la, t); - stateStack.Push(637); + stateStack.Push(640); goto case 37; } - case 637: { + case 640: { PopContext(); - goto case 635; + goto case 638; } - case 638: { + case 641: { PushContext(Context.Type, la, t); - goto case 639; + goto case 642; } - case 639: { - if (la == null) { currentState = 639; break; } + case 642: { + if (la == null) { currentState = 642; break; } if (la.kind == 40) { - stateStack.Push(639); - goto case 445; + stateStack.Push(642); + goto case 448; } else { if (la.kind == 162) { - stateStack.Push(640); + stateStack.Push(643); goto case 85; } else { if (set[16].Get(la.kind)) { - stateStack.Push(640); + stateStack.Push(643); goto case 37; } else { Error(la); - goto case 640; + goto case 643; } } } } - case 640: { + case 643: { PopContext(); - goto case 609; + goto case 612; } - case 641: { - if (la == null) { currentState = 641; break; } + case 644: { + if (la == null) { currentState = 644; break; } Expect(98, la); // "Custom" - currentState = 642; + currentState = 645; break; } - case 642: { - stateStack.Push(643); - goto case 653; + case 645: { + stateStack.Push(646); + goto case 656; } - case 643: { - if (la == null) { currentState = 643; break; } - if (set[115].Get(la.kind)) { - goto case 645; + case 646: { + if (la == null) { currentState = 646; break; } + if (set[116].Get(la.kind)) { + goto case 648; } else { Expect(113, la); // "End" - currentState = 644; + currentState = 647; break; } } - case 644: { - if (la == null) { currentState = 644; break; } + case 647: { + if (la == null) { currentState = 647; break; } Expect(119, la); // "Event" currentState = 23; break; } - case 645: { - if (la == null) { currentState = 645; break; } + case 648: { + if (la == null) { currentState = 648; break; } if (la.kind == 40) { - stateStack.Push(645); - goto case 445; + stateStack.Push(648); + goto case 448; } else { if (la.kind == 56) { - currentState = 646; + currentState = 649; break; } else { if (la.kind == 193) { - currentState = 646; + currentState = 649; break; } else { if (la.kind == 189) { - currentState = 646; + currentState = 649; break; } else { Error(la); - goto case 646; + goto case 649; } } } } } - case 646: { - if (la == null) { currentState = 646; break; } + case 649: { + if (la == null) { currentState = 649; break; } Expect(37, la); // "(" - currentState = 647; + currentState = 650; break; } - case 647: { - stateStack.Push(648); - goto case 430; + case 650: { + stateStack.Push(651); + goto case 433; } - case 648: { - if (la == null) { currentState = 648; break; } + case 651: { + if (la == null) { currentState = 651; break; } Expect(38, la); // ")" - currentState = 649; + currentState = 652; break; } - case 649: { - stateStack.Push(650); + case 652: { + stateStack.Push(653); goto case 261; } - case 650: { - if (la == null) { currentState = 650; break; } + case 653: { + if (la == null) { currentState = 653; break; } Expect(113, la); // "End" - currentState = 651; + currentState = 654; break; } - case 651: { - if (la == null) { currentState = 651; break; } + case 654: { + if (la == null) { currentState = 654; break; } if (la.kind == 56) { - currentState = 652; + currentState = 655; break; } else { if (la.kind == 193) { - currentState = 652; + currentState = 655; break; } else { if (la.kind == 189) { - currentState = 652; + currentState = 655; break; } else { Error(la); - goto case 652; + goto case 655; } } } } - case 652: { - stateStack.Push(643); + case 655: { + stateStack.Push(646); goto case 23; } - case 653: { - if (la == null) { currentState = 653; break; } + case 656: { + if (la == null) { currentState = 656; break; } Expect(119, la); // "Event" - currentState = 654; + currentState = 657; break; } - case 654: { + case 657: { PushContext(Context.Identifier, la, t); SetIdentifierExpected(la); - stateStack.Push(655); + stateStack.Push(658); goto case 205; } - case 655: { + case 658: { PopContext(); - goto case 656; + goto case 659; } - case 656: { - if (la == null) { currentState = 656; break; } + case 659: { + if (la == null) { currentState = 659; break; } if (la.kind == 63) { - currentState = 663; + currentState = 666; break; } else { if (set[152].Get(la.kind)) { if (la.kind == 37) { - stateStack.Push(657); - goto case 426; + stateStack.Push(660); + goto case 429; } else { - goto case 657; + goto case 660; } } else { Error(la); - goto case 657; + goto case 660; } } } - case 657: { - if (la == null) { currentState = 657; break; } + case 660: { + if (la == null) { currentState = 660; break; } if (la.kind == 136) { - currentState = 658; + currentState = 661; break; } else { goto case 23; } } - case 658: { + case 661: { PushContext(Context.Type, la, t); - stateStack.Push(659); + stateStack.Push(662); goto case 37; } - case 659: { + case 662: { PopContext(); - goto case 660; + goto case 663; } - case 660: { - if (la == null) { currentState = 660; break; } + case 663: { + if (la == null) { currentState = 663; break; } if (la.kind == 22) { - currentState = 661; + currentState = 664; break; } else { goto case 23; } } - case 661: { + case 664: { PushContext(Context.Type, la, t); - stateStack.Push(662); + stateStack.Push(665); goto case 37; } - case 662: { + case 665: { PopContext(); - goto case 660; + goto case 663; } - case 663: { + case 666: { PushContext(Context.Type, la, t); - stateStack.Push(664); + stateStack.Push(667); goto case 37; } - case 664: { + case 667: { PopContext(); - goto case 657; + goto case 660; } - case 665: { - if (la == null) { currentState = 665; break; } + case 668: { + if (la == null) { currentState = 668; break; } Expect(101, la); // "Declare" - currentState = 666; + currentState = 669; break; } - case 666: { - if (la == null) { currentState = 666; break; } + case 669: { + if (la == null) { currentState = 669; break; } if (la.kind == 62 || la.kind == 66 || la.kind == 223) { - currentState = 667; + currentState = 670; break; } else { - goto case 667; + goto case 670; } } - case 667: { - if (la == null) { currentState = 667; break; } + case 670: { + if (la == null) { currentState = 670; break; } if (la.kind == 210) { - currentState = 668; + currentState = 671; break; } else { if (la.kind == 127) { - currentState = 668; + currentState = 671; break; } else { Error(la); - goto case 668; + goto case 671; } } } - case 668: { + case 671: { PushContext(Context.Identifier, la, t); SetIdentifierExpected(la); - stateStack.Push(669); + stateStack.Push(672); goto case 205; } - case 669: { + case 672: { PopContext(); - goto case 670; + goto case 673; } - case 670: { - if (la == null) { currentState = 670; break; } + case 673: { + if (la == null) { currentState = 673; break; } Expect(149, la); // "Lib" - currentState = 671; + currentState = 674; break; } - case 671: { - if (la == null) { currentState = 671; break; } + case 674: { + if (la == null) { currentState = 674; break; } Expect(3, la); // LiteralString - currentState = 672; + currentState = 675; break; } - case 672: { - if (la == null) { currentState = 672; break; } + case 675: { + if (la == null) { currentState = 675; break; } if (la.kind == 59) { - currentState = 677; + currentState = 680; break; } else { - goto case 673; + goto case 676; } - } - case 673: { - if (la == null) { currentState = 673; break; } + } + case 676: { + if (la == null) { currentState = 676; break; } if (la.kind == 37) { - stateStack.Push(674); - goto case 426; + stateStack.Push(677); + goto case 429; } else { - goto case 674; + goto case 677; } } - case 674: { - if (la == null) { currentState = 674; break; } + case 677: { + if (la == null) { currentState = 677; break; } if (la.kind == 63) { - currentState = 675; + currentState = 678; break; } else { goto case 23; } } - case 675: { + case 678: { PushContext(Context.Type, la, t); - stateStack.Push(676); + stateStack.Push(679); goto case 37; } - case 676: { + case 679: { PopContext(); goto case 23; } - case 677: { - if (la == null) { currentState = 677; break; } + case 680: { + if (la == null) { currentState = 680; break; } Expect(3, la); // LiteralString - currentState = 673; + currentState = 676; break; } - case 678: { - if (la == null) { currentState = 678; break; } + case 681: { + if (la == null) { currentState = 681; break; } if (la.kind == 210) { - currentState = 679; + currentState = 682; break; } else { if (la.kind == 127) { - currentState = 679; + currentState = 682; break; } else { Error(la); - goto case 679; + goto case 682; } } } - case 679: { + case 682: { PushContext(Context.Identifier, la, t); SetIdentifierExpected(la); - goto case 680; + goto case 683; } - case 680: { - if (la == null) { currentState = 680; break; } - currentState = 681; + case 683: { + if (la == null) { currentState = 683; break; } + currentState = 684; break; } - case 681: { + case 684: { PopContext(); - goto case 682; + goto case 685; } - case 682: { - if (la == null) { currentState = 682; break; } + case 685: { + if (la == null) { currentState = 685; break; } if (la.kind == 37) { - currentState = 692; + currentState = 695; break; } else { if (la.kind == 63) { - currentState = 690; + currentState = 693; break; } else { - goto case 683; + goto case 686; } } } - case 683: { - if (la == null) { currentState = 683; break; } + case 686: { + if (la == null) { currentState = 686; break; } if (la.kind == 134 || la.kind == 136) { - currentState = 687; + currentState = 690; break; } else { - goto case 684; + goto case 687; } } - case 684: { - stateStack.Push(685); + case 687: { + stateStack.Push(688); goto case 261; } - case 685: { - if (la == null) { currentState = 685; break; } + case 688: { + if (la == null) { currentState = 688; break; } Expect(113, la); // "End" - currentState = 686; + currentState = 689; break; } - case 686: { - if (la == null) { currentState = 686; break; } + case 689: { + if (la == null) { currentState = 689; break; } if (la.kind == 210) { currentState = 23; break; @@ -7993,129 +8022,129 @@ partial class ExpressionFinder { currentState = 23; break; } else { - goto case 534; + goto case 537; } } } - case 687: { - if (la == null) { currentState = 687; break; } + case 690: { + if (la == null) { currentState = 690; break; } if (la.kind == 153 || la.kind == 158 || la.kind == 159) { - currentState = 689; + currentState = 692; break; } else { - goto case 688; + goto case 691; } } - case 688: { - stateStack.Push(684); + case 691: { + stateStack.Push(687); goto case 37; } - case 689: { - if (la == null) { currentState = 689; break; } + case 692: { + if (la == null) { currentState = 692; break; } Expect(26, la); // "." - currentState = 688; + currentState = 691; break; } - case 690: { + case 693: { PushContext(Context.Type, la, t); - stateStack.Push(691); + stateStack.Push(694); goto case 37; } - case 691: { + case 694: { PopContext(); - goto case 683; + goto case 686; } - case 692: { + case 695: { SetIdentifierExpected(la); - goto case 693; + goto case 696; } - case 693: { - if (la == null) { currentState = 693; break; } + case 696: { + if (la == null) { currentState = 696; break; } if (set[150].Get(la.kind)) { if (la.kind == 169) { - currentState = 695; + currentState = 698; break; } else { - if (set[77].Get(la.kind)) { - stateStack.Push(694); - goto case 430; + if (set[78].Get(la.kind)) { + stateStack.Push(697); + goto case 433; } else { Error(la); - goto case 694; + goto case 697; } } } else { - goto case 694; + goto case 697; } } - case 694: { - if (la == null) { currentState = 694; break; } + case 697: { + if (la == null) { currentState = 697; break; } Expect(38, la); // ")" - currentState = 682; + currentState = 685; break; } - case 695: { - stateStack.Push(694); - goto case 504; - } - case 696: { + case 698: { stateStack.Push(697); + goto case 507; + } + case 699: { + stateStack.Push(700); SetIdentifierExpected(la); - goto case 698; + goto case 701; } - case 697: { - if (la == null) { currentState = 697; break; } + case 700: { + if (la == null) { currentState = 700; break; } if (la.kind == 22) { - currentState = 696; + currentState = 699; break; } else { goto case 23; } } - case 698: { - if (la == null) { currentState = 698; break; } + case 701: { + if (la == null) { currentState = 701; break; } if (la.kind == 88) { - currentState = 699; + currentState = 702; break; } else { - goto case 699; + goto case 702; } } - case 699: { + case 702: { PushContext(Context.Identifier, la, t); SetIdentifierExpected(la); - stateStack.Push(700); - goto case 710; + stateStack.Push(703); + goto case 713; } - case 700: { + case 703: { PopContext(); - goto case 701; + goto case 704; } - case 701: { - if (la == null) { currentState = 701; break; } + case 704: { + if (la == null) { currentState = 704; break; } if (la.kind == 33) { - currentState = 702; + currentState = 705; break; } else { - goto case 702; + goto case 705; } } - case 702: { - if (la == null) { currentState = 702; break; } + case 705: { + if (la == null) { currentState = 705; break; } if (la.kind == 37) { - currentState = 707; + currentState = 710; break; } else { if (la.kind == 63) { - currentState = 704; + currentState = 707; break; } else { - goto case 703; + goto case 706; } } } - case 703: { - if (la == null) { currentState = 703; break; } + case 706: { + if (la == null) { currentState = 706; break; } if (la.kind == 20) { currentState = 55; break; @@ -8124,56 +8153,56 @@ partial class ExpressionFinder { goto switchlbl; } } - case 704: { + case 707: { PushContext(Context.Type, la, t); - goto case 705; + goto case 708; } - case 705: { - if (la == null) { currentState = 705; break; } + case 708: { + if (la == null) { currentState = 708; break; } if (la.kind == 162) { - stateStack.Push(706); + stateStack.Push(709); goto case 85; } else { if (set[16].Get(la.kind)) { - stateStack.Push(706); + stateStack.Push(709); goto case 37; } else { Error(la); - goto case 706; + goto case 709; } } } - case 706: { + case 709: { PopContext(); - goto case 703; + goto case 706; } - case 707: { + case 710: { nextTokenIsPotentialStartOfExpression = true; - goto case 708; + goto case 711; } - case 708: { - if (la == null) { currentState = 708; break; } + case 711: { + if (la == null) { currentState = 711; break; } if (set[23].Get(la.kind)) { - stateStack.Push(709); + stateStack.Push(712); goto case 55; } else { - goto case 709; + goto case 712; } } - case 709: { - if (la == null) { currentState = 709; break; } + case 712: { + if (la == null) { currentState = 712; break; } if (la.kind == 22) { - currentState = 707; + currentState = 710; break; } else { Expect(38, la); // ")" - currentState = 702; + currentState = 705; break; } } - case 710: { - if (la == null) { currentState = 710; break; } - if (set[137].Get(la.kind)) { + case 713: { + if (la == null) { currentState = 713; break; } + if (set[138].Get(la.kind)) { currentState = stateStack.Pop(); break; } else { @@ -8188,249 +8217,249 @@ partial class ExpressionFinder { } } } - case 711: { + case 714: { isMissingModifier = false; - goto case 585; + goto case 588; } - case 712: { - if (la == null) { currentState = 712; break; } + case 715: { + if (la == null) { currentState = 715; break; } Expect(136, la); // "Implements" - currentState = 713; + currentState = 716; break; } - case 713: { + case 716: { PushContext(Context.Type, la, t); - stateStack.Push(714); + stateStack.Push(717); goto case 37; } - case 714: { + case 717: { PopContext(); - goto case 715; + goto case 718; } - case 715: { - if (la == null) { currentState = 715; break; } + case 718: { + if (la == null) { currentState = 718; break; } if (la.kind == 22) { - currentState = 716; + currentState = 719; break; } else { - stateStack.Push(577); + stateStack.Push(580); goto case 23; } } - case 716: { + case 719: { PushContext(Context.Type, la, t); - stateStack.Push(717); + stateStack.Push(720); goto case 37; } - case 717: { + case 720: { PopContext(); - goto case 715; + goto case 718; } - case 718: { - if (la == null) { currentState = 718; break; } + case 721: { + if (la == null) { currentState = 721; break; } Expect(140, la); // "Inherits" - currentState = 719; + currentState = 722; break; } - case 719: { + case 722: { PushContext(Context.Type, la, t); - stateStack.Push(720); + stateStack.Push(723); goto case 37; } - case 720: { + case 723: { PopContext(); - stateStack.Push(575); + stateStack.Push(578); goto case 23; } - case 721: { - if (la == null) { currentState = 721; break; } + case 724: { + if (la == null) { currentState = 724; break; } Expect(169, la); // "Of" - currentState = 722; + currentState = 725; break; } - case 722: { - stateStack.Push(723); - goto case 504; + case 725: { + stateStack.Push(726); + goto case 507; } - case 723: { - if (la == null) { currentState = 723; break; } + case 726: { + if (la == null) { currentState = 726; break; } Expect(38, la); // ")" - currentState = 572; + currentState = 575; break; } - case 724: { + case 727: { isMissingModifier = false; goto case 28; } - case 725: { + case 728: { PushContext(Context.Type, la, t); - stateStack.Push(726); + stateStack.Push(729); goto case 37; } - case 726: { + case 729: { PopContext(); - goto case 727; + goto case 730; } - case 727: { - if (la == null) { currentState = 727; break; } + case 730: { + if (la == null) { currentState = 730; break; } if (la.kind == 22) { - currentState = 728; + currentState = 731; break; } else { stateStack.Push(17); goto case 23; } } - case 728: { + case 731: { PushContext(Context.Type, la, t); - stateStack.Push(729); + stateStack.Push(732); goto case 37; } - case 729: { + case 732: { PopContext(); - goto case 727; + goto case 730; } - case 730: { - if (la == null) { currentState = 730; break; } + case 733: { + if (la == null) { currentState = 733; break; } Expect(169, la); // "Of" - currentState = 731; + currentState = 734; break; } - case 731: { - stateStack.Push(732); - goto case 504; + case 734: { + stateStack.Push(735); + goto case 507; } - case 732: { - if (la == null) { currentState = 732; break; } + case 735: { + if (la == null) { currentState = 735; break; } Expect(38, la); // ")" currentState = 14; break; } - case 733: { + case 736: { PushContext(Context.Identifier, la, t); SetIdentifierExpected(la); - goto case 734; + goto case 737; } - case 734: { - if (la == null) { currentState = 734; break; } + case 737: { + if (la == null) { currentState = 737; break; } if (set[49].Get(la.kind)) { - currentState = 734; + currentState = 737; break; } else { PopContext(); - stateStack.Push(735); + stateStack.Push(738); goto case 23; } } - case 735: { - if (la == null) { currentState = 735; break; } + case 738: { + if (la == null) { currentState = 738; break; } if (set[3].Get(la.kind)) { - stateStack.Push(735); + stateStack.Push(738); goto case 5; } else { Expect(113, la); // "End" - currentState = 736; + currentState = 739; break; } } - case 736: { - if (la == null) { currentState = 736; break; } + case 739: { + if (la == null) { currentState = 739; break; } Expect(160, la); // "Namespace" currentState = 23; break; } - case 737: { - if (la == null) { currentState = 737; break; } + case 740: { + if (la == null) { currentState = 740; break; } Expect(137, la); // "Imports" - currentState = 738; + currentState = 741; break; } - case 738: { + case 741: { PushContext(Context.Importable, la, t); nextTokenIsStartOfImportsOrAccessExpression = true; - goto case 739; + goto case 742; } - case 739: { - if (la == null) { currentState = 739; break; } + case 742: { + if (la == null) { currentState = 742; break; } if (set[153].Get(la.kind)) { - currentState = 745; + currentState = 748; break; } else { if (la.kind == 10) { - currentState = 741; + currentState = 744; break; } else { Error(la); - goto case 740; + goto case 743; } } } - case 740: { + case 743: { PopContext(); goto case 23; } - case 741: { - stateStack.Push(742); + case 744: { + stateStack.Push(745); goto case 205; } - case 742: { - if (la == null) { currentState = 742; break; } + case 745: { + if (la == null) { currentState = 745; break; } Expect(20, la); // "=" - currentState = 743; + currentState = 746; break; } - case 743: { - if (la == null) { currentState = 743; break; } + case 746: { + if (la == null) { currentState = 746; break; } Expect(3, la); // LiteralString - currentState = 744; + currentState = 747; break; } - case 744: { - if (la == null) { currentState = 744; break; } + case 747: { + if (la == null) { currentState = 747; break; } Expect(11, la); // XmlCloseTag - currentState = 740; + currentState = 743; break; } - case 745: { - if (la == null) { currentState = 745; break; } + case 748: { + if (la == null) { currentState = 748; break; } if (la.kind == 33 || la.kind == 37) { - stateStack.Push(745); + stateStack.Push(748); goto case 42; } else { if (la.kind == 20 || la.kind == 26) { - currentState = 746; + currentState = 749; break; } else { - goto case 740; + goto case 743; } } } - case 746: { - stateStack.Push(740); + case 749: { + stateStack.Push(743); goto case 37; } - case 747: { - if (la == null) { currentState = 747; break; } + case 750: { + if (la == null) { currentState = 750; break; } Expect(173, la); // "Option" - currentState = 748; + currentState = 751; break; } - case 748: { - if (la == null) { currentState = 748; break; } + case 751: { + if (la == null) { currentState = 751; break; } if (la.kind == 121 || la.kind == 139 || la.kind == 207) { - currentState = 750; + currentState = 753; break; } else { if (la.kind == 87) { - currentState = 749; + currentState = 752; break; } else { - goto case 534; + goto case 537; } } } - case 749: { - if (la == null) { currentState = 749; break; } + case 752: { + if (la == null) { currentState = 752; break; } if (la.kind == 213) { currentState = 23; break; @@ -8439,12 +8468,12 @@ partial class ExpressionFinder { currentState = 23; break; } else { - goto case 534; + goto case 537; } } } - case 750: { - if (la == null) { currentState = 750; break; } + case 753: { + if (la == null) { currentState = 753; break; } if (la.kind == 170 || la.kind == 171) { currentState = 23; break; @@ -8541,6 +8570,7 @@ partial class ExpressionFinder { new BitArray(new int[] {-66189316, 1174405160, -51383073, -972018405, -1030969182, 17106228, -97186288, 8259}), new BitArray(new int[] {-65140740, 1174409128, -51384097, -971985637, -1030903646, 17106228, -97186288, 8259}), new BitArray(new int[] {-65140740, 1174409128, -51384097, -972018405, -1030903646, 17106228, -97186288, 8259}), + new BitArray(new int[] {1048576, 3968, 0, 0, 65536, 0, 0, 0}), new BitArray(new int[] {1048576, 3968, 0, 0, 0, 0, 0, 0}), new BitArray(new int[] {-64092162, 1191182376, -1051937, -680509669, -1030969166, -1593504460, -21144002, 8903}), new BitArray(new int[] {-64092162, 1191182376, -1051937, -680476901, -1030969166, -1593504460, -21144002, 8903}), @@ -8615,7 +8645,6 @@ partial class ExpressionFinder { new BitArray(new int[] {-64092162, 1191182376, -1051937, -680378597, -1030969166, -1593504460, -21144002, 8903}), new BitArray(new int[] {0, 0, 33554432, 16777216, 16, 0, 16392, 0}), new BitArray(new int[] {-66189316, 1174405160, -51383585, -972018405, -1030969182, 17106228, -97186288, 8259}), - new BitArray(new int[] {1048576, 3968, 0, 0, 65536, 0, 0, 0}), new BitArray(new int[] {0, 0, 288, 0, 0, 4210688, 0, 0}), new BitArray(new int[] {-18434, -1, -1, -1, -1, -1, -1, -1}), new BitArray(new int[] {-22530, -1, -1, -1, -1, -1, -1, -1}), diff --git a/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/PushParser.frame b/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/PushParser.frame index 1bf369d5ea..73427172fc 100644 --- a/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/PushParser.frame +++ b/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/PushParser.frame @@ -37,6 +37,7 @@ partial class ExpressionFinder { bool wasQualifierTokenAtStart = false; bool nextTokenIsPotentialStartOfExpression = false; bool readXmlIdentifier = false; + bool xmlAllowed = true; bool identifierExpected = false; bool nextTokenIsStartOfImportsOrAccessExpression = false; bool isMissingModifier = false; diff --git a/src/Libraries/NRefactory/Test/Lexer/VBNet/XmlModeLexerTests.cs b/src/Libraries/NRefactory/Test/Lexer/VBNet/XmlModeLexerTests.cs index 287cb12990..e4ff7815fd 100644 --- a/src/Libraries/NRefactory/Test/Lexer/VBNet/XmlModeLexerTests.cs +++ b/src/Libraries/NRefactory/Test/Lexer/VBNet/XmlModeLexerTests.cs @@ -783,7 +783,7 @@ End If"; public void SelectStatement() { string statement = @"Select Case - Case , + Case < 1, () Case Else End Select"; @@ -792,8 +792,8 @@ End Select"; CheckHead(lexer); CheckTokens(lexer, Tokens.Select, Tokens.Case, Tokens.XmlOpenTag, Tokens.Identifier, Tokens.XmlCloseTagEmptyElement, Tokens.EOL, - Tokens.Case, Tokens.XmlOpenTag, Tokens.Identifier, Tokens.XmlCloseTagEmptyElement, Tokens.Comma, - Tokens.XmlOpenTag, Tokens.Identifier, Tokens.XmlCloseTagEmptyElement, Tokens.EOL, + Tokens.Case, Tokens.LessThan, Tokens.LiteralInteger, Tokens.Comma, Tokens.OpenParenthesis, + Tokens.XmlOpenTag, Tokens.Identifier, Tokens.XmlCloseTagEmptyElement, Tokens.CloseParenthesis, Tokens.EOL, Tokens.Case, Tokens.Else, Tokens.EOL, Tokens.End, Tokens.Select ); diff --git a/src/Libraries/NRefactory/Test/Parser/Statements/SwitchStatementTests.cs b/src/Libraries/NRefactory/Test/Parser/Statements/SwitchStatementTests.cs index 73de1122ee..997fbaaa5f 100644 --- a/src/Libraries/NRefactory/Test/Parser/Statements/SwitchStatementTests.cs +++ b/src/Libraries/NRefactory/Test/Parser/Statements/SwitchStatementTests.cs @@ -39,6 +39,20 @@ namespace ICSharpCode.NRefactory.Tests.Ast SwitchSection sec = switchStmt.SwitchSections[0]; Assert.AreEqual(0, sec.SwitchLabels.Count); } + + [Test] + public void SpecialCaseStatement() + { + SwitchStatement stmt = ParseUtilVBNet.ParseStatement("Select Case a\nCase < 50\nCase > 20, < 10\nEnd Select"); + Assert.AreEqual("a", ((IdentifierExpression)stmt.SwitchExpression).Identifier); + } + + [Test] + public void SpecialCaseStatement2() + { + SwitchStatement stmt = ParseUtilVBNet.ParseStatement("Select Case a\nCase < 50\nEnd Select"); + Assert.AreEqual("a", ((IdentifierExpression)stmt.SwitchExpression).Identifier); + } #endregion } } diff --git a/src/Main/Base/Project/Src/Gui/Components/ExtTreeView/ExtTreeView.cs b/src/Main/Base/Project/Src/Gui/Components/ExtTreeView/ExtTreeView.cs index e3951cdb8e..99c2d8ea6a 100644 --- a/src/Main/Base/Project/Src/Gui/Components/ExtTreeView/ExtTreeView.cs +++ b/src/Main/Base/Project/Src/Gui/Components/ExtTreeView/ExtTreeView.cs @@ -132,7 +132,7 @@ namespace ICSharpCode.SharpDevelop.Gui #region label editing - string labelEditOldLabel; + //string labelEditOldLabel; public void StartLabelEdit(ExtTreeNode node) { @@ -146,10 +146,12 @@ namespace ICSharpCode.SharpDevelop.Gui LabelEdit = true; node.BeforeLabelEdit(); node.BeginEdit(); - // remove node's label so that it doesn't get rendered behind the label editing textbox - // (if the user deletes some characters so that the text box shrinks) - labelEditOldLabel = node.Text; - node.Text = ""; + // Workaround disabled due to http://community.sharpdevelop.net/forums/t/14354.aspx + // "Rename fails if filename in Project Explorer is too long for the treeview viewport" + //// remove node's label so that it doesn't get rendered behind the label editing textbox + //// (if the user deletes some characters so that the text box shrinks) + //labelEditOldLabel = node.Text; + //node.Text = ""; } } @@ -176,8 +178,8 @@ namespace ICSharpCode.SharpDevelop.Gui ExtTreeNode node = e.Node as ExtTreeNode; if (node != null) { - node.Text = labelEditOldLabel; - labelEditOldLabel = null; + //node.Text = labelEditOldLabel; + //labelEditOldLabel = null; if (e.Label != null) { node.AfterLabelEdit(e.Label); } diff --git a/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ProjectWithServiceReferences.cs b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ProjectWithServiceReferences.cs index 78dec9ce42..d28261fb3e 100644 --- a/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ProjectWithServiceReferences.cs +++ b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ProjectWithServiceReferences.cs @@ -82,9 +82,16 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference void AddServiceReferencesItemToProject() { - var projectItem = new ServiceReferencesProjectItem(project); - projectItem.Include = "Service References"; - AddProjectItemToProject(projectItem); + if (IsServiceReferencesItemMissingFromProject()) { + var projectItem = new ServiceReferencesProjectItem(project); + projectItem.Include = "Service References"; + AddProjectItemToProject(projectItem); + } + } + + bool IsServiceReferencesItemMissingFromProject() + { + return project.GetItemsOfType(ItemType.ServiceReferences).Count() == 0; } void AddServiceReferenceItemToProject(ServiceReferenceFileName fileName) diff --git a/src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/Commands/ReferenceFolderNodeCommands.cs b/src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/Commands/ReferenceFolderNodeCommands.cs index ea770cddbe..b9f930e7a6 100644 --- a/src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/Commands/ReferenceFolderNodeCommands.cs +++ b/src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/Commands/ReferenceFolderNodeCommands.cs @@ -3,6 +3,7 @@ using System; using System.Diagnostics; +using System.IO; using System.Net; using System.Web.Services.Discovery; using System.Windows.Forms; @@ -178,54 +179,70 @@ namespace ICSharpCode.SharpDevelop.Project.Commands } return webReferencesNode; } - } - + } - public class ShowServiceInBrowser: AbstractMenuCommand + public class ShowServiceInBrowser : AbstractMenuCommand { - private static string NodePath = "//system.serviceModel//client//endpoint"; + static string NodePath = "//system.serviceModel//client//endpoint"; public override void Run() { - // hack try url fvoid = LoadConfigDocument(f); + XmlDocument appConfig = LoadAppConfig(); + if (appConfig != null) { + string endpointAddress = FindEndPointAddress(appConfig); + if (endpointAddress != null) { + StartInternetExplorer(endpointAddress); + } else { + MessageService.ShowError("No service found."); + } + } else { + MessageService.ShowError("No app.config file found."); + } + } + + XmlDocument LoadAppConfig() + { AbstractProjectBrowserTreeNode node = ProjectBrowserPad.Instance.SelectedNode; - var f = CompilableProject.GetAppConfigFile(node.Project,false); - if (!String.IsNullOrEmpty(f)) - { - - var configFile = LoadConfigDocument(f); - var endPoint = configFile.SelectSingleNode(NodePath).Attributes["address"].Value; - ProcessStartInfo startInfo = new ProcessStartInfo("IExplore.exe"); - startInfo.WindowStyle = ProcessWindowStyle.Normal; - startInfo.Arguments = endPoint; - - Process.Start(startInfo); - - - - } else - { - MessageService.ShowError("No app.config File found"); + FileName appConfigFileName = CompilableProject.GetAppConfigFile(node.Project, false); + if (!String.IsNullOrEmpty(appConfigFileName)) { + return LoadAppConfig(appConfigFileName); } + return null; } - static XmlDocument LoadConfigDocument(string fileName) + static XmlDocument LoadAppConfig(string fileName) { - XmlDocument doc = null; - try - { - doc = new XmlDocument(); - + try { + var doc = new XmlDocument(); doc.Load(fileName); return doc; + } catch (FileNotFoundException ex) { + LoggingService.Debug("LoadConfigDocument: " + fileName + ": " + ex.Message); } - catch (System.IO.FileNotFoundException e) - { - throw new Exception("No configuration file found.", e); + return null; + } + + string FindEndPointAddress(XmlDocument appConfig) + { + XmlNode endPoint = appConfig.SelectSingleNode(NodePath); + if (endPoint != null) { + XmlAttribute addressAttribute = endPoint.Attributes["address"]; + if (addressAttribute != null) { + return addressAttribute.Value; + } } + return null; + } + + void StartInternetExplorer(string arguments) + { + var startInfo = new ProcessStartInfo("IExplore.exe") { + WindowStyle = ProcessWindowStyle.Normal, + Arguments = arguments + }; + Process.Start(startInfo); } } - public class AddServiceReferenceToProject : AbstractMenuCommand { @@ -247,14 +264,12 @@ namespace ICSharpCode.SharpDevelop.Project.Commands } } - public class RefreshReference : AbstractMenuCommand { public override void Run() { - ReferenceNode node = Owner as ReferenceNode; - if (node != null) - { + var node = Owner as ReferenceNode; + if (node != null) { ReferenceProjectItem item = node.ReferenceProjectItem; if (item != null) { AssemblyParserService.RefreshProjectContentForReference(item); diff --git a/src/Main/Base/Test/ServiceReferences/ProjectWithServiceReferencesTests.cs b/src/Main/Base/Test/ServiceReferences/ProjectWithServiceReferencesTests.cs index de3917af7c..13a7b3604f 100644 --- a/src/Main/Base/Test/ServiceReferences/ProjectWithServiceReferencesTests.cs +++ b/src/Main/Base/Test/ServiceReferences/ProjectWithServiceReferencesTests.cs @@ -63,6 +63,11 @@ namespace ICSharpCode.SharpDevelop.Tests.ServiceReferences return msbuildProject.GetItemsOfType(ItemType.ServiceReferences).SingleOrDefault() as ServiceReferencesProjectItem; } + int GetHowManyWCFMetadataItemsInMSBuildProject() + { + return msbuildProject.GetItemsOfType(ItemType.ServiceReferences).Count(); + } + ProjectItem GetFileProjectItemInMSBuildProject(string fileName) { return msbuildProject.Items.SingleOrDefault(item => item.FileName == fileName); @@ -175,6 +180,21 @@ namespace ICSharpCode.SharpDevelop.Tests.ServiceReferences Assert.AreEqual("Service References", item.Include); } + [Test] + public void AddServiceReferenceProxyFile_ProjectHasServiceReferences_WCFMetadataItemNotAddedToProjectForServiceReferencesRootFolder() + { + CreateProjectWithMSBuildProject(); + var proxyFileName = new ServiceReferenceFileName() { ServiceName = "Service1" }; + project.AddServiceReferenceProxyFile(proxyFileName); + proxyFileName = new ServiceReferenceFileName() { ServiceName = "Service2" }; + + project.AddServiceReferenceProxyFile(proxyFileName); + + int count = GetHowManyWCFMetadataItemsInMSBuildProject(); + + Assert.AreEqual(1, count); + } + [Test] public void AddServiceReferenceProxyFile_ProjectHasNoServiceReferences_WCFMetadataStorageItemAddedToProjectForServiceReferencesFolder() {