From 397df1679342e348f689c82cfef4a7b977c1337c Mon Sep 17 00:00:00 2001 From: Ed Harvey Date: Sun, 29 May 2011 11:29:38 +1000 Subject: [PATCH 01/16] Use standard icon --- ILSpy/Images/Delete.png | Bin 575 -> 584 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/ILSpy/Images/Delete.png b/ILSpy/Images/Delete.png index 824d938dd67435984f22217cceab55e0c4438e15..560865f301f384826d3960c4ec607c3ae855ae52 100644 GIT binary patch delta 502 zcmV?~JY~rU z2Nl>`zeO-t(+*i8OpEN-EdYlJEL26}Ud~nm9CjKEP$EWwg{*1BsCWlxnjRB@ez3_R z;}QwMJ_K%%l0{Rne|3NM2njvF39{8A#oV8ui1{(?q~iu7ImqHZiN&U9CyzkiO|b<9 zH-MErL%itGlE_0_0VMSTGsyFRvGU^5(%bM-b6;Imk##y^OCbb}+;7O1LKdEPh=q(v z6{MSx*}Jj{QqC@TTit+~`$vvI>C!5^UzpYL??edD8_+&GY&C^DyLgr!R*p3^6pm%(^|2LJ#707*qoM6N<$f>}}D&j0`b delta 491 zcmVp|{G~2o{wE;)*%qi7NB95)5LUl_u1%Q#TA$%R4FARxxBvmfgdQuuZ(cC?cKU$B zFJSV3;V(-k=HrS*fB-@AKdHj*OmJEOy67>`W!Hd~ zJV Date: Sun, 29 May 2011 11:33:03 +1000 Subject: [PATCH 02/16] Slight change to hue of access overlay icons. --- ILSpy/Images/OverlayInternal.png | Bin 1292 -> 1292 bytes ILSpy/Images/OverlayProtected.png | Bin 352 -> 351 bytes ILSpy/Images/OverlayProtectedInternal.png | Bin 440 -> 440 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/ILSpy/Images/OverlayInternal.png b/ILSpy/Images/OverlayInternal.png index fcc53bddecc15a060e83493ac08fdd7967ff9453..3c1cbc6069440ef99f10792e82723c79fbadb13e 100644 GIT binary patch delta 181 zcmV;m080Oi3XBSnX;2>=HYFH3C>upD9ZxqQPc|Z0J0e{{DQ-|QgIF~H~bX&xyl9w}D1fUvYE508ix3tT`5qJ;@A jAi%}V$-&0V2onGR{FKsX0#zd800000NkvXXu0mjfNJUCf delta 181 zcmV;m080Oi3XBSnX;2~@HY^xAFdIcV9Zx|bPeLJBNFrTMDQ;gfgKRN?Zau7*X|kMY zwV-jgqI0>Wb-AZ>ys3D-s(8ShC(f@t(zQgutb4++eZ;bV@7r?!@Qks+qymx92n2yJ zV6L-i16Kh|xR3xJFAvOt3=$$z($Z2Q>~H~bX%Q(Y5h*sffUvZfh=`~Z3tT`DqJ;@A jz|Y0a$-&CZ2onGR2}9DOgu=$(00000NkvXXu0mjfD0)pV diff --git a/ILSpy/Images/OverlayProtected.png b/ILSpy/Images/OverlayProtected.png index 0d125f7d25e4ab710d03227b66922e7c13a467d0..8f789baff05035448e3b3bff7ae01cde7044dcc1 100644 GIT binary patch delta 208 zcmV;>05AXG0^b6Vmw&TKL_t(IPh(&h1;Z%>uB~p$y}Z2s|LJ+9|4&Sb|9@*k#}=af z2h;rJ_R6O}c4zzt;bjFD|8K5uUr3Z8Ae+D3T>A9i(>4El!sP$oT^RNM|1zWhi!=28 z6K%koqdhM{HiI;S@VlA%#2avGR-OmQ-ymB-hQKr*=uZqJ%1H$vMRU^)+(0&i3;;PD z=oM9>HNzCb3?Rw*$hLqCc(Eq-e}AOX|5uI*{cy}YCT|LOIm|4*!p|9|U1#}=af z2h;rJ)yk(oZe;ui;bpBB|8MSZUr3Z8Ae+CuT>A9i*ERopvgQBZ-4pfy|9PYTiyQR* z6K%ko8$B;UHiI;S@Vf*0#2avGZJr0n-ymB-hQKr*Sd1qG}B(QZ)krsaS&QYij7V00000 LNkvXXu0mjfAA)Jb diff --git a/ILSpy/Images/OverlayProtectedInternal.png b/ILSpy/Images/OverlayProtectedInternal.png index dacce33c49fa7d2f9e4cbe20bd5d4829be45dce9..82676812f8f5f3f91df1782689d0af3e40605e65 100644 GIT binary patch delta 283 zcmV+$0p$L;1Goc_rhoE+R$pFK|Nr#D(*GxB#Q$H>mHCorzrr-%JvsBwj{_P1L3mlQ z#s7JYNq2}bBot)x-Q!dL{CmFUe@~?R|GUeg{{LTV^nY=V-hZqH99drf|IpIf{|6RU z|4$2Z{0}nV#`b!!%^=Mn{BD6hZUYX3G&iaLe}Am#|Npx^|9^|)?7{v9*$OfQrnxB0 zvIDCN4lJq$YlImBGAP$e3T!jT0FcwY^#xpU`hV~I3a|l}=DL6l0pZRR4Y&b#oewf~ z=bRE0FMted%CQ3*@M2@^|Na=I|G{P=Za7`AeR}c#<~YOu4av6u^FodO$GU3%_qS5| hudgITSToR602Gl!&leF>xjg^?002ovPDHLkV1jX@la2rY delta 283 zcmV+$0p$L;1Goc_rhm$VR$tyx|Nr#*(*Gw`#{XY2CG#cGeuZhidu8UIA2%}ogYdFe zi~sYwlkN~>NGQnWyO*c_`S*3r|DJ65|9AI9{r`X7=>Osdz5iGZII^k!|Dg@F{|~IG z{+|}(_#b4zjidEon?agE_}u}0+y)#5X`ZA0|NZTv|NlSq{C_V_w+H(hWGl!JnC7Ac z%MPqAIIy-FtPy4i$e`Q^DX`5T13*sqwiIy1>Hoc}D!>L@+Uf!}1cW5>H|NHZl{s%jVxZ!lc_C>}2n{y2RH{{v=&x<$uAM2<2-``Q` hzrLCfVa-5O0Th9X)Q{H?vyA`%002ovPDHLkV1gYAod^H` From 529e9aaf5a8e2d1c3a3d23f5e79c1da3a78f40f9 Mon Sep 17 00:00:00 2001 From: Ed Harvey Date: Sun, 29 May 2011 16:34:18 +1000 Subject: [PATCH 03/16] Sort Analyzer results. --- .../Analyzer/AnalyzedEventFiredByTreeNode.cs | 6 ++-- .../AnalyzedEventOverridesTreeNode.cs | 8 +++-- .../Analyzer/AnalyzedFieldAccessTreeNode.cs | 11 ++++--- ...yzedInterfaceEventImplementedByTreeNode.cs | 15 ++++++--- ...zedInterfaceMethodImplementedByTreeNode.cs | 15 ++++++--- ...dInterfacePropertyImplementedByTreeNode.cs | 15 ++++++--- .../AnalyzedMethodOverridesTreeNode.cs | 10 ++++-- .../Analyzer/AnalyzedMethodUsedByTreeNode.cs | 7 ++-- .../Analyzer/AnalyzedMethodUsesTreeNode.cs | 17 ++++++++-- .../AnalyzedPropertyOverridesTreeNode.cs | 8 +++-- .../Analyzer/AnalyzedTypeExposedByTreeNode.cs | 33 ++++++++++++++----- .../AnalyzedTypeExtensionMethodsTreeNode.cs | 8 +++-- .../AnalyzedTypeInstantiationsTreeNode.cs | 11 +++++-- .../AnalyzedVirtualMethodUsedByTreeNode.cs | 13 ++++---- 14 files changed, 127 insertions(+), 50 deletions(-) diff --git a/ILSpy/TreeNodes/Analyzer/AnalyzedEventFiredByTreeNode.cs b/ILSpy/TreeNodes/Analyzer/AnalyzedEventFiredByTreeNode.cs index 02320cc09..f0247dc55 100644 --- a/ILSpy/TreeNodes/Analyzer/AnalyzedEventFiredByTreeNode.cs +++ b/ILSpy/TreeNodes/Analyzer/AnalyzedEventFiredByTreeNode.cs @@ -77,7 +77,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer { foundMethods = new ConcurrentDictionary(); - foreach (var child in FindReferencesInType(analyzedEvent.DeclaringType)) { + foreach (var child in FindReferencesInType(analyzedEvent.DeclaringType).OrderBy(n => n.Text)) { yield return child; } @@ -117,7 +117,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer if (found) { MethodDefinition codeLocation = this.Language.GetOriginalCodeLocation(method) as MethodDefinition; if (codeLocation != null && !HasAlreadyBeenFound(codeLocation)) { - yield return new AnalyzedMethodTreeNode(codeLocation); + var node = new AnalyzedMethodTreeNode(codeLocation); + node.Language = this.Language; + yield return node; } } } diff --git a/ILSpy/TreeNodes/Analyzer/AnalyzedEventOverridesTreeNode.cs b/ILSpy/TreeNodes/Analyzer/AnalyzedEventOverridesTreeNode.cs index 549152bb7..99aa27af6 100644 --- a/ILSpy/TreeNodes/Analyzer/AnalyzedEventOverridesTreeNode.cs +++ b/ILSpy/TreeNodes/Analyzer/AnalyzedEventOverridesTreeNode.cs @@ -71,7 +71,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer ScopedWhereUsedAnalyzer analyzer; analyzer = new ScopedWhereUsedAnalyzer(analyzedEvent, FindReferencesInType); - return analyzer.PerformAnalysis(ct); + foreach (var child in analyzer.PerformAnalysis(ct).OrderBy(n => n.Text)) { + yield return child; + } } private IEnumerable FindReferencesInType(TypeDefinition type) @@ -86,7 +88,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer if (TypesHierarchyHelpers.IsBaseEvent(analyzedEvent, eventDef)) { MethodDefinition anyAccessor = eventDef.AddMethod ?? eventDef.RemoveMethod; bool hidesParent = !anyAccessor.IsVirtual ^ anyAccessor.IsNewSlot; - yield return new AnalyzedEventTreeNode(eventDef, hidesParent ? "(hides) " : ""); + var node = new AnalyzedEventTreeNode(eventDef, hidesParent ? "(hides) " : ""); + node.Language = this.Language; + yield return node; } } } diff --git a/ILSpy/TreeNodes/Analyzer/AnalyzedFieldAccessTreeNode.cs b/ILSpy/TreeNodes/Analyzer/AnalyzedFieldAccessTreeNode.cs index 850ab3141..edc14fd04 100644 --- a/ILSpy/TreeNodes/Analyzer/AnalyzedFieldAccessTreeNode.cs +++ b/ILSpy/TreeNodes/Analyzer/AnalyzedFieldAccessTreeNode.cs @@ -18,6 +18,7 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Threading; using ICSharpCode.TreeView; using Mono.Cecil; @@ -74,7 +75,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer foundMethods = new Lazy(LazyThreadSafetyMode.ExecutionAndPublication); var analyzer = new ScopedWhereUsedAnalyzer(analyzedField, FindReferencesInType); - foreach (var child in analyzer.PerformAnalysis(ct)) { + foreach (var child in analyzer.PerformAnalysis(ct).OrderBy(n => n.Text)) { yield return child; } @@ -93,8 +94,8 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer foreach (Instruction instr in method.Body.Instructions) { if (CanBeReference(instr.OpCode.Code)) { FieldReference fr = instr.Operand as FieldReference; - if (fr != null && fr.Name == name && - Helpers.IsReferencedBy(analyzedField.DeclaringType, fr.DeclaringType) && + if (fr != null && fr.Name == name && + Helpers.IsReferencedBy(analyzedField.DeclaringType, fr.DeclaringType) && fr.Resolve() == analyzedField) { found = true; break; @@ -107,7 +108,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer if (found) { MethodDefinition codeLocation = this.Language.GetOriginalCodeLocation(method) as MethodDefinition; if (codeLocation != null && !HasAlreadyBeenFound(codeLocation)) { - yield return new AnalyzedMethodTreeNode(codeLocation); + var node = new AnalyzedMethodTreeNode(codeLocation); + node.Language = this.Language; + yield return node; } } } diff --git a/ILSpy/TreeNodes/Analyzer/AnalyzedInterfaceEventImplementedByTreeNode.cs b/ILSpy/TreeNodes/Analyzer/AnalyzedInterfaceEventImplementedByTreeNode.cs index 09cab0bf3..f6773be82 100644 --- a/ILSpy/TreeNodes/Analyzer/AnalyzedInterfaceEventImplementedByTreeNode.cs +++ b/ILSpy/TreeNodes/Analyzer/AnalyzedInterfaceEventImplementedByTreeNode.cs @@ -71,7 +71,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer { ScopedWhereUsedAnalyzer analyzer; analyzer = new ScopedWhereUsedAnalyzer(analyzedMethod, FindReferencesInType); - return analyzer.PerformAnalysis(ct); + foreach (var child in analyzer.PerformAnalysis(ct).OrderBy(n => n.Text)) { + yield return child; + } } private IEnumerable FindReferencesInType(TypeDefinition type) @@ -84,15 +86,20 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer foreach (EventDefinition ev in type.Events.Where(e => e.Name == analyzedEvent.Name)) { MethodDefinition accessor = ev.AddMethod ?? ev.RemoveMethod; - if (TypesHierarchyHelpers.MatchInterfaceMethod(accessor, analyzedMethod, implementedInterfaceRef)) - yield return new AnalyzedEventTreeNode(ev); + if (TypesHierarchyHelpers.MatchInterfaceMethod(accessor, analyzedMethod, implementedInterfaceRef)) { + var node = new AnalyzedEventTreeNode(ev); + node.Language = this.Language; + yield return node; + } yield break; } foreach (EventDefinition ev in type.Events.Where(e => e.Name.EndsWith(analyzedEvent.Name))) { MethodDefinition accessor = ev.AddMethod ?? ev.RemoveMethod; if (accessor.HasOverrides && accessor.Overrides.Any(m => m.Resolve() == analyzedMethod)) { - yield return new AnalyzedEventTreeNode(ev); + var node = new AnalyzedEventTreeNode(ev); + node.Language = this.Language; + yield return node; } } } diff --git a/ILSpy/TreeNodes/Analyzer/AnalyzedInterfaceMethodImplementedByTreeNode.cs b/ILSpy/TreeNodes/Analyzer/AnalyzedInterfaceMethodImplementedByTreeNode.cs index 960f48f89..3f139e040 100644 --- a/ILSpy/TreeNodes/Analyzer/AnalyzedInterfaceMethodImplementedByTreeNode.cs +++ b/ILSpy/TreeNodes/Analyzer/AnalyzedInterfaceMethodImplementedByTreeNode.cs @@ -69,7 +69,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer { ScopedWhereUsedAnalyzer analyzer; analyzer = new ScopedWhereUsedAnalyzer(analyzedMethod, FindReferencesInType); - return analyzer.PerformAnalysis(ct); + foreach (var child in analyzer.PerformAnalysis(ct).OrderBy(n => n.Text)) { + yield return child; + } } private IEnumerable FindReferencesInType(TypeDefinition type) @@ -81,14 +83,19 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer yield break; foreach (MethodDefinition method in type.Methods.Where(m => m.Name == analyzedMethod.Name)) { - if (TypesHierarchyHelpers.MatchInterfaceMethod(method, analyzedMethod, implementedInterfaceRef)) - yield return new AnalyzedMethodTreeNode(method); + if (TypesHierarchyHelpers.MatchInterfaceMethod(method, analyzedMethod, implementedInterfaceRef)) { + var node = new AnalyzedMethodTreeNode(method); + node.Language = this.Language; + yield return node; + } yield break; } foreach (MethodDefinition method in type.Methods) { if (method.HasOverrides && method.Overrides.Any(m => m.Resolve() == analyzedMethod)) { - yield return new AnalyzedMethodTreeNode(method); + var node = new AnalyzedMethodTreeNode(method); + node.Language = this.Language; + yield return node; } } } diff --git a/ILSpy/TreeNodes/Analyzer/AnalyzedInterfacePropertyImplementedByTreeNode.cs b/ILSpy/TreeNodes/Analyzer/AnalyzedInterfacePropertyImplementedByTreeNode.cs index 35d9bc3d0..56f89ad13 100644 --- a/ILSpy/TreeNodes/Analyzer/AnalyzedInterfacePropertyImplementedByTreeNode.cs +++ b/ILSpy/TreeNodes/Analyzer/AnalyzedInterfacePropertyImplementedByTreeNode.cs @@ -71,7 +71,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer { ScopedWhereUsedAnalyzer analyzer; analyzer = new ScopedWhereUsedAnalyzer(analyzedMethod, FindReferencesInType); - return analyzer.PerformAnalysis(ct); + foreach (var child in analyzer.PerformAnalysis(ct).OrderBy(n => n.Text)) { + yield return child; + } } private IEnumerable FindReferencesInType(TypeDefinition type) @@ -84,15 +86,20 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer foreach (PropertyDefinition property in type.Properties.Where(e => e.Name == analyzedProperty.Name)) { MethodDefinition accessor = property.GetMethod ?? property.SetMethod; - if (TypesHierarchyHelpers.MatchInterfaceMethod(accessor, analyzedMethod, implementedInterfaceRef)) - yield return new AnalyzedPropertyTreeNode(property); + if (TypesHierarchyHelpers.MatchInterfaceMethod(accessor, analyzedMethod, implementedInterfaceRef)) { + var node = new AnalyzedPropertyTreeNode(property); + node.Language = this.Language; + yield return node; + } yield break; } foreach (PropertyDefinition property in type.Properties.Where(e => e.Name.EndsWith(analyzedProperty.Name))) { MethodDefinition accessor = property.GetMethod ?? property.SetMethod; if (accessor.HasOverrides && accessor.Overrides.Any(m => m.Resolve() == analyzedMethod)) { - yield return new AnalyzedPropertyTreeNode(property); + var node = new AnalyzedPropertyTreeNode(property); + node.Language = this.Language; + yield return node; } } } diff --git a/ILSpy/TreeNodes/Analyzer/AnalyzedMethodOverridesTreeNode.cs b/ILSpy/TreeNodes/Analyzer/AnalyzedMethodOverridesTreeNode.cs index 05a3f5d6a..4e8af7663 100644 --- a/ILSpy/TreeNodes/Analyzer/AnalyzedMethodOverridesTreeNode.cs +++ b/ILSpy/TreeNodes/Analyzer/AnalyzedMethodOverridesTreeNode.cs @@ -76,12 +76,14 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer ScopedWhereUsedAnalyzer analyzer; analyzer = new ScopedWhereUsedAnalyzer(analyzedMethod, FindReferencesInType); - return analyzer.PerformAnalysis(ct); + foreach (var child in analyzer.PerformAnalysis(ct).OrderBy(n => n.Text)) { + yield return child; + } } private IEnumerable FindReferencesInType(TypeDefinition type) { - SharpTreeNode newNode = null; + AnalyzerTreeNode newNode = null; try { if (!TypesHierarchyHelpers.IsBaseType(analyzedMethod.DeclaringType, type, resolveTypeArguments: false)) yield break; @@ -97,8 +99,10 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer // ignore this type definition. maybe add a notification about such cases. } - if (newNode != null) + if (newNode != null) { + newNode.Language = this.Language; yield return newNode; + } } public static bool CanShow(MethodDefinition method) diff --git a/ILSpy/TreeNodes/Analyzer/AnalyzedMethodUsedByTreeNode.cs b/ILSpy/TreeNodes/Analyzer/AnalyzedMethodUsedByTreeNode.cs index f3f9504e6..175ce4efc 100644 --- a/ILSpy/TreeNodes/Analyzer/AnalyzedMethodUsedByTreeNode.cs +++ b/ILSpy/TreeNodes/Analyzer/AnalyzedMethodUsedByTreeNode.cs @@ -19,6 +19,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Linq; using System.Threading; using ICSharpCode.TreeView; using Mono.Cecil; @@ -71,7 +72,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer foundMethods = new ConcurrentDictionary(); var analyzer = new ScopedWhereUsedAnalyzer(analyzedMethod, FindReferencesInType); - foreach (var child in analyzer.PerformAnalysis(ct)) { + foreach (var child in analyzer.PerformAnalysis(ct).OrderBy(n => n.Text)) { yield return child; } @@ -100,7 +101,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer if (found) { MethodDefinition codeLocation = this.Language.GetOriginalCodeLocation(method) as MethodDefinition; if (codeLocation != null && !HasAlreadyBeenFound(codeLocation)) { - yield return new AnalyzedMethodTreeNode(codeLocation); + var node= new AnalyzedMethodTreeNode(codeLocation); + node.Language = this.Language; + yield return node; } } } diff --git a/ILSpy/TreeNodes/Analyzer/AnalyzedMethodUsesTreeNode.cs b/ILSpy/TreeNodes/Analyzer/AnalyzedMethodUsesTreeNode.cs index 5553f5a98..1b18a9ae1 100644 --- a/ILSpy/TreeNodes/Analyzer/AnalyzedMethodUsesTreeNode.cs +++ b/ILSpy/TreeNodes/Analyzer/AnalyzedMethodUsesTreeNode.cs @@ -51,14 +51,25 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer } protected override void LoadChildren() + { + analyzedMethod.Body = null; + foreach (var child in GetChildren().OrderBy(n => n.Text)) { + this.Children.Add(child); + } + } + + private IEnumerable GetChildren() { foreach (var f in GetUsedFields().Distinct()) { - this.Children.Add(new AnalyzedFieldTreeNode(f)); + var node = new AnalyzedFieldTreeNode(f); + node.Language = this.Language; + yield return node; } foreach (var m in GetUsedMethods().Distinct()) { - this.Children.Add(new AnalyzedMethodTreeNode(m)); + var node = new AnalyzedMethodTreeNode(m); + node.Language = this.Language; + yield return node; } - analyzedMethod.Body = null; } private IEnumerable GetUsedMethods() diff --git a/ILSpy/TreeNodes/Analyzer/AnalyzedPropertyOverridesTreeNode.cs b/ILSpy/TreeNodes/Analyzer/AnalyzedPropertyOverridesTreeNode.cs index 6a6ea0f32..8f264d7ff 100644 --- a/ILSpy/TreeNodes/Analyzer/AnalyzedPropertyOverridesTreeNode.cs +++ b/ILSpy/TreeNodes/Analyzer/AnalyzedPropertyOverridesTreeNode.cs @@ -72,7 +72,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer ScopedWhereUsedAnalyzer analyzer; analyzer = new ScopedWhereUsedAnalyzer(analyzedProperty, FindReferencesInType); - return analyzer.PerformAnalysis(ct); + foreach (var child in analyzer.PerformAnalysis(ct).OrderBy(n => n.Text)) { + yield return child; + } } private IEnumerable FindReferencesInType(TypeDefinition type) @@ -88,7 +90,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer if (TypesHierarchyHelpers.IsBaseProperty(analyzedProperty, property)) { MethodDefinition anyAccessor = property.GetMethod ?? property.SetMethod; bool hidesParent = !anyAccessor.IsVirtual ^ anyAccessor.IsNewSlot; - yield return new AnalyzedPropertyTreeNode(property, hidesParent ? "(hides) " : ""); + var node = new AnalyzedPropertyTreeNode(property, hidesParent ? "(hides) " : ""); + node.Language = this.Language; + yield return node; } } } diff --git a/ILSpy/TreeNodes/Analyzer/AnalyzedTypeExposedByTreeNode.cs b/ILSpy/TreeNodes/Analyzer/AnalyzedTypeExposedByTreeNode.cs index cd14c0575..26c2bca71 100644 --- a/ILSpy/TreeNodes/Analyzer/AnalyzedTypeExposedByTreeNode.cs +++ b/ILSpy/TreeNodes/Analyzer/AnalyzedTypeExposedByTreeNode.cs @@ -18,6 +18,7 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Threading; using ICSharpCode.TreeView; using Mono.Cecil; @@ -68,7 +69,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer ScopedWhereUsedAnalyzer analyzer; analyzer = new ScopedWhereUsedAnalyzer(analyzedType, FindReferencesInType); - return analyzer.PerformAnalysis(ct); + foreach (var child in analyzer.PerformAnalysis(ct).OrderBy(n => n.Text)) { + yield return child; + } } private IEnumerable FindReferencesInType(TypeDefinition type) @@ -80,23 +83,35 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer yield break; foreach (FieldDefinition field in type.Fields) { - if (TypeIsExposedBy(field)) - yield return new AnalyzedFieldTreeNode(field); + if (TypeIsExposedBy(field)) { + var node = new AnalyzedFieldTreeNode(field); + node.Language = this.Language; + yield return node; + } } foreach (PropertyDefinition property in type.Properties) { - if (TypeIsExposedBy(property)) - yield return new AnalyzedPropertyTreeNode(property); + if (TypeIsExposedBy(property)) { + var node = new AnalyzedPropertyTreeNode(property); + node.Language = this.Language; + yield return node; + } } foreach (EventDefinition eventDef in type.Events) { - if (TypeIsExposedBy(eventDef)) - yield return new AnalyzedEventTreeNode(eventDef); + if (TypeIsExposedBy(eventDef)) { + var node = new AnalyzedEventTreeNode(eventDef); + node.Language = this.Language; + yield return node; + } } foreach (MethodDefinition method in type.Methods) { - if (TypeIsExposedBy(method)) - yield return new AnalyzedMethodTreeNode(method); + if (TypeIsExposedBy(method)) { + var node = new AnalyzedMethodTreeNode(method); + node.Language = this.Language; + yield return node; + } } } diff --git a/ILSpy/TreeNodes/Analyzer/AnalyzedTypeExtensionMethodsTreeNode.cs b/ILSpy/TreeNodes/Analyzer/AnalyzedTypeExtensionMethodsTreeNode.cs index 3bd42506c..605190b88 100644 --- a/ILSpy/TreeNodes/Analyzer/AnalyzedTypeExtensionMethodsTreeNode.cs +++ b/ILSpy/TreeNodes/Analyzer/AnalyzedTypeExtensionMethodsTreeNode.cs @@ -69,7 +69,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer ScopedWhereUsedAnalyzer analyzer; analyzer = new ScopedWhereUsedAnalyzer(analyzedType, FindReferencesInType); - return analyzer.PerformAnalysis(ct); + foreach (var child in analyzer.PerformAnalysis(ct).OrderBy(n => n.Text)) { + yield return child; + } } private IEnumerable FindReferencesInType(TypeDefinition type) @@ -79,7 +81,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer foreach (MethodDefinition method in type.Methods) { if (method.IsStatic && HasExtensionAttribute(method)) { if (method.HasParameters && method.Parameters[0].ParameterType.Resolve() == analyzedType) { - yield return new AnalyzedMethodTreeNode(method); + var node = new AnalyzedMethodTreeNode(method); + node.Language = this.Language; + yield return node; } } } diff --git a/ILSpy/TreeNodes/Analyzer/AnalyzedTypeInstantiationsTreeNode.cs b/ILSpy/TreeNodes/Analyzer/AnalyzedTypeInstantiationsTreeNode.cs index 0c2d9465a..10b477bcf 100644 --- a/ILSpy/TreeNodes/Analyzer/AnalyzedTypeInstantiationsTreeNode.cs +++ b/ILSpy/TreeNodes/Analyzer/AnalyzedTypeInstantiationsTreeNode.cs @@ -74,7 +74,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer ScopedWhereUsedAnalyzer analyzer; analyzer = new ScopedWhereUsedAnalyzer(analyzedType, FindReferencesInType); - return analyzer.PerformAnalysis(ct); + foreach (var child in analyzer.PerformAnalysis(ct).OrderBy(n => n.Text)) { + yield return child; + } } private IEnumerable FindReferencesInType(TypeDefinition type) @@ -102,8 +104,11 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer method.Body = null; - if (found) - yield return new AnalyzedMethodTreeNode(method); + if (found) { + var node = new AnalyzedMethodTreeNode(method); + node.Language = this.Language; + yield return node; + } } } diff --git a/ILSpy/TreeNodes/Analyzer/AnalyzedVirtualMethodUsedByTreeNode.cs b/ILSpy/TreeNodes/Analyzer/AnalyzedVirtualMethodUsedByTreeNode.cs index 26f5e4c65..f31eb5d5e 100644 --- a/ILSpy/TreeNodes/Analyzer/AnalyzedVirtualMethodUsedByTreeNode.cs +++ b/ILSpy/TreeNodes/Analyzer/AnalyzedVirtualMethodUsedByTreeNode.cs @@ -75,7 +75,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer InitializeAnalyzer(); var analyzer = new ScopedWhereUsedAnalyzer(analyzedMethod, FindReferencesInType); - foreach (var child in analyzer.PerformAnalysis(ct)) { + foreach (var child in analyzer.PerformAnalysis(ct).OrderBy(n => n.Text)) { yield return child; } @@ -95,8 +95,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer possibleTypes = new List(); TypeReference type = analyzedMethod.DeclaringType.BaseType; - while (type !=null) - { + while (type != null) { possibleTypes.Add(type); type = type.Resolve().BaseType; } @@ -120,8 +119,8 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer MethodReference mr = instr.Operand as MethodReference; if (mr != null && mr.Name == name) { // explicit call to the requested method - if (instr.OpCode.Code == Code.Call - && Helpers.IsReferencedBy(analyzedMethod.DeclaringType, mr.DeclaringType) + if (instr.OpCode.Code == Code.Call + && Helpers.IsReferencedBy(analyzedMethod.DeclaringType, mr.DeclaringType) && mr.Resolve() == analyzedMethod) { found = true; prefix = "(as base) "; @@ -147,7 +146,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer if (found) { MethodDefinition codeLocation = this.Language.GetOriginalCodeLocation(method) as MethodDefinition; if (codeLocation != null && !HasAlreadyBeenFound(codeLocation)) { - yield return new AnalyzedMethodTreeNode(codeLocation, prefix); + var node = new AnalyzedMethodTreeNode(codeLocation); + node.Language = this.Language; + yield return node; } } } From 43e867c2ae25f59ee3b95715104e16c94ec99d0c Mon Sep 17 00:00:00 2001 From: Ed Harvey Date: Sun, 29 May 2011 17:02:17 +1000 Subject: [PATCH 04/16] Implement filtering on DerivedTypesTreeNode. --- ILSpy/TreeNodes/DerivedTypesTreeNode.cs | 52 +++++++++++++++++++------ 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/ILSpy/TreeNodes/DerivedTypesTreeNode.cs b/ILSpy/TreeNodes/DerivedTypesTreeNode.cs index 2fd497395..9c3f77c70 100644 --- a/ILSpy/TreeNodes/DerivedTypesTreeNode.cs +++ b/ILSpy/TreeNodes/DerivedTypesTreeNode.cs @@ -105,13 +105,13 @@ namespace ICSharpCode.ILSpy.TreeNodes class DerivedTypesEntryNode : ILSpyTreeNode, IMemberTreeNode { - TypeDefinition def; + TypeDefinition type; AssemblyDefinition[] assemblies; ThreadingSupport threading; - public DerivedTypesEntryNode(TypeDefinition def, AssemblyDefinition[] assemblies) + public DerivedTypesEntryNode(TypeDefinition type, AssemblyDefinition[] assemblies) { - this.def = def; + this.type = type; this.assemblies = assemblies; this.LazyLoading = true; threading = new ThreadingSupport(); @@ -119,20 +119,50 @@ namespace ICSharpCode.ILSpy.TreeNodes public override bool ShowExpander { get { - return !def.IsSealed && base.ShowExpander; + return !type.IsSealed && base.ShowExpander; } } public override object Text { - get { return this.Language.TypeToString(def, true); } + get { return this.Language.TypeToString(type, true); } } public override object Icon { get { - return TypeTreeNode.GetIcon(def); + return TypeTreeNode.GetIcon(type); } } - + + public override FilterResult Filter(FilterSettings settings) + { + if (!settings.ShowInternalApi && !IsPublicAPI) + return FilterResult.Hidden; + if (settings.SearchTermMatches(type.Name)) { + if (type.IsNested && !settings.Language.ShowMember(type)) + return FilterResult.Hidden; + else + return FilterResult.Match; + } else { + return FilterResult.Recurse; + } + } + + public bool IsPublicAPI + { + get + { + switch (type.Attributes & TypeAttributes.VisibilityMask) { + case TypeAttributes.Public: + case TypeAttributes.NestedPublic: + case TypeAttributes.NestedFamily: + case TypeAttributes.NestedFamORAssem: + return true; + default: + return false; + } + } + } + protected override void LoadChildren() { threading.LoadChildren(this, FetchChildren); @@ -141,21 +171,21 @@ namespace ICSharpCode.ILSpy.TreeNodes IEnumerable FetchChildren(CancellationToken ct) { // FetchChildren() runs on the main thread; but the enumerator will be consumed on a background thread - return DerivedTypesTreeNode.FindDerivedTypes(def, assemblies, ct); + return DerivedTypesTreeNode.FindDerivedTypes(type, assemblies, ct); } public override void ActivateItem(System.Windows.RoutedEventArgs e) { - e.Handled = BaseTypesEntryNode.ActivateItem(this, def); + e.Handled = BaseTypesEntryNode.ActivateItem(this, type); } public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) { - language.WriteCommentLine(output, language.TypeToString(def, true)); + language.WriteCommentLine(output, language.TypeToString(type, true)); } MemberReference IMemberTreeNode.Member { - get { return def; } + get { return type; } } } } From 17f8c8f1efaa4c364babb711165056a85da13500 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Wed, 25 May 2011 20:37:54 +0200 Subject: [PATCH 05/16] convert elements with no value to empty elements --- ILSpy.BamlDecompiler/BamlResourceEntryNode.cs | 16 +++++++++++++++- .../XmlBamlReader.cs | 3 --- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/ILSpy.BamlDecompiler/BamlResourceEntryNode.cs b/ILSpy.BamlDecompiler/BamlResourceEntryNode.cs index cce7182f9..79b715105 100644 --- a/ILSpy.BamlDecompiler/BamlResourceEntryNode.cs +++ b/ILSpy.BamlDecompiler/BamlResourceEntryNode.cs @@ -3,11 +3,12 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; using System.Threading.Tasks; +using System.Xml; using System.Xml.Linq; - using ICSharpCode.AvalonEdit.Highlighting; using ICSharpCode.ILSpy.TextView; using ICSharpCode.ILSpy.TreeNodes; @@ -54,8 +55,21 @@ namespace ILSpy.BamlDecompiler using (XmlBamlReader reader = new XmlBamlReader(bamlStream, new CecilTypeResolver(asm))) xamlDocument = XDocument.Load(reader); + ConvertToEmptyElements(xamlDocument.Root); + output.Write(xamlDocument.ToString()); return true; } + + void ConvertToEmptyElements(XElement element) + { + foreach (var el in element.Elements()) { + if (!el.IsEmpty && !el.HasElements && el.Value == "") { + el.RemoveNodes(); + continue; + } + ConvertToEmptyElements(el); + } + } } } \ No newline at end of file diff --git a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlReader.cs b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlReader.cs index 93ed72c66..7f6fbbfc5 100644 --- a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlReader.cs +++ b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlReader.cs @@ -1057,9 +1057,6 @@ namespace Ricciolo.StylesExplorer.MarkupReflection private void ReadPropertyComplexEnd() { - if (!(elements.Peek() is XmlBamlPropertyElement)) - throw new InvalidCastException(); - XmlBamlPropertyElement propertyElement = (XmlBamlPropertyElement) elements.Peek(); CloseElement(); From 7c4b9448635e040b191a063521100ed53678c9b2 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 28 May 2011 21:06:08 +0200 Subject: [PATCH 06/16] implement MoveNamespacesToRoot and add Unit Tests --- ILSpy.BamlDecompiler/BamlResourceEntryNode.cs | 49 ++++++-- ILSpy.BamlDecompiler/CecilTypeResolver.cs | 14 ++- ILSpy.BamlDecompiler/Extensions.cs | 22 ++++ .../ILSpy.BamlDecompiler.csproj | 1 + .../Properties/AssemblyInfo.cs | 3 + .../XmlBamlReader.cs | 8 +- ILSpy.BamlDecompiler/Tests/Cases/Simple.xaml | 3 + .../Tests/Cases/Simple.xaml.cs | 26 ++++ .../Tests/ILSpy.BamlDecompiler.Tests.csproj | 111 ++++++++++++++++++ .../Tests/Properties/AssemblyInfo.cs | 31 +++++ ILSpy.BamlDecompiler/Tests/TestRunner.cs | 67 +++++++++++ ILSpy.sln | 12 +- ILSpy/LoadedAssembly.cs | 5 + 13 files changed, 330 insertions(+), 22 deletions(-) create mode 100644 ILSpy.BamlDecompiler/Extensions.cs create mode 100644 ILSpy.BamlDecompiler/Tests/Cases/Simple.xaml create mode 100644 ILSpy.BamlDecompiler/Tests/Cases/Simple.xaml.cs create mode 100644 ILSpy.BamlDecompiler/Tests/ILSpy.BamlDecompiler.Tests.csproj create mode 100644 ILSpy.BamlDecompiler/Tests/Properties/AssemblyInfo.cs create mode 100644 ILSpy.BamlDecompiler/Tests/TestRunner.cs diff --git a/ILSpy.BamlDecompiler/BamlResourceEntryNode.cs b/ILSpy.BamlDecompiler/BamlResourceEntryNode.cs index 79b715105..71c5f4131 100644 --- a/ILSpy.BamlDecompiler/BamlResourceEntryNode.cs +++ b/ILSpy.BamlDecompiler/BamlResourceEntryNode.cs @@ -10,8 +10,10 @@ using System.Threading.Tasks; using System.Xml; using System.Xml.Linq; using ICSharpCode.AvalonEdit.Highlighting; +using ICSharpCode.ILSpy; using ICSharpCode.ILSpy.TextView; using ICSharpCode.ILSpy.TreeNodes; +using Mono.Cecil; using Ricciolo.StylesExplorer.MarkupReflection; namespace ILSpy.BamlDecompiler @@ -43,25 +45,56 @@ namespace ILSpy.BamlDecompiler return true; } + const string XWPFNamespace = "http://schemas.microsoft.com/winfx/2006/xaml"; + const string DefaultWPFNamespace = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"; + bool LoadBaml(AvalonEditTextOutput output) { var asm = this.Ancestors().OfType().FirstOrDefault().LoadedAssembly; - MemoryStream bamlStream = new MemoryStream(); Data.Position = 0; - Data.CopyTo(bamlStream); - bamlStream.Position = 0; + + XDocument xamlDocument = LoadIntoDocument(asm.GetAssemblyResolver(), asm.AssemblyDefinition, Data); + + output.Write(xamlDocument.ToString()); + return true; + } + + internal static XDocument LoadIntoDocument(IAssemblyResolver resolver, AssemblyDefinition asm, Stream stream) + { XDocument xamlDocument; - using (XmlBamlReader reader = new XmlBamlReader(bamlStream, new CecilTypeResolver(asm))) + using (XmlBamlReader reader = new XmlBamlReader(stream, new CecilTypeResolver(resolver, asm))) xamlDocument = XDocument.Load(reader); - ConvertToEmptyElements(xamlDocument.Root); + MoveNamespacesToRoot(xamlDocument); + return xamlDocument; + } + + static void MoveNamespacesToRoot(XDocument xamlDocument) + { + var additionalXmlns = new List { + new XAttribute("xmlns", DefaultWPFNamespace), + new XAttribute(XName.Get("x", XNamespace.Xmlns.NamespaceName), XWPFNamespace) + }; - output.Write(xamlDocument.ToString()); - return true; + foreach (var element in xamlDocument.Root.DescendantsAndSelf()) { + if (element.Name.NamespaceName != DefaultWPFNamespace && !additionalXmlns.Any(ka => ka.Value == element.Name.NamespaceName)) { + string newPrefix = new string(element.Name.LocalName.Where(c => char.IsUpper(c)).ToArray()).ToLowerInvariant(); + int current = additionalXmlns.Count(ka => ka.Name.Namespace == XNamespace.Xmlns && ka.Name.LocalName.TrimEnd(ch => char.IsNumber(ch)) == newPrefix); + if (current > 0) + newPrefix += (current + 1).ToString(); + XName defaultXmlns = XName.Get(newPrefix, XNamespace.Xmlns.NamespaceName); + if (element.Name.NamespaceName != DefaultWPFNamespace) + additionalXmlns.Add(new XAttribute(defaultXmlns, element.Name.NamespaceName)); + } + } + + foreach (var xmlns in additionalXmlns.Except(xamlDocument.Root.Attributes())) { + xamlDocument.Root.Add(xmlns); + } } - void ConvertToEmptyElements(XElement element) + static void ConvertToEmptyElements(XElement element) { foreach (var el in element.Elements()) { if (!el.IsEmpty && !el.HasElements && el.Value == "") { diff --git a/ILSpy.BamlDecompiler/CecilTypeResolver.cs b/ILSpy.BamlDecompiler/CecilTypeResolver.cs index 853025b06..90d0d0916 100644 --- a/ILSpy.BamlDecompiler/CecilTypeResolver.cs +++ b/ILSpy.BamlDecompiler/CecilTypeResolver.cs @@ -14,11 +14,13 @@ namespace ILSpy.BamlDecompiler /// public class CecilTypeResolver : ITypeResolver { - LoadedAssembly assembly; + IAssemblyResolver resolver; + AssemblyDefinition thisAssembly; - public CecilTypeResolver(LoadedAssembly assembly) + public CecilTypeResolver(IAssemblyResolver resolver, AssemblyDefinition asm) { - this.assembly = assembly; + this.resolver = resolver; + this.thisAssembly = asm; } public IType GetTypeByAssemblyQualifiedName(string name) @@ -31,12 +33,12 @@ namespace ILSpy.BamlDecompiler string fullName = name.Substring(0, comma); string assemblyName = name.Substring(comma + 1).Trim(); - var type = assembly.AssemblyDefinition.MainModule.GetType(fullName); + var type = thisAssembly.MainModule.GetType(fullName); if (type == null) { - var otherAssembly = assembly.LookupReferencedAssembly(assemblyName); + var otherAssembly = resolver.Resolve(assemblyName); if (otherAssembly == null) throw new Exception("could not resolve '" + assemblyName + "'!"); - type = otherAssembly.AssemblyDefinition.MainModule.GetType(fullName); + type = otherAssembly.MainModule.GetType(fullName); } return new CecilType(type); diff --git a/ILSpy.BamlDecompiler/Extensions.cs b/ILSpy.BamlDecompiler/Extensions.cs new file mode 100644 index 000000000..c76a581ea --- /dev/null +++ b/ILSpy.BamlDecompiler/Extensions.cs @@ -0,0 +1,22 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt) + +using System; +using System.Linq; + +namespace ILSpy.BamlDecompiler +{ + public static class Extensions + { + public static string TrimEnd(this string target, Func predicate) + { + if (target == null) + throw new ArgumentNullException("target"); + + while (predicate(target.LastOrDefault())) + target = target.Remove(target.Length - 1); + + return target; + } + } +} diff --git a/ILSpy.BamlDecompiler/ILSpy.BamlDecompiler.csproj b/ILSpy.BamlDecompiler/ILSpy.BamlDecompiler.csproj index 6514c632b..c87d30781 100644 --- a/ILSpy.BamlDecompiler/ILSpy.BamlDecompiler.csproj +++ b/ILSpy.BamlDecompiler/ILSpy.BamlDecompiler.csproj @@ -77,6 +77,7 @@ + diff --git a/ILSpy.BamlDecompiler/Properties/AssemblyInfo.cs b/ILSpy.BamlDecompiler/Properties/AssemblyInfo.cs index f28440c93..a2c459d27 100644 --- a/ILSpy.BamlDecompiler/Properties/AssemblyInfo.cs +++ b/ILSpy.BamlDecompiler/Properties/AssemblyInfo.cs @@ -3,6 +3,7 @@ using System; using System.Reflection; using System.Runtime.InteropServices; +using System.Runtime.CompilerServices; #endregion @@ -22,6 +23,8 @@ using System.Runtime.InteropServices; // If you need to expose a type to COM, use [ComVisible(true)] on that type. [assembly: ComVisible(false)] +[assembly: InternalsVisibleTo("ILSpy.BamlDecompiler.Tests")] + // The assembly version has following format : // // Major.Minor.Build.Revision diff --git a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlReader.cs b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlReader.cs index 7f6fbbfc5..28120b490 100644 --- a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlReader.cs +++ b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlReader.cs @@ -284,13 +284,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection else currentType = (BamlRecordType)type; - if (currentType.ToString().EndsWith("End")) - Debug.Unindent(); - - Debug.WriteLine(currentType); - - if (currentType.ToString().StartsWith("Start")) - Debug.Indent(); +// Debug.WriteLine(currentType); } private bool SetNextNode() diff --git a/ILSpy.BamlDecompiler/Tests/Cases/Simple.xaml b/ILSpy.BamlDecompiler/Tests/Cases/Simple.xaml new file mode 100644 index 000000000..e54fa6efa --- /dev/null +++ b/ILSpy.BamlDecompiler/Tests/Cases/Simple.xaml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/ILSpy.BamlDecompiler/Tests/Cases/Simple.xaml.cs b/ILSpy.BamlDecompiler/Tests/Cases/Simple.xaml.cs new file mode 100644 index 000000000..12770ff11 --- /dev/null +++ b/ILSpy.BamlDecompiler/Tests/Cases/Simple.xaml.cs @@ -0,0 +1,26 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; + +namespace ILSpy.BamlDecompiler.Tests.Cases +{ + /// + /// Interaction logic for Simple.xaml + /// + public partial class Simple : Window + { + public Simple() + { + InitializeComponent(); + } + } +} \ No newline at end of file diff --git a/ILSpy.BamlDecompiler/Tests/ILSpy.BamlDecompiler.Tests.csproj b/ILSpy.BamlDecompiler/Tests/ILSpy.BamlDecompiler.Tests.csproj new file mode 100644 index 000000000..4955c4e1b --- /dev/null +++ b/ILSpy.BamlDecompiler/Tests/ILSpy.BamlDecompiler.Tests.csproj @@ -0,0 +1,111 @@ + + + + {1169E6D1-1899-43D4-A500-07CE4235B388} + Debug + x86 + Library + ILSpy.BamlDecompiler.Tests + ILSpy.BamlDecompiler.Tests + v4.0 + Client + False + False + 4 + false + + + x86 + False + Auto + 4194304 + 4096 + + + ..\bin\Debug\ + true + Full + False + True + DEBUG;TRACE + + + ..\bin\Release\ + false + None + True + False + TRACE + + + + ..\..\packages\DiffLib.1.0.0.55\lib\net35-Client\DiffLib.dll + + + ..\..\ICSharpCode.Decompiler\Tests\nunit.framework.dll + + + + 3.0 + + + + 3.0 + + + + 3.5 + + + 4.0 + + + + 3.5 + + + + 3.0 + + + + + Simple.xaml + Code + + + + + + + {FEC0DA52-C4A6-4710-BE36-B484A20C5E22} + ICSharpCode.Decompiler.Tests + + + {1E85EFF9-E370-4683-83E4-8A3D063FF791} + ILSpy + + + {D68133BD-1E63-496E-9EDE-4FBDBF77B486} + Mono.Cecil + + + {DDE2A481-8271-4EAC-A330-8FA6A38D13D1} + ICSharpCode.TreeView + + + {A6BAD2BA-76BA-461C-8B6D-418607591247} + ILSpy.BamlDecompiler + + + + + + + + + Always + + + + \ No newline at end of file diff --git a/ILSpy.BamlDecompiler/Tests/Properties/AssemblyInfo.cs b/ILSpy.BamlDecompiler/Tests/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..30c5daa49 --- /dev/null +++ b/ILSpy.BamlDecompiler/Tests/Properties/AssemblyInfo.cs @@ -0,0 +1,31 @@ +#region Using directives + +using System; +using System.Reflection; +using System.Runtime.InteropServices; + +#endregion + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("ILSpy.BamlDecompiler.Tests")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ILSpy.BamlDecompiler.Tests")] +[assembly: AssemblyCopyright("Copyright 2011")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// This sets the default COM visibility of types in the assembly to invisible. +// If you need to expose a type to COM, use [ComVisible(true)] on that type. +[assembly: ComVisible(false)] + +// The assembly version has following format : +// +// Major.Minor.Build.Revision +// +// You can specify all the values or you can use the default the Revision and +// Build Numbers by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.*")] diff --git a/ILSpy.BamlDecompiler/Tests/TestRunner.cs b/ILSpy.BamlDecompiler/Tests/TestRunner.cs new file mode 100644 index 000000000..6579dd0a1 --- /dev/null +++ b/ILSpy.BamlDecompiler/Tests/TestRunner.cs @@ -0,0 +1,67 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Resources; +using System.Xml.Linq; +using ICSharpCode.Decompiler.Tests.Helpers; +using ICSharpCode.ILSpy; +using Mono.Cecil; +using NUnit.Framework; +using Ricciolo.StylesExplorer.MarkupReflection; + +namespace ILSpy.BamlDecompiler.Tests +{ + [TestFixture] + public class TestRunner + { + [Test] + public void Simple() + { + RunTest("cases/simple"); + } + + void RunTest(string name) + { + string asmPath = typeof(TestRunner).Assembly.Location; + var assembly = AssemblyDefinition.ReadAssembly(asmPath); + Resource res = assembly.MainModule.Resources.First(); + Stream bamlStream = LoadBaml(res, name + ".baml"); + Assert.IsNotNull(bamlStream); + XDocument document = BamlResourceEntryNode.LoadIntoDocument(new DefaultAssemblyResolver(), assembly, bamlStream); + string path = Path.Combine("..\\..\\Tests", name + ".xaml"); + + CodeAssert.AreEqual(document.ToString(), File.ReadAllText(path)); + } + + Stream LoadBaml(Resource res, string name) + { + EmbeddedResource er = res as EmbeddedResource; + if (er != null) { + Stream s = er.GetResourceStream(); + s.Position = 0; + ResourceReader reader; + try { + reader = new ResourceReader(s); + } + catch (ArgumentException) { + return null; + } + foreach (DictionaryEntry entry in reader.Cast().OrderBy(e => e.Key.ToString())) { + if (entry.Key.ToString() == name) { + if (entry.Value is Stream) + return (Stream)entry.Value; + if (entry.Value is byte[]) + return new MemoryStream((byte[])entry.Value); + } + } + } + + return null; + } + } +} diff --git a/ILSpy.sln b/ILSpy.sln index e3c407eb5..22cda9165 100644 --- a/ILSpy.sln +++ b/ILSpy.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2010 -# SharpDevelop 4.0.1.7146 +# SharpDevelop 4.1.0.7466-alpha Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "doc", "doc", "{F45DB999-7E72-4000-B5AD-3A7B485A0896}" ProjectSection(SolutionItems) = postProject doc\Command Line.txt = doc\Command Line.txt @@ -27,6 +27,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Cecil.Pdb", "Mono.Ceci EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ILSpy.BamlDecompiler", "ILSpy.BamlDecompiler\ILSpy.BamlDecompiler.csproj", "{A6BAD2BA-76BA-461C-8B6D-418607591247}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ILSpy.BamlDecompiler.Tests", "ILSpy.BamlDecompiler\Tests\ILSpy.BamlDecompiler.Tests.csproj", "{1169E6D1-1899-43D4-A500-07CE4235B388}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -115,6 +117,14 @@ Global {A6BAD2BA-76BA-461C-8B6D-418607591247}.Release|Any CPU.ActiveCfg = Release|Any CPU {A6BAD2BA-76BA-461C-8B6D-418607591247}.Release|x86.Build.0 = Release|x86 {A6BAD2BA-76BA-461C-8B6D-418607591247}.Release|x86.ActiveCfg = Release|x86 + {1169E6D1-1899-43D4-A500-07CE4235B388}.Debug|Any CPU.Build.0 = Debug|x86 + {1169E6D1-1899-43D4-A500-07CE4235B388}.Debug|Any CPU.ActiveCfg = Debug|x86 + {1169E6D1-1899-43D4-A500-07CE4235B388}.Debug|x86.Build.0 = Debug|x86 + {1169E6D1-1899-43D4-A500-07CE4235B388}.Debug|x86.ActiveCfg = Debug|x86 + {1169E6D1-1899-43D4-A500-07CE4235B388}.Release|Any CPU.Build.0 = Release|x86 + {1169E6D1-1899-43D4-A500-07CE4235B388}.Release|Any CPU.ActiveCfg = Release|x86 + {1169E6D1-1899-43D4-A500-07CE4235B388}.Release|x86.Build.0 = Release|x86 + {1169E6D1-1899-43D4-A500-07CE4235B388}.Release|x86.ActiveCfg = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/ILSpy/LoadedAssembly.cs b/ILSpy/LoadedAssembly.cs index 8285be9ae..2bb0ae05d 100644 --- a/ILSpy/LoadedAssembly.cs +++ b/ILSpy/LoadedAssembly.cs @@ -171,6 +171,11 @@ namespace ICSharpCode.ILSpy } } + public IAssemblyResolver GetAssemblyResolver() + { + return new MyAssemblyResolver(this); + } + public LoadedAssembly LookupReferencedAssembly(string fullName) { foreach (LoadedAssembly asm in assemblyList.GetAssemblies()) { From 963f8ff94514973aeb6bcf9743ae9d20022e46d2 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 28 May 2011 22:14:16 +0200 Subject: [PATCH 07/16] implemented using base type as root node in decompiled BAML --- ILSpy.BamlDecompiler/CecilType.cs | 10 ++++++ ILSpy.BamlDecompiler/CecilTypeResolver.cs | 11 ++++++ .../AppDomainTypeResolver.cs | 11 ++++++ .../DotNetType.cs | 6 ++++ .../IType.cs | 3 +- .../ITypeResolver.cs | 2 ++ .../KnownInfo.cs | 36 +++++++++++++++---- .../XmlBamlReader.cs | 18 +++++++++- 8 files changed, 89 insertions(+), 8 deletions(-) diff --git a/ILSpy.BamlDecompiler/CecilType.cs b/ILSpy.BamlDecompiler/CecilType.cs index 41a0fc203..e84f95938 100644 --- a/ILSpy.BamlDecompiler/CecilType.cs +++ b/ILSpy.BamlDecompiler/CecilType.cs @@ -67,5 +67,15 @@ namespace ILSpy.BamlDecompiler { return string.Format("[CecilType Type={0}]", type); } + + public IType BaseType { + get { + TypeDefinition td = type.BaseType.Resolve(); + if (td == null) + throw new Exception("could not resolve '" + type.BaseType.FullName + "'!"); + + return new CecilType(td); + } + } } } diff --git a/ILSpy.BamlDecompiler/CecilTypeResolver.cs b/ILSpy.BamlDecompiler/CecilTypeResolver.cs index 90d0d0916..702c37c38 100644 --- a/ILSpy.BamlDecompiler/CecilTypeResolver.cs +++ b/ILSpy.BamlDecompiler/CecilTypeResolver.cs @@ -23,6 +23,11 @@ namespace ILSpy.BamlDecompiler this.thisAssembly = asm; } + public bool IsLocalAssembly(string name) + { + return name == this.thisAssembly.Name.Name; + } + public IType GetTypeByAssemblyQualifiedName(string name) { int comma = name.IndexOf(','); @@ -51,5 +56,11 @@ namespace ILSpy.BamlDecompiler return new CecilDependencyPropertyDescriptor(name, ((CecilType)ownerType).type); } + + public string RuntimeVersion { + get { + return thisAssembly.MainModule.Runtime.ToString(); + } + } } } diff --git a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/AppDomainTypeResolver.cs b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/AppDomainTypeResolver.cs index 9cc329459..b33379323 100644 --- a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/AppDomainTypeResolver.cs +++ b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/AppDomainTypeResolver.cs @@ -131,6 +131,17 @@ namespace Ricciolo.StylesExplorer.MarkupReflection return null; } } + + public bool IsLocalAssembly(string name) + { + return false; + } + + public string RuntimeVersion { + get { + throw new NotImplementedException(); + } + } #endregion diff --git a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/DotNetType.cs b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/DotNetType.cs index 1dbf1b21a..313863bd0 100644 --- a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/DotNetType.cs +++ b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/DotNetType.cs @@ -42,6 +42,12 @@ namespace Ricciolo.StylesExplorer.MarkupReflection if (_type == null) return false; return this._type.Equals(((DotNetType)type).Type); } + + public IType BaseType { + get { + return new DotNetType(this._type.BaseType.AssemblyQualifiedName); + } + } #endregion diff --git a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/IType.cs b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/IType.cs index 7ec8c79e4..b420bf480 100644 --- a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/IType.cs +++ b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/IType.cs @@ -8,10 +8,11 @@ using System.Text; namespace Ricciolo.StylesExplorer.MarkupReflection { /// - /// Interface rappresenting a DotNet type + /// Interface representing a DotNet type /// public interface IType { + IType BaseType { get; } string AssemblyQualifiedName { get; } bool IsSubclassOf(IType type); bool Equals(IType type); diff --git a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/ITypeResolver.cs b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/ITypeResolver.cs index 71e802a61..993126b32 100644 --- a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/ITypeResolver.cs +++ b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/ITypeResolver.cs @@ -9,6 +9,8 @@ namespace Ricciolo.StylesExplorer.MarkupReflection { public interface ITypeResolver { + string RuntimeVersion { get; } + bool IsLocalAssembly(string name); IType GetTypeByAssemblyQualifiedName(string name); IDependencyPropertyDescriptor GetDependencyPropertyDescriptor(string name, IType ownerType, IType targetType); } diff --git a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/KnownInfo.cs b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/KnownInfo.cs index e58762f41..81d7bea20 100644 --- a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/KnownInfo.cs +++ b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/KnownInfo.cs @@ -34,12 +34,16 @@ namespace Ricciolo.StylesExplorer.MarkupReflection public KnownInfo(ITypeResolver resolver) { - KnownAssemblyTable = new string[5]; - KnownAssemblyTable[0] = "PresentationFramework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"; - KnownAssemblyTable[1] = "PresentationCore, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"; - KnownAssemblyTable[2] = "mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; - KnownAssemblyTable[3] = "System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; - KnownAssemblyTable[4] = "WindowBase, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"; + switch (resolver.RuntimeVersion) { + case "Net_2_0": + LoadKnownAssemblies30(); + break; + case "Net_4_0": + LoadKnownAssemblies40(); + break; + default: + throw new NotSupportedException(); + } KnownTypeTable = new TypeDeclaration[760]; KnownTypeTable[0] = new TypeDeclaration(resolver, string.Empty, string.Empty, 0); @@ -1305,6 +1309,26 @@ namespace Ricciolo.StylesExplorer.MarkupReflection KnownResourceTable.Add(0xa9, new ResourceName("SystemParameters.WorkArea")); } + void LoadKnownAssemblies30() + { + KnownAssemblyTable = new string[5]; + KnownAssemblyTable[0] = "PresentationFramework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"; + KnownAssemblyTable[1] = "PresentationCore, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"; + KnownAssemblyTable[2] = "mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; + KnownAssemblyTable[3] = "System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; + KnownAssemblyTable[4] = "WindowBase, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"; + } + + void LoadKnownAssemblies40() + { + KnownAssemblyTable = new string[5]; + KnownAssemblyTable[0] = "PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"; + KnownAssemblyTable[1] = "PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"; + KnownAssemblyTable[2] = "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; + KnownAssemblyTable[3] = "System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; + KnownAssemblyTable[4] = "WindowBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"; + } + #endregion public bool IsKnownType(string type) diff --git a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlReader.cs b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlReader.cs index 28120b490..ccb790df6 100644 --- a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlReader.cs +++ b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlReader.cs @@ -8,6 +8,7 @@ using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; +using System.Linq; using System.Reflection; using System.Text; using System.Xml; @@ -445,7 +446,6 @@ namespace Ricciolo.StylesExplorer.MarkupReflection break; default: throw new NotImplementedException("UnsupportedNode: " + currentType); - break; } } @@ -1182,6 +1182,12 @@ namespace Ricciolo.StylesExplorer.MarkupReflection } else element = new XmlBamlElement(); + + // the type is defined in the local assembly, i.e., the main assembly + // and this is the root element + if (_resolver.IsLocalAssembly(declaration.Assembly) && parentElement == null) { + declaration = GetKnownTypeDeclarationByName(declaration.Type.BaseType.AssemblyQualifiedName); + } element.TypeDeclaration = declaration; elements.Push(element); @@ -1563,6 +1569,16 @@ namespace Ricciolo.StylesExplorer.MarkupReflection return declaration; } + + TypeDeclaration GetKnownTypeDeclarationByName(string name) + { + foreach (var type in KnownInfo.KnownTypeTable) { + if (name == string.Format("{0}.{1}, {2}", type.Namespace, type.Name, type.Assembly)) + return type; + } + + throw new NotSupportedException(); + } internal string GetAssembly(short identifier) { From f20cd83e6d0c63baee5a34385e5478e1a1ec0b7f Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sun, 29 May 2011 09:19:15 +0200 Subject: [PATCH 08/16] implement x:Class detection in BamlDecompiler --- ILSpy.BamlDecompiler/BamlResourceEntryNode.cs | 14 +++----- .../ILSpy.BamlDecompiler.csproj | 1 + .../XmlBamlReader.cs | 29 ++++++++++++---- .../XmlBamlSimpleProperty.cs | 34 +++++++++++++++++++ 4 files changed, 62 insertions(+), 16 deletions(-) create mode 100644 ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlSimpleProperty.cs diff --git a/ILSpy.BamlDecompiler/BamlResourceEntryNode.cs b/ILSpy.BamlDecompiler/BamlResourceEntryNode.cs index 71c5f4131..b79492d1f 100644 --- a/ILSpy.BamlDecompiler/BamlResourceEntryNode.cs +++ b/ILSpy.BamlDecompiler/BamlResourceEntryNode.cs @@ -45,17 +45,11 @@ namespace ILSpy.BamlDecompiler return true; } - const string XWPFNamespace = "http://schemas.microsoft.com/winfx/2006/xaml"; - const string DefaultWPFNamespace = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"; - bool LoadBaml(AvalonEditTextOutput output) { var asm = this.Ancestors().OfType().FirstOrDefault().LoadedAssembly; Data.Position = 0; - - XDocument xamlDocument = LoadIntoDocument(asm.GetAssemblyResolver(), asm.AssemblyDefinition, Data); - output.Write(xamlDocument.ToString()); return true; } @@ -73,18 +67,18 @@ namespace ILSpy.BamlDecompiler static void MoveNamespacesToRoot(XDocument xamlDocument) { var additionalXmlns = new List { - new XAttribute("xmlns", DefaultWPFNamespace), - new XAttribute(XName.Get("x", XNamespace.Xmlns.NamespaceName), XWPFNamespace) + new XAttribute("xmlns", XmlBamlReader.DefaultWPFNamespace), + new XAttribute(XName.Get("x", XNamespace.Xmlns.NamespaceName), XmlBamlReader.XWPFNamespace) }; foreach (var element in xamlDocument.Root.DescendantsAndSelf()) { - if (element.Name.NamespaceName != DefaultWPFNamespace && !additionalXmlns.Any(ka => ka.Value == element.Name.NamespaceName)) { + if (element.Name.NamespaceName != XmlBamlReader.DefaultWPFNamespace && !additionalXmlns.Any(ka => ka.Value == element.Name.NamespaceName)) { string newPrefix = new string(element.Name.LocalName.Where(c => char.IsUpper(c)).ToArray()).ToLowerInvariant(); int current = additionalXmlns.Count(ka => ka.Name.Namespace == XNamespace.Xmlns && ka.Name.LocalName.TrimEnd(ch => char.IsNumber(ch)) == newPrefix); if (current > 0) newPrefix += (current + 1).ToString(); XName defaultXmlns = XName.Get(newPrefix, XNamespace.Xmlns.NamespaceName); - if (element.Name.NamespaceName != DefaultWPFNamespace) + if (element.Name.NamespaceName != XmlBamlReader.DefaultWPFNamespace) additionalXmlns.Add(new XAttribute(defaultXmlns, element.Name.NamespaceName)); } } diff --git a/ILSpy.BamlDecompiler/ILSpy.BamlDecompiler.csproj b/ILSpy.BamlDecompiler/ILSpy.BamlDecompiler.csproj index c87d30781..a681f07fd 100644 --- a/ILSpy.BamlDecompiler/ILSpy.BamlDecompiler.csproj +++ b/ILSpy.BamlDecompiler/ILSpy.BamlDecompiler.csproj @@ -98,6 +98,7 @@ + diff --git a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlReader.cs b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlReader.cs index ccb790df6..6417549f7 100644 --- a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlReader.cs +++ b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlReader.cs @@ -55,6 +55,9 @@ namespace Ricciolo.StylesExplorer.MarkupReflection private readonly TypeDeclaration XamlTypeDeclaration; private readonly XmlNameTable _nameTable = new NameTable(); private IDictionary _rootNamespaces; + + public const string XWPFNamespace = "http://schemas.microsoft.com/winfx/2006/xaml"; + public const string DefaultWPFNamespace = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"; #endregion @@ -160,7 +163,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection public override bool MoveToFirstAttribute() { intoAttribute = false; - if (nodes.Count > 0 && nodes.Peek() is XmlBamlProperty) + if (nodes.Count > 0 && (nodes.Peek() is XmlBamlProperty || nodes.Peek() is XmlBamlSimpleProperty)) { _currentNode = nodes.Dequeue(); return true; @@ -179,7 +182,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection public override bool MoveToNextAttribute() { intoAttribute = false; - if (nodes.Count > 0 && nodes.Peek() is XmlBamlProperty) + if (nodes.Count > 0 && (nodes.Peek() is XmlBamlProperty || nodes.Peek() is XmlBamlSimpleProperty)) { _currentNode = nodes.Dequeue(); return true; @@ -197,7 +200,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection /// public override bool MoveToElement() { - while (nodes.Peek() is XmlBamlProperty) + while (nodes.Peek() is XmlBamlProperty || nodes.Peek() is XmlBamlSimpleProperty) { nodes.Dequeue(); } @@ -295,6 +298,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection _currentNode = nodes.Dequeue(); if ((_currentNode is XmlBamlProperty)) continue; + if ((_currentNode is XmlBamlSimpleProperty)) continue; if (this.NodeType == XmlNodeType.EndElement) { @@ -580,7 +584,10 @@ namespace Ricciolo.StylesExplorer.MarkupReflection String localName = String.Empty; XmlBamlNode node = this.CurrentNode; - if (node is XmlBamlProperty) + if (node is XmlBamlSimpleProperty) { + var simpleNode = (XmlBamlSimpleProperty)node; + localName = simpleNode.LocalName; + } else if (node is XmlBamlProperty) { PropertyDeclaration pd = ((XmlBamlProperty)node).PropertyDeclaration; localName = FormatPropertyDeclaration(pd, false, true, true); @@ -1185,13 +1192,19 @@ namespace Ricciolo.StylesExplorer.MarkupReflection // the type is defined in the local assembly, i.e., the main assembly // and this is the root element + TypeDeclaration oldDeclaration = null; if (_resolver.IsLocalAssembly(declaration.Assembly) && parentElement == null) { + oldDeclaration = declaration; declaration = GetKnownTypeDeclarationByName(declaration.Type.BaseType.AssemblyQualifiedName); } element.TypeDeclaration = declaration; elements.Push(element); nodes.Enqueue(element); + + if (oldDeclaration != null) { + nodes.Enqueue(new XmlBamlSimpleProperty(XWPFNamespace, "Class", string.Format("{0}.{1}", oldDeclaration.Namespace, oldDeclaration.Name))); + } if (parentElement != null && complexPropertyOpened == 0) { @@ -1609,7 +1622,9 @@ namespace Ricciolo.StylesExplorer.MarkupReflection TypeDeclaration declaration; XmlBamlNode node = this.CurrentNode; - if (node is XmlBamlProperty) + if (node is XmlBamlSimpleProperty) + return ((XmlBamlSimpleProperty)node).NamespaceName; + else if (node is XmlBamlProperty) { declaration = ((XmlBamlProperty)node).PropertyDeclaration.DeclaringType; TypeDeclaration elementDeclaration = this.readingElements.Peek().TypeDeclaration; @@ -1685,7 +1700,9 @@ namespace Ricciolo.StylesExplorer.MarkupReflection get { XmlBamlNode node = this.CurrentNode; - if (node is XmlBamlProperty) + if (node is XmlBamlSimpleProperty) + return ((XmlBamlSimpleProperty)node).Value; + else if (node is XmlBamlProperty) return ((XmlBamlProperty)node).Value.ToString(); else if (node is XmlBamlText) return ((XmlBamlText)node).Text; diff --git a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlSimpleProperty.cs b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlSimpleProperty.cs new file mode 100644 index 000000000..be00e41e1 --- /dev/null +++ b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlSimpleProperty.cs @@ -0,0 +1,34 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt) + +using System; +using System.Collections.Generic; +using System.Text; +using System.Xml; + +namespace Ricciolo.StylesExplorer.MarkupReflection +{ + class XmlBamlSimpleProperty : XmlBamlNode + { + public string NamespaceName { get; private set; } + public string LocalName { get; private set; } + public string Value { get; private set; } + + public XmlBamlSimpleProperty(string namespaceName, string localName, string value) + { + if (string.IsNullOrWhiteSpace(namespaceName)) + throw new ArgumentException("namespaceName"); + if (string.IsNullOrWhiteSpace(localName)) + throw new ArgumentException("localName"); + if (value == null) + throw new ArgumentNullException("value"); + this.NamespaceName = namespaceName; + this.LocalName = localName; + this.Value = value; + } + + public override XmlNodeType NodeType { + get { return XmlNodeType.Attribute; } + } + } +} From 9af1c54fe295080cdfb6ec37d4b1413b9e238582 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sun, 29 May 2011 09:29:41 +0200 Subject: [PATCH 09/16] add simple unit test for ResourceDictionary --- ILSpy.BamlDecompiler/Tests/Cases/Simple.xaml | 2 +- ILSpy.BamlDecompiler/Tests/Cases/SimpleDictionary.xaml | 1 + .../Tests/ILSpy.BamlDecompiler.Tests.csproj | 1 + ILSpy.BamlDecompiler/Tests/TestRunner.cs | 6 ++++++ 4 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 ILSpy.BamlDecompiler/Tests/Cases/SimpleDictionary.xaml diff --git a/ILSpy.BamlDecompiler/Tests/Cases/Simple.xaml b/ILSpy.BamlDecompiler/Tests/Cases/Simple.xaml index e54fa6efa..ab5d5afc6 100644 --- a/ILSpy.BamlDecompiler/Tests/Cases/Simple.xaml +++ b/ILSpy.BamlDecompiler/Tests/Cases/Simple.xaml @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/ILSpy.BamlDecompiler/Tests/Cases/SimpleDictionary.xaml b/ILSpy.BamlDecompiler/Tests/Cases/SimpleDictionary.xaml new file mode 100644 index 000000000..4eb8fb3c7 --- /dev/null +++ b/ILSpy.BamlDecompiler/Tests/Cases/SimpleDictionary.xaml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ILSpy.BamlDecompiler/Tests/ILSpy.BamlDecompiler.Tests.csproj b/ILSpy.BamlDecompiler/Tests/ILSpy.BamlDecompiler.Tests.csproj index 4955c4e1b..975dfc6ee 100644 --- a/ILSpy.BamlDecompiler/Tests/ILSpy.BamlDecompiler.Tests.csproj +++ b/ILSpy.BamlDecompiler/Tests/ILSpy.BamlDecompiler.Tests.csproj @@ -106,6 +106,7 @@ Always + \ No newline at end of file diff --git a/ILSpy.BamlDecompiler/Tests/TestRunner.cs b/ILSpy.BamlDecompiler/Tests/TestRunner.cs index 6579dd0a1..441116873 100644 --- a/ILSpy.BamlDecompiler/Tests/TestRunner.cs +++ b/ILSpy.BamlDecompiler/Tests/TestRunner.cs @@ -25,6 +25,12 @@ namespace ILSpy.BamlDecompiler.Tests RunTest("cases/simple"); } + [Test] + public void SimpleDictionary() + { + RunTest("cases/simpledictionary"); + } + void RunTest(string name) { string asmPath = typeof(TestRunner).Assembly.Location; From e32c170ec48d4f6333615fd156bd320251a8a902 Mon Sep 17 00:00:00 2001 From: Ed Harvey Date: Sun, 29 May 2011 17:53:33 +1000 Subject: [PATCH 10/16] Move classes to separate files. --- ILSpy/ILSpy.csproj | 3 + ILSpy/TreeNodes/BaseTypesEntryNode.cs | 104 +++++++++++++++++++++ ILSpy/TreeNodes/BaseTypesTreeNode.cs | 96 +++----------------- ILSpy/TreeNodes/DerivedTypesEntryNode.cs | 111 +++++++++++++++++++++++ ILSpy/TreeNodes/DerivedTypesTreeNode.cs | 111 +++-------------------- ILSpy/TreeNodes/FilterResult.cs | 40 ++++++++ ILSpy/TreeNodes/ILSpyTreeNode.cs | 58 ++++-------- 7 files changed, 302 insertions(+), 221 deletions(-) create mode 100644 ILSpy/TreeNodes/BaseTypesEntryNode.cs create mode 100644 ILSpy/TreeNodes/DerivedTypesEntryNode.cs create mode 100644 ILSpy/TreeNodes/FilterResult.cs diff --git a/ILSpy/ILSpy.csproj b/ILSpy/ILSpy.csproj index 1589927c7..8956512a1 100644 --- a/ILSpy/ILSpy.csproj +++ b/ILSpy/ILSpy.csproj @@ -158,6 +158,9 @@ + + + diff --git a/ILSpy/TreeNodes/BaseTypesEntryNode.cs b/ILSpy/TreeNodes/BaseTypesEntryNode.cs new file mode 100644 index 000000000..821784ccb --- /dev/null +++ b/ILSpy/TreeNodes/BaseTypesEntryNode.cs @@ -0,0 +1,104 @@ +// 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.Linq; +using ICSharpCode.Decompiler; +using ICSharpCode.TreeView; +using Mono.Cecil; + +namespace ICSharpCode.ILSpy.TreeNodes +{ + sealed class BaseTypesEntryNode : ILSpyTreeNode, IMemberTreeNode + { + private TypeReference tr; + private TypeDefinition def; + private bool isInterface; + + public BaseTypesEntryNode(TypeReference tr, bool isInterface) + { + if (tr == null) + throw new ArgumentNullException("tr"); + this.tr = tr; + this.def = tr.Resolve(); + this.isInterface = isInterface; + this.LazyLoading = true; + } + + public override bool ShowExpander + { + get { return def != null && (def.BaseType != null || def.HasInterfaces); } + } + + public override object Text + { + get { return this.Language.TypeToString(tr, true); } + } + + public override object Icon + { + get + { + if (def != null) + return TypeTreeNode.GetIcon(def); + else + return isInterface ? Images.Interface : Images.Class; + } + } + + protected override void LoadChildren() + { + if (def != null) + BaseTypesTreeNode.AddBaseTypes(this.Children, def); + } + + public override void ActivateItem(System.Windows.RoutedEventArgs e) + { + // on item activation, try to resolve once again (maybe the user loaded the assembly in the meantime) + if (def == null) { + def = tr.Resolve(); + if (def != null) + this.LazyLoading = true; + // re-load children + } + e.Handled = ActivateItem(this, def); + } + + internal static bool ActivateItem(SharpTreeNode node, TypeDefinition def) + { + if (def != null) { + var assemblyListNode = node.Ancestors().OfType().FirstOrDefault(); + if (assemblyListNode != null) { + assemblyListNode.Select(assemblyListNode.FindTypeNode(def)); + return true; + } + } + return false; + } + + public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) + { + language.WriteCommentLine(output, language.TypeToString(tr, true)); + } + + MemberReference IMemberTreeNode.Member + { + get { return tr; } + } + } +} diff --git a/ILSpy/TreeNodes/BaseTypesTreeNode.cs b/ILSpy/TreeNodes/BaseTypesTreeNode.cs index 0209f7410..610458cdf 100644 --- a/ILSpy/TreeNodes/BaseTypesTreeNode.cs +++ b/ILSpy/TreeNodes/BaseTypesTreeNode.cs @@ -17,9 +17,7 @@ // DEALINGS IN THE SOFTWARE. using System; -using System.Linq; using System.Windows.Threading; - using ICSharpCode.Decompiler; using ICSharpCode.TreeView; using Mono.Cecil; @@ -32,26 +30,28 @@ namespace ICSharpCode.ILSpy.TreeNodes sealed class BaseTypesTreeNode : ILSpyTreeNode { readonly TypeDefinition type; - + public BaseTypesTreeNode(TypeDefinition type) { this.type = type; this.LazyLoading = true; } - - public override object Text { + + public override object Text + { get { return "Base Types"; } } - - public override object Icon { + + public override object Icon + { get { return Images.SuperTypes; } } - + protected override void LoadChildren() { AddBaseTypes(this.Children, type); } - + internal static void AddBaseTypes(SharpTreeNodeCollection children, TypeDefinition type) { if (type.BaseType != null) @@ -60,7 +60,7 @@ namespace ICSharpCode.ILSpy.TreeNodes children.Add(new BaseTypesEntryNode(i, true)); } } - + public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) { App.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(EnsureLazyChildren)); @@ -69,78 +69,4 @@ namespace ICSharpCode.ILSpy.TreeNodes } } } - - sealed class BaseTypesEntryNode : ILSpyTreeNode, IMemberTreeNode - { - TypeReference tr; - TypeDefinition def; - bool isInterface; - - public BaseTypesEntryNode(TypeReference tr, bool isInterface) - { - if (tr == null) - throw new ArgumentNullException("tr"); - this.tr = tr; - this.def = tr.Resolve(); - this.isInterface = isInterface; - this.LazyLoading = true; - } - - public override bool ShowExpander { - get { - return def != null && (def.BaseType != null || def.HasInterfaces); - } - } - - public override object Text { - get { return this.Language.TypeToString(tr, true); } - } - - public override object Icon { - get { - if (def != null) - return TypeTreeNode.GetIcon(def); - else - return isInterface ? Images.Interface : Images.Class; - } - } - - protected override void LoadChildren() - { - if (def != null) - BaseTypesTreeNode.AddBaseTypes(this.Children, def); - } - - public override void ActivateItem(System.Windows.RoutedEventArgs e) - { - // on item activation, try to resolve once again (maybe the user loaded the assembly in the meantime) - if (def == null) { - def = tr.Resolve(); - if (def != null) - this.LazyLoading = true; // re-load children - } - e.Handled = ActivateItem(this, def); - } - - internal static bool ActivateItem(SharpTreeNode node, TypeDefinition def) - { - if (def != null) { - var assemblyListNode = node.Ancestors().OfType().FirstOrDefault(); - if (assemblyListNode != null) { - assemblyListNode.Select(assemblyListNode.FindTypeNode(def)); - return true; - } - } - return false; - } - - public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) - { - language.WriteCommentLine(output, language.TypeToString(tr, true)); - } - - MemberReference IMemberTreeNode.Member { - get { return tr; } - } - } -} +} \ No newline at end of file diff --git a/ILSpy/TreeNodes/DerivedTypesEntryNode.cs b/ILSpy/TreeNodes/DerivedTypesEntryNode.cs new file mode 100644 index 000000000..326418633 --- /dev/null +++ b/ILSpy/TreeNodes/DerivedTypesEntryNode.cs @@ -0,0 +1,111 @@ +// 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.Threading; +using ICSharpCode.Decompiler; +using Mono.Cecil; + +namespace ICSharpCode.ILSpy.TreeNodes +{ + class DerivedTypesEntryNode : ILSpyTreeNode, IMemberTreeNode + { + private TypeDefinition type; + private AssemblyDefinition[] assemblies; + private ThreadingSupport threading; + + public DerivedTypesEntryNode(TypeDefinition type, AssemblyDefinition[] assemblies) + { + this.type = type; + this.assemblies = assemblies; + this.LazyLoading = true; + threading = new ThreadingSupport(); + } + + public override bool ShowExpander + { + get { return !type.IsSealed && base.ShowExpander; } + } + + public override object Text + { + get { return this.Language.TypeToString(type, true); } + } + + public override object Icon + { + get { return TypeTreeNode.GetIcon(type); } + } + + public override FilterResult Filter(FilterSettings settings) + { + if (!settings.ShowInternalApi && !IsPublicAPI) + return FilterResult.Hidden; + if (settings.SearchTermMatches(type.Name)) { + if (type.IsNested && !settings.Language.ShowMember(type)) + return FilterResult.Hidden; + else + return FilterResult.Match; + } else + return FilterResult.Recurse; + } + + public bool IsPublicAPI + { + get + { + switch (type.Attributes & TypeAttributes.VisibilityMask) { + case TypeAttributes.Public: + case TypeAttributes.NestedPublic: + case TypeAttributes.NestedFamily: + case TypeAttributes.NestedFamORAssem: + return true; + default: + return false; + } + } + } + + protected override void LoadChildren() + { + threading.LoadChildren(this, FetchChildren); + } + + IEnumerable FetchChildren(CancellationToken ct) + { + // FetchChildren() runs on the main thread; but the enumerator will be consumed on a background thread + return DerivedTypesTreeNode.FindDerivedTypes(type, assemblies, ct); + } + + public override void ActivateItem(System.Windows.RoutedEventArgs e) + { + e.Handled = BaseTypesEntryNode.ActivateItem(this, type); + } + + public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) + { + language.WriteCommentLine(output, language.TypeToString(type, true)); + } + + MemberReference IMemberTreeNode.Member + { + get { return type; } + } + } +} diff --git a/ILSpy/TreeNodes/DerivedTypesTreeNode.cs b/ILSpy/TreeNodes/DerivedTypesTreeNode.cs index 9c3f77c70..0775f58e9 100644 --- a/ILSpy/TreeNodes/DerivedTypesTreeNode.cs +++ b/ILSpy/TreeNodes/DerivedTypesTreeNode.cs @@ -20,7 +20,6 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading; - using ICSharpCode.Decompiler; using ICSharpCode.NRefactory.Utils; using Mono.Cecil; @@ -35,7 +34,7 @@ namespace ICSharpCode.ILSpy.TreeNodes readonly AssemblyList list; readonly TypeDefinition type; ThreadingSupport threading; - + public DerivedTypesTreeNode(AssemblyList list, TypeDefinition type) { this.list = list; @@ -43,27 +42,29 @@ namespace ICSharpCode.ILSpy.TreeNodes this.LazyLoading = true; this.threading = new ThreadingSupport(); } - - public override object Text { + + public override object Text + { get { return "Derived Types"; } } - - public override object Icon { + + public override object Icon + { get { return Images.SubTypes; } } - + protected override void LoadChildren() { threading.LoadChildren(this, FetchChildren); } - + IEnumerable FetchChildren(CancellationToken cancellationToken) { // FetchChildren() runs on the main thread; but the enumerator will be consumed on a background thread var assemblies = list.GetAssemblies().Select(node => node.AssemblyDefinition).Where(asm => asm != null).ToArray(); return FindDerivedTypes(type, assemblies, cancellationToken); } - + internal static IEnumerable FindDerivedTypes(TypeDefinition type, AssemblyDefinition[] assemblies, CancellationToken cancellationToken) { foreach (AssemblyDefinition asm in assemblies) { @@ -80,7 +81,7 @@ namespace ICSharpCode.ILSpy.TreeNodes } } } - + static bool IsSameType(TypeReference typeRef, TypeDefinition type) { if (typeRef.FullName == type.FullName) @@ -96,96 +97,10 @@ namespace ICSharpCode.ILSpy.TreeNodes return false; return true; } - - public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) - { - threading.Decompile(language, output, options, EnsureLazyChildren); - } - } - - class DerivedTypesEntryNode : ILSpyTreeNode, IMemberTreeNode - { - TypeDefinition type; - AssemblyDefinition[] assemblies; - ThreadingSupport threading; - - public DerivedTypesEntryNode(TypeDefinition type, AssemblyDefinition[] assemblies) - { - this.type = type; - this.assemblies = assemblies; - this.LazyLoading = true; - threading = new ThreadingSupport(); - } - - public override bool ShowExpander { - get { - return !type.IsSealed && base.ShowExpander; - } - } - - public override object Text { - get { return this.Language.TypeToString(type, true); } - } - - public override object Icon { - get { - return TypeTreeNode.GetIcon(type); - } - } - - public override FilterResult Filter(FilterSettings settings) - { - if (!settings.ShowInternalApi && !IsPublicAPI) - return FilterResult.Hidden; - if (settings.SearchTermMatches(type.Name)) { - if (type.IsNested && !settings.Language.ShowMember(type)) - return FilterResult.Hidden; - else - return FilterResult.Match; - } else { - return FilterResult.Recurse; - } - } - - public bool IsPublicAPI - { - get - { - switch (type.Attributes & TypeAttributes.VisibilityMask) { - case TypeAttributes.Public: - case TypeAttributes.NestedPublic: - case TypeAttributes.NestedFamily: - case TypeAttributes.NestedFamORAssem: - return true; - default: - return false; - } - } - } - protected override void LoadChildren() - { - threading.LoadChildren(this, FetchChildren); - } - - IEnumerable FetchChildren(CancellationToken ct) - { - // FetchChildren() runs on the main thread; but the enumerator will be consumed on a background thread - return DerivedTypesTreeNode.FindDerivedTypes(type, assemblies, ct); - } - - public override void ActivateItem(System.Windows.RoutedEventArgs e) - { - e.Handled = BaseTypesEntryNode.ActivateItem(this, type); - } - public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) { - language.WriteCommentLine(output, language.TypeToString(type, true)); - } - - MemberReference IMemberTreeNode.Member { - get { return type; } + threading.Decompile(language, output, options, EnsureLazyChildren); } } -} +} \ No newline at end of file diff --git a/ILSpy/TreeNodes/FilterResult.cs b/ILSpy/TreeNodes/FilterResult.cs new file mode 100644 index 000000000..106bed1e3 --- /dev/null +++ b/ILSpy/TreeNodes/FilterResult.cs @@ -0,0 +1,40 @@ +// 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. + +namespace ICSharpCode.ILSpy.TreeNodes +{ + public enum FilterResult + { + /// + /// Hides the node. + /// + Hidden, + /// + /// Shows the node (and resets the search term for child nodes). + /// + Match, + /// + /// Hides the node only if all children are hidden (and resets the search term for child nodes). + /// + MatchAndRecurse, + /// + /// Hides the node only if all children are hidden (doesn't reset the search term for child nodes). + /// + Recurse + } +} diff --git a/ILSpy/TreeNodes/ILSpyTreeNode.cs b/ILSpy/TreeNodes/ILSpyTreeNode.cs index ea92d8f22..8b4835fe5 100644 --- a/ILSpy/TreeNodes/ILSpyTreeNode.cs +++ b/ILSpy/TreeNodes/ILSpyTreeNode.cs @@ -17,7 +17,6 @@ // DEALINGS IN THE SOFTWARE. using System; -using System.Collections.ObjectModel; using System.Collections.Specialized; using System.ComponentModel; using System.Linq; @@ -33,21 +32,24 @@ namespace ICSharpCode.ILSpy.TreeNodes { FilterSettings filterSettings; bool childrenNeedFiltering; - - public FilterSettings FilterSettings { + + public FilterSettings FilterSettings + { get { return filterSettings; } - set { + set + { if (filterSettings != value) { filterSettings = value; OnFilterSettingsChanged(); } } } - - public Language Language { + + public Language Language + { get { return filterSettings != null ? filterSettings.Language : Languages.AllLanguages[0]; } } - + public virtual FilterResult Filter(FilterSettings settings) { if (string.IsNullOrEmpty(settings.SearchTerm)) @@ -55,15 +57,15 @@ namespace ICSharpCode.ILSpy.TreeNodes else return FilterResult.Hidden; } - + protected static object HighlightSearchMatch(string text, string suffix = null) { // TODO: implement highlighting the search match return text + suffix; } - + public abstract void Decompile(Language language, ITextOutput output, DecompilationOptions options); - + /// /// Used to implement special view logic for some items. /// This method is called on the main thread when only a single item is selected. @@ -73,7 +75,7 @@ namespace ICSharpCode.ILSpy.TreeNodes { return false; } - + /// /// Used to implement special save logic for some items. /// This method is called on the main thread when only a single item is selected. @@ -83,7 +85,7 @@ namespace ICSharpCode.ILSpy.TreeNodes { return false; } - + protected override void OnChildrenChanged(NotifyCollectionChangedEventArgs e) { if (e.NewItems != null) { @@ -96,7 +98,7 @@ namespace ICSharpCode.ILSpy.TreeNodes } base.OnChildrenChanged(e); } - + void ApplyFilterToChild(ILSpyTreeNode child) { FilterResult r; @@ -126,7 +128,7 @@ namespace ICSharpCode.ILSpy.TreeNodes throw new InvalidEnumArgumentException(); } } - + FilterSettings StripSearchTerm(FilterSettings filterSettings) { if (filterSettings == null) @@ -137,7 +139,7 @@ namespace ICSharpCode.ILSpy.TreeNodes } return filterSettings; } - + protected virtual void OnFilterSettingsChanged() { RaisePropertyChanged("Text"); @@ -148,13 +150,13 @@ namespace ICSharpCode.ILSpy.TreeNodes childrenNeedFiltering = true; } } - + protected override void OnIsVisibleChanged() { base.OnIsVisibleChanged(); EnsureChildrenFiltered(); } - + void EnsureChildrenFiltered() { EnsureLazyChildren(); @@ -165,24 +167,4 @@ namespace ICSharpCode.ILSpy.TreeNodes } } } - - public enum FilterResult - { - /// - /// Hides the node. - /// - Hidden, - /// - /// Shows the node (and resets the search term for child nodes). - /// - Match, - /// - /// Hides the node only if all children are hidden (and resets the search term for child nodes). - /// - MatchAndRecurse, - /// - /// Hides the node only if all children are hidden (doesn't reset the search term for child nodes). - /// - Recurse - } -} +} \ No newline at end of file From 7ddf11ef7505323c5cddbe2785a15d88fcb6587d Mon Sep 17 00:00:00 2001 From: Ed Harvey Date: Sun, 29 May 2011 18:36:47 +1000 Subject: [PATCH 11/16] Move classes to separate files & organize command functionality under one folder. --- ILSpy/Commands.cs | 178 ------------------ ILSpy/Commands/BrowseBackCommand.cs | 32 ++++ ILSpy/Commands/BrowseForwardCommand.cs | 32 ++++ ILSpy/Commands/CommandWrapper.cs | 58 ++++++ ILSpy/Commands/DecompileAllCommand.cs | 69 +++++++ ILSpy/Commands/ExitCommand.cs | 31 +++ .../{ => Commands}/ExportCommandAttribute.cs | 0 ILSpy/Commands/OpenCommand.cs | 33 ++++ ILSpy/Commands/OpenFromGacCommand.cs | 34 ++++ ILSpy/Commands/RefreshCommand.cs | 33 ++++ ILSpy/Commands/SaveCommand.cs | 32 ++++ ILSpy/Commands/SimpleCommand.cs | 39 ++++ ILSpy/ILSpy.csproj | 14 +- 13 files changed, 405 insertions(+), 180 deletions(-) delete mode 100644 ILSpy/Commands.cs create mode 100644 ILSpy/Commands/BrowseBackCommand.cs create mode 100644 ILSpy/Commands/BrowseForwardCommand.cs create mode 100644 ILSpy/Commands/CommandWrapper.cs create mode 100644 ILSpy/Commands/DecompileAllCommand.cs create mode 100644 ILSpy/Commands/ExitCommand.cs rename ILSpy/{ => Commands}/ExportCommandAttribute.cs (100%) create mode 100644 ILSpy/Commands/OpenCommand.cs create mode 100644 ILSpy/Commands/OpenFromGacCommand.cs create mode 100644 ILSpy/Commands/RefreshCommand.cs create mode 100644 ILSpy/Commands/SaveCommand.cs create mode 100644 ILSpy/Commands/SimpleCommand.cs diff --git a/ILSpy/Commands.cs b/ILSpy/Commands.cs deleted file mode 100644 index 8d89e9afc..000000000 --- a/ILSpy/Commands.cs +++ /dev/null @@ -1,178 +0,0 @@ -// 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.ComponentModel.Composition; -using System.Diagnostics; -using System.Linq; -using System.Threading.Tasks; -using System.Windows.Input; -using ICSharpCode.ILSpy.TextView; -using ICSharpCode.ILSpy.TreeNodes; - -namespace ICSharpCode.ILSpy -{ - [ExportMainMenuCommand(Menu = "_File", Header = "E_xit", MenuOrder = 99999, MenuCategory = "Exit")] - sealed class ExitCommand : SimpleCommand - { - public override void Execute(object parameter) - { - MainWindow.Instance.Close(); - } - } - - [ExportToolbarCommand(ToolTip = "Back", ToolbarIcon = "Images/Back.png", ToolbarCategory = "Navigation", ToolbarOrder = 0)] - sealed class BrowseBackCommand : CommandWrapper { - public BrowseBackCommand() : base(NavigationCommands.BrowseBack) {} - } - - [ExportToolbarCommand(ToolTip = "Forward", ToolbarIcon = "Images/Forward.png", ToolbarCategory = "Navigation", ToolbarOrder = 1)] - sealed class BrowseForwardCommand : CommandWrapper { - public BrowseForwardCommand() : base(NavigationCommands.BrowseForward) {} - } - - [ExportToolbarCommand(ToolTip = "Open", ToolbarIcon = "Images/Open.png", ToolbarCategory = "Open", ToolbarOrder = 0)] - [ExportMainMenuCommand(Menu = "_File", MenuIcon = "Images/Open.png", MenuCategory = "Open", MenuOrder = 0)] - sealed class OpenCommand : CommandWrapper { - public OpenCommand() : base(ApplicationCommands.Open) {} - } - - [ExportMainMenuCommand(Menu = "_File", Header = "Open from _GAC", MenuCategory = "Open", MenuOrder = 1)] - sealed class OpenFromGacCommand : SimpleCommand - { - public override void Execute(object parameter) - { - OpenFromGacDialog dlg = new OpenFromGacDialog(); - dlg.Owner = MainWindow.Instance; - if (dlg.ShowDialog() == true) { - MainWindow.Instance.OpenFiles(dlg.SelectedFileNames); - } - } - } - - [ExportToolbarCommand(ToolTip = "Reload all assemblies", ToolbarIcon = "Images/Refresh.png", ToolbarCategory = "Open", ToolbarOrder = 2)] - [ExportMainMenuCommand(Menu = "_File", Header = "Reload", MenuIcon = "Images/Refresh.png", MenuCategory = "Open", MenuOrder = 2)] - sealed class RefreshCommand : CommandWrapper { - public RefreshCommand() : base(NavigationCommands.Refresh) {} - } - - [ExportMainMenuCommand(Menu = "_File", Header = "_Save Code...", MenuIcon = "Images/SaveFile.png", MenuCategory = "Save", MenuOrder = 0)] - sealed class SaveCommand : CommandWrapper - { - public SaveCommand() : base(ApplicationCommands.Save) {} - } - - #if DEBUG - [ExportMainMenuCommand(Menu = "_File", Header = "DEBUG -- Decompile All", MenuCategory = "Open", MenuOrder = 2.5)] - sealed class DecompileAllCommand : SimpleCommand - { - public override bool CanExecute(object parameter) - { - return System.IO.Directory.Exists("c:\\temp\\decompiled"); - } - - public override void Execute(object parameter) - { - MainWindow.Instance.TextView.RunWithCancellation( - ct => Task.Factory.StartNew( - () => { - AvalonEditTextOutput output = new AvalonEditTextOutput(); - Parallel.ForEach( - MainWindow.Instance.CurrentAssemblyList.GetAssemblies(), - new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount, CancellationToken = ct }, - delegate (LoadedAssembly asm) { - if (!asm.HasLoadError) { - Stopwatch w = Stopwatch.StartNew(); - Exception exception = null; - using (var writer = new System.IO.StreamWriter("c:\\temp\\decompiled\\" + asm.ShortName + ".cs")) { - try { - new CSharpLanguage().DecompileAssembly( - asm, new Decompiler.PlainTextOutput(writer), - new DecompilationOptions { FullDecompilation = true, CancellationToken = ct }); - } catch (Exception ex) { - writer.WriteLine(ex.ToString()); - exception = ex; - } - } - lock (output) { - output.Write(asm.ShortName + " - " + w.Elapsed); - if (exception != null) { - output.Write(" - "); - output.Write(exception.GetType().Name); - } - output.WriteLine(); - } - } - }); - return output; - } - ), - task => MainWindow.Instance.TextView.ShowText(task.Result)); - } - } - #endif - - class CommandWrapper : ICommand - { - ICommand wrappedCommand; - - public CommandWrapper(ICommand wrappedCommand) - { - this.wrappedCommand = wrappedCommand; - } - - public static ICommand Unwrap(ICommand command) - { - CommandWrapper w = command as CommandWrapper; - if (w != null) - return w.wrappedCommand; - else - return command; - } - - public event EventHandler CanExecuteChanged { - add { wrappedCommand.CanExecuteChanged += value; } - remove { wrappedCommand.CanExecuteChanged -= value; } - } - - public void Execute(object parameter) - { - wrappedCommand.Execute(parameter); - } - - public bool CanExecute(object parameter) - { - return wrappedCommand.CanExecute(parameter); - } - } - - public abstract class SimpleCommand : ICommand - { - public event EventHandler CanExecuteChanged { - add { CommandManager.RequerySuggested += value; } - remove { CommandManager.RequerySuggested -= value; } - } - - public abstract void Execute(object parameter); - - public virtual bool CanExecute(object parameter) - { - return true; - } - } -} diff --git a/ILSpy/Commands/BrowseBackCommand.cs b/ILSpy/Commands/BrowseBackCommand.cs new file mode 100644 index 000000000..e5af95db8 --- /dev/null +++ b/ILSpy/Commands/BrowseBackCommand.cs @@ -0,0 +1,32 @@ +// 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.Windows.Input; + +namespace ICSharpCode.ILSpy +{ + [ExportToolbarCommand(ToolTip = "Back", ToolbarIcon = "Images/Back.png", ToolbarCategory = "Navigation", ToolbarOrder = 0)] + sealed class BrowseBackCommand : CommandWrapper + { + public BrowseBackCommand() + : base(NavigationCommands.BrowseBack) + { + } + } +} diff --git a/ILSpy/Commands/BrowseForwardCommand.cs b/ILSpy/Commands/BrowseForwardCommand.cs new file mode 100644 index 000000000..1e0db84a7 --- /dev/null +++ b/ILSpy/Commands/BrowseForwardCommand.cs @@ -0,0 +1,32 @@ +// 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.Windows.Input; + +namespace ICSharpCode.ILSpy +{ + [ExportToolbarCommand(ToolTip = "Forward", ToolbarIcon = "Images/Forward.png", ToolbarCategory = "Navigation", ToolbarOrder = 1)] + sealed class BrowseForwardCommand : CommandWrapper + { + public BrowseForwardCommand() + : base(NavigationCommands.BrowseForward) + { + } + } +} diff --git a/ILSpy/Commands/CommandWrapper.cs b/ILSpy/Commands/CommandWrapper.cs new file mode 100644 index 000000000..f3d89138c --- /dev/null +++ b/ILSpy/Commands/CommandWrapper.cs @@ -0,0 +1,58 @@ +// 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.Windows.Input; + +namespace ICSharpCode.ILSpy +{ + class CommandWrapper : ICommand + { + private ICommand wrappedCommand; + + public CommandWrapper(ICommand wrappedCommand) + { + this.wrappedCommand = wrappedCommand; + } + + public static ICommand Unwrap(ICommand command) + { + CommandWrapper w = command as CommandWrapper; + if (w != null) + return w.wrappedCommand; + else + return command; + } + + public event EventHandler CanExecuteChanged + { + add { wrappedCommand.CanExecuteChanged += value; } + remove { wrappedCommand.CanExecuteChanged -= value; } + } + + public void Execute(object parameter) + { + wrappedCommand.Execute(parameter); + } + + public bool CanExecute(object parameter) + { + return wrappedCommand.CanExecute(parameter); + } + } +} diff --git a/ILSpy/Commands/DecompileAllCommand.cs b/ILSpy/Commands/DecompileAllCommand.cs new file mode 100644 index 000000000..542c155e4 --- /dev/null +++ b/ILSpy/Commands/DecompileAllCommand.cs @@ -0,0 +1,69 @@ +// 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. + +#if DEBUG + +using System; +using System.Diagnostics; +using System.Threading.Tasks; +using ICSharpCode.ILSpy.TextView; + +namespace ICSharpCode.ILSpy +{ + [ExportMainMenuCommand(Menu = "_File", Header = "DEBUG -- Decompile All", MenuCategory = "Open", MenuOrder = 2.5)] + sealed class DecompileAllCommand : SimpleCommand + { + public override bool CanExecute(object parameter) + { + return System.IO.Directory.Exists("c:\\temp\\decompiled"); + } + + public override void Execute(object parameter) + { + MainWindow.Instance.TextView.RunWithCancellation(ct => Task.Factory.StartNew(() => { + AvalonEditTextOutput output = new AvalonEditTextOutput(); + Parallel.ForEach(MainWindow.Instance.CurrentAssemblyList.GetAssemblies(), new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount, CancellationToken = ct }, delegate(LoadedAssembly asm) { + if (!asm.HasLoadError) { + Stopwatch w = Stopwatch.StartNew(); + Exception exception = null; + using (var writer = new System.IO.StreamWriter("c:\\temp\\decompiled\\" + asm.ShortName + ".cs")) { + try { + new CSharpLanguage().DecompileAssembly(asm, new Decompiler.PlainTextOutput(writer), new DecompilationOptions { FullDecompilation = true, CancellationToken = ct }); + } + catch (Exception ex) { + writer.WriteLine(ex.ToString()); + exception = ex; + } + } + lock (output) { + output.Write(asm.ShortName + " - " + w.Elapsed); + if (exception != null) { + output.Write(" - "); + output.Write(exception.GetType().Name); + } + output.WriteLine(); + } + } + }); + return output; + }), task => MainWindow.Instance.TextView.ShowText(task.Result)); + } + } +} + +#endif \ No newline at end of file diff --git a/ILSpy/Commands/ExitCommand.cs b/ILSpy/Commands/ExitCommand.cs new file mode 100644 index 000000000..d064aa557 --- /dev/null +++ b/ILSpy/Commands/ExitCommand.cs @@ -0,0 +1,31 @@ +// 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; + +namespace ICSharpCode.ILSpy +{ + [ExportMainMenuCommand(Menu = "_File", Header = "E_xit", MenuOrder = 99999, MenuCategory = "Exit")] + sealed class ExitCommand : SimpleCommand + { + public override void Execute(object parameter) + { + MainWindow.Instance.Close(); + } + } +} \ No newline at end of file diff --git a/ILSpy/ExportCommandAttribute.cs b/ILSpy/Commands/ExportCommandAttribute.cs similarity index 100% rename from ILSpy/ExportCommandAttribute.cs rename to ILSpy/Commands/ExportCommandAttribute.cs diff --git a/ILSpy/Commands/OpenCommand.cs b/ILSpy/Commands/OpenCommand.cs new file mode 100644 index 000000000..74030365f --- /dev/null +++ b/ILSpy/Commands/OpenCommand.cs @@ -0,0 +1,33 @@ +// 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.Windows.Input; + +namespace ICSharpCode.ILSpy +{ + [ExportToolbarCommand(ToolTip = "Open", ToolbarIcon = "Images/Open.png", ToolbarCategory = "Open", ToolbarOrder = 0)] + [ExportMainMenuCommand(Menu = "_File", MenuIcon = "Images/Open.png", MenuCategory = "Open", MenuOrder = 0)] + sealed class OpenCommand : CommandWrapper + { + public OpenCommand() + : base(ApplicationCommands.Open) + { + } + } +} diff --git a/ILSpy/Commands/OpenFromGacCommand.cs b/ILSpy/Commands/OpenFromGacCommand.cs new file mode 100644 index 000000000..ceeff5bdc --- /dev/null +++ b/ILSpy/Commands/OpenFromGacCommand.cs @@ -0,0 +1,34 @@ +// 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; + +namespace ICSharpCode.ILSpy +{ + [ExportMainMenuCommand(Menu = "_File", Header = "Open from _GAC", MenuCategory = "Open", MenuOrder = 1)] + sealed class OpenFromGacCommand : SimpleCommand + { + public override void Execute(object parameter) + { + OpenFromGacDialog dlg = new OpenFromGacDialog(); + dlg.Owner = MainWindow.Instance; + if (dlg.ShowDialog() == true) + MainWindow.Instance.OpenFiles(dlg.SelectedFileNames); + } + } +} diff --git a/ILSpy/Commands/RefreshCommand.cs b/ILSpy/Commands/RefreshCommand.cs new file mode 100644 index 000000000..21edd69c5 --- /dev/null +++ b/ILSpy/Commands/RefreshCommand.cs @@ -0,0 +1,33 @@ +// 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.Windows.Input; + +namespace ICSharpCode.ILSpy +{ + [ExportToolbarCommand(ToolTip = "Reload all assemblies", ToolbarIcon = "Images/Refresh.png", ToolbarCategory = "Open", ToolbarOrder = 2)] + [ExportMainMenuCommand(Menu = "_File", Header = "Reload", MenuIcon = "Images/Refresh.png", MenuCategory = "Open", MenuOrder = 2)] + sealed class RefreshCommand : CommandWrapper + { + public RefreshCommand() + : base(NavigationCommands.Refresh) + { + } + } +} diff --git a/ILSpy/Commands/SaveCommand.cs b/ILSpy/Commands/SaveCommand.cs new file mode 100644 index 000000000..63989d863 --- /dev/null +++ b/ILSpy/Commands/SaveCommand.cs @@ -0,0 +1,32 @@ +// 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.Windows.Input; + +namespace ICSharpCode.ILSpy +{ + [ExportMainMenuCommand(Menu = "_File", Header = "_Save Code...", MenuIcon = "Images/SaveFile.png", MenuCategory = "Save", MenuOrder = 0)] + sealed class SaveCommand : CommandWrapper + { + public SaveCommand() + : base(ApplicationCommands.Save) + { + } + } +} diff --git a/ILSpy/Commands/SimpleCommand.cs b/ILSpy/Commands/SimpleCommand.cs new file mode 100644 index 000000000..d8490a1a6 --- /dev/null +++ b/ILSpy/Commands/SimpleCommand.cs @@ -0,0 +1,39 @@ +// 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.Windows.Input; + +namespace ICSharpCode.ILSpy +{ + public abstract class SimpleCommand : ICommand + { + public event EventHandler CanExecuteChanged + { + add { CommandManager.RequerySuggested += value; } + remove { CommandManager.RequerySuggested -= value; } + } + + public abstract void Execute(object parameter); + + public virtual bool CanExecute(object parameter) + { + return true; + } + } +} diff --git a/ILSpy/ILSpy.csproj b/ILSpy/ILSpy.csproj index 8956512a1..f97c43f28 100644 --- a/ILSpy/ILSpy.csproj +++ b/ILSpy/ILSpy.csproj @@ -93,16 +93,20 @@ + + - + + + DecompilerSettingsPanel.xaml Code - + @@ -126,6 +130,8 @@ + + OpenFromGacDialog.xaml Code @@ -135,6 +141,8 @@ Code + + Code @@ -142,6 +150,7 @@ DisplaySettingsPanel.xaml Code + @@ -325,5 +334,6 @@ + \ No newline at end of file From bf5ddabfc6060f7df1a4564b2ed3c744e20cc862 Mon Sep 17 00:00:00 2001 From: Ed Harvey Date: Sun, 29 May 2011 18:41:21 +1000 Subject: [PATCH 12/16] Move IPane to separate file. --- ILSpy/ILSpy.csproj | 1 + ILSpy/IPane.cs | 27 +++++++++++++++++++++++++++ ILSpy/SearchPane.cs | 8 -------- 3 files changed, 28 insertions(+), 8 deletions(-) create mode 100644 ILSpy/IPane.cs diff --git a/ILSpy/ILSpy.csproj b/ILSpy/ILSpy.csproj index f97c43f28..5488709c4 100644 --- a/ILSpy/ILSpy.csproj +++ b/ILSpy/ILSpy.csproj @@ -123,6 +123,7 @@ + diff --git a/ILSpy/IPane.cs b/ILSpy/IPane.cs new file mode 100644 index 000000000..2447f8bdd --- /dev/null +++ b/ILSpy/IPane.cs @@ -0,0 +1,27 @@ +// 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; + +namespace ICSharpCode.ILSpy +{ + public interface IPane + { + void Closed(); + } +} diff --git a/ILSpy/SearchPane.cs b/ILSpy/SearchPane.cs index d935b424c..1b829ea71 100644 --- a/ILSpy/SearchPane.cs +++ b/ILSpy/SearchPane.cs @@ -35,14 +35,6 @@ using Mono.Cecil; namespace ICSharpCode.ILSpy { - /// - /// Notifies panes when they are closed. - /// - public interface IPane - { - void Closed(); - } - /// /// Search pane /// From 1ca1caef54cefd6912cf551b07e29b31e4496b0a Mon Sep 17 00:00:00 2001 From: Ed Harvey Date: Sun, 29 May 2011 18:46:37 +1000 Subject: [PATCH 13/16] Split ShowAnalyzerCommand into separate file. --- ILSpy/AnalyzerTreeView.cs | 36 ++++++++------------------- ILSpy/Commands/ShowAnalyzerCommand.cs | 31 +++++++++++++++++++++++ ILSpy/ILSpy.csproj | 1 + 3 files changed, 42 insertions(+), 26 deletions(-) create mode 100644 ILSpy/Commands/ShowAnalyzerCommand.cs diff --git a/ILSpy/AnalyzerTreeView.cs b/ILSpy/AnalyzerTreeView.cs index d89174d18..94f4ed66c 100644 --- a/ILSpy/AnalyzerTreeView.cs +++ b/ILSpy/AnalyzerTreeView.cs @@ -17,15 +17,6 @@ // DEALINGS IN THE SOFTWARE. using System; -using System.Collections.Generic; -using System.Text; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; - using ICSharpCode.ILSpy.TreeNodes.Analyzer; using ICSharpCode.TreeView; @@ -37,9 +28,11 @@ namespace ICSharpCode.ILSpy public partial class AnalyzerTreeView : SharpTreeView, IPane { static AnalyzerTreeView instance; - - public static AnalyzerTreeView Instance { - get { + + public static AnalyzerTreeView Instance + { + get + { if (instance == null) { App.Current.VerifyAccess(); instance = new AnalyzerTreeView(); @@ -47,42 +40,33 @@ namespace ICSharpCode.ILSpy return instance; } } - + private AnalyzerTreeView() { this.ShowRoot = false; this.Root = new AnalyzerTreeNode { Language = MainWindow.Instance.CurrentLanguage }; ContextMenuProvider.Add(this); } - + public void Show() { if (!IsVisible) MainWindow.Instance.ShowInBottomPane("Analyzer", this); } - + public void Show(AnalyzerTreeNode node) { Show(); - + node.IsExpanded = true; this.Root.Children.Add(node); this.SelectedItem = node; this.FocusNode(node); } - + void IPane.Closed() { this.Root.Children.Clear(); } } - - [ExportMainMenuCommand(Menu = "_View", Header = "_Analyzer", MenuCategory = "ShowPane", MenuOrder = 100)] - sealed class ShowAnalyzerCommand : SimpleCommand - { - public override void Execute(object parameter) - { - AnalyzerTreeView.Instance.Show(); - } - } } \ No newline at end of file diff --git a/ILSpy/Commands/ShowAnalyzerCommand.cs b/ILSpy/Commands/ShowAnalyzerCommand.cs new file mode 100644 index 000000000..1dcc74c6d --- /dev/null +++ b/ILSpy/Commands/ShowAnalyzerCommand.cs @@ -0,0 +1,31 @@ +// 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; + +namespace ICSharpCode.ILSpy +{ + [ExportMainMenuCommand(Menu = "_View", Header = "_Analyzer", MenuCategory = "ShowPane", MenuOrder = 100)] + sealed class ShowAnalyzerCommand : SimpleCommand + { + public override void Execute(object parameter) + { + AnalyzerTreeView.Instance.Show(); + } + } +} diff --git a/ILSpy/ILSpy.csproj b/ILSpy/ILSpy.csproj index 5488709c4..bdfc4f123 100644 --- a/ILSpy/ILSpy.csproj +++ b/ILSpy/ILSpy.csproj @@ -152,6 +152,7 @@ Code + From 27461a9717ea57811804822f0ba68c1c6a29715b Mon Sep 17 00:00:00 2001 From: Ed Harvey Date: Sun, 29 May 2011 18:52:55 +1000 Subject: [PATCH 14/16] Move all *Language classes to subfolder. --- ILSpy/ILSpy.csproj | 8 ++++---- ILSpy/{ => Languages}/CSharpLanguage.cs | 0 ILSpy/{ => Languages}/ILAstLanguage.cs | 0 ILSpy/{ => Languages}/ILLanguage.cs | 0 ILSpy/{ => Languages}/Language.cs | 0 5 files changed, 4 insertions(+), 4 deletions(-) rename ILSpy/{ => Languages}/CSharpLanguage.cs (100%) rename ILSpy/{ => Languages}/ILAstLanguage.cs (100%) rename ILSpy/{ => Languages}/ILLanguage.cs (100%) rename ILSpy/{ => Languages}/Language.cs (100%) diff --git a/ILSpy/ILSpy.csproj b/ILSpy/ILSpy.csproj index bdfc4f123..9b03b70f8 100644 --- a/ILSpy/ILSpy.csproj +++ b/ILSpy/ILSpy.csproj @@ -109,7 +109,7 @@ - + @@ -117,15 +117,15 @@ - - + + - + diff --git a/ILSpy/CSharpLanguage.cs b/ILSpy/Languages/CSharpLanguage.cs similarity index 100% rename from ILSpy/CSharpLanguage.cs rename to ILSpy/Languages/CSharpLanguage.cs diff --git a/ILSpy/ILAstLanguage.cs b/ILSpy/Languages/ILAstLanguage.cs similarity index 100% rename from ILSpy/ILAstLanguage.cs rename to ILSpy/Languages/ILAstLanguage.cs diff --git a/ILSpy/ILLanguage.cs b/ILSpy/Languages/ILLanguage.cs similarity index 100% rename from ILSpy/ILLanguage.cs rename to ILSpy/Languages/ILLanguage.cs diff --git a/ILSpy/Language.cs b/ILSpy/Languages/Language.cs similarity index 100% rename from ILSpy/Language.cs rename to ILSpy/Languages/Language.cs From 60cf22a48cb3f482126b265547553ba65fb889b4 Mon Sep 17 00:00:00 2001 From: Ed Harvey Date: Sun, 29 May 2011 18:56:20 +1000 Subject: [PATCH 15/16] Move Languages collection to separate file. --- ILSpy/ILSpy.csproj | 1 + ILSpy/Languages/Language.cs | 43 +------------------------- ILSpy/Languages/Languages.cs | 58 ++++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 42 deletions(-) create mode 100644 ILSpy/Languages/Languages.cs diff --git a/ILSpy/ILSpy.csproj b/ILSpy/ILSpy.csproj index 9b03b70f8..9090a9a0a 100644 --- a/ILSpy/ILSpy.csproj +++ b/ILSpy/ILSpy.csproj @@ -127,6 +127,7 @@ + diff --git a/ILSpy/Languages/Language.cs b/ILSpy/Languages/Language.cs index d9f566013..2f5f54972 100644 --- a/ILSpy/Languages/Language.cs +++ b/ILSpy/Languages/Language.cs @@ -18,9 +18,6 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel.Composition.Hosting; -using System.Linq; using ICSharpCode.Decompiler; using Mono.Cecil; @@ -156,42 +153,4 @@ namespace ICSharpCode.ILSpy return member; } } - - public static class Languages - { - static ReadOnlyCollection allLanguages; - - /// - /// A list of all languages. - /// - public static ReadOnlyCollection AllLanguages - { - get - { - return allLanguages; - } - } - - - internal static void Initialize(CompositionContainer composition) - { - List languages = new List(); - languages.AddRange(composition.GetExportedValues()); - languages.Add(new ILLanguage(true)); -#if DEBUG - languages.AddRange(ILAstLanguage.GetDebugLanguages()); - languages.AddRange(CSharpLanguage.GetDebugLanguages()); -#endif - allLanguages = languages.AsReadOnly(); - } - - /// - /// Gets a language using its name. - /// If the language is not found, C# is returned instead. - /// - public static Language GetLanguage(string name) - { - return AllLanguages.FirstOrDefault(l => l.Name == name) ?? AllLanguages.First(); - } - } -} +} \ No newline at end of file diff --git a/ILSpy/Languages/Languages.cs b/ILSpy/Languages/Languages.cs new file mode 100644 index 000000000..2cdac7a7e --- /dev/null +++ b/ILSpy/Languages/Languages.cs @@ -0,0 +1,58 @@ +// 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.Collections.ObjectModel; +using System.ComponentModel.Composition.Hosting; +using System.Linq; + +namespace ICSharpCode.ILSpy +{ + public static class Languages + { + private static ReadOnlyCollection allLanguages; + + /// + /// A list of all languages. + /// + public static ReadOnlyCollection AllLanguages + { + get { return allLanguages; } + } + + internal static void Initialize(CompositionContainer composition) + { + List languages = new List(); + languages.AddRange(composition.GetExportedValues()); + languages.Add(new ILLanguage(true)); + languages.AddRange(ILAstLanguage.GetDebugLanguages()); + languages.AddRange(CSharpLanguage.GetDebugLanguages()); + allLanguages = languages.AsReadOnly(); + } + + /// + /// Gets a language using its name. + /// If the language is not found, C# is returned instead. + /// + public static Language GetLanguage(string name) + { + return AllLanguages.FirstOrDefault(l => l.Name == name) ?? AllLanguages.First(); + } + } +} From 54cf43a1e14176fcba9cccbefe61a740da01e0cc Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sun, 29 May 2011 13:14:41 +0200 Subject: [PATCH 16/16] Fix build. --- ILSpy/Languages/Languages.cs | 2 ++ Mono.Cecil/symbols/pdb/Mono.Cecil.Pdb.csproj | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ILSpy/Languages/Languages.cs b/ILSpy/Languages/Languages.cs index 2cdac7a7e..5b9e18092 100644 --- a/ILSpy/Languages/Languages.cs +++ b/ILSpy/Languages/Languages.cs @@ -41,8 +41,10 @@ namespace ICSharpCode.ILSpy List languages = new List(); languages.AddRange(composition.GetExportedValues()); languages.Add(new ILLanguage(true)); + #if DEBUG languages.AddRange(ILAstLanguage.GetDebugLanguages()); languages.AddRange(CSharpLanguage.GetDebugLanguages()); + #endif allLanguages = languages.AsReadOnly(); } diff --git a/Mono.Cecil/symbols/pdb/Mono.Cecil.Pdb.csproj b/Mono.Cecil/symbols/pdb/Mono.Cecil.Pdb.csproj index d0f6fe4ef..2d2dfd273 100644 --- a/Mono.Cecil/symbols/pdb/Mono.Cecil.Pdb.csproj +++ b/Mono.Cecil/symbols/pdb/Mono.Cecil.Pdb.csproj @@ -1,4 +1,4 @@ - + net_4_0_Debug @@ -13,6 +13,7 @@ 512 true ..\..\mono.snk + 0649 true