public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) { var doc = new BamlElement(node); doc.Xaml = new XElement(ctx.GetPseudoName("Document")); HandlerMap.ProcessChildren(ctx, (BamlBlockNode)node, doc); return doc; }
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) { var record = (OptimizedStaticResourceRecord)((BamlRecordNode)node).Record; var key = XamlResourceKey.FindKeyInSiblings(node); key.StaticResources.Add(node); return null; }
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) { var record = (ConnectionIdRecord)((BamlRecordNode)node).Record; parent.Xaml.Element.AddAnnotation(new BamlConnectionId(record.ConnectionId)); return null; }
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) { var record = (TextWithIdRecord)((BamlRecordNode)node).Record; parent.Xaml.Element.Add(ctx.ResolveString(record.ValueId)); return null; }
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) { var record = (PropertyWithStaticResourceIdRecord)((BamlRecordNode)node).Record; var doc = new BamlElement(node); var elemAttr = ctx.ResolveProperty(record.AttributeId); doc.Xaml = new XElement(elemAttr.ToXName(ctx, null)); doc.Xaml.Element.AddAnnotation(elemAttr); parent.Xaml.Element.Add(doc.Xaml.Element); BamlNode found = node; XamlResourceKey key; do { key = XamlResourceKey.FindKeyInAncestors(found.Parent, out found); } while (key != null && record.StaticResourceId >= key.StaticResources.Count); if (key == null) throw new Exception("Cannot find StaticResource @" + node.Record.Position); var resNode = key.StaticResources[record.StaticResourceId]; var handler = (IDeferHandler)HandlerMap.LookupHandler(resNode.Type); var resElem = handler.TranslateDefer(ctx, resNode, doc); doc.Children.Add(resElem); resElem.Parent = doc; elemAttr.DeclaringType.ResolveNamespace(doc.Xaml, ctx); doc.Xaml.Element.Name = elemAttr.ToXName(ctx, null); return doc; }
bool RewriteElement(XamlContext ctx, XElement parent, XElement elem) { var type = parent.Annotation<XamlType>(); var property = elem.Annotation<XamlProperty>(); if ((property == null || type == null) && elem.Name != key) return false; if (elem.Elements().Count() != 1 || elem.Attributes().Any(t => t.Name.Namespace != XNamespace.Xmlns)) return false; var value = elem.Elements().Single(); if (!CanInlineExt(ctx, value)) return false; var ext = InlineExtension(ctx, value); if (ext == null) return false; ctx.CancellationToken.ThrowIfCancellationRequested(); var extValue = ext.ToString(ctx, parent); var attrName = elem.Name; if (attrName != key) attrName = property.ToXName(ctx, parent, property.IsAttachedTo(type)); var attr = new XAttribute(attrName, extValue); parent.Add(attr); elem.Remove(); return true; }
void RewriteClass(XamlContext ctx, XElement elem) { var type = elem.Annotation<XamlType>(); if (type == null || type.ResolvedType == null) return; var typeDef = type.ResolvedType.ResolveTypeDef(); var comparer = new AssemblyNameComparer(AssemblyNameComparerFlags.All); if (typeDef == null || !comparer.Equals(typeDef.DefinitionAssembly, ctx.Module.Assembly)) return; var newType = typeDef.BaseType; var xamlType = new XamlType(newType.DefinitionAssembly, newType.ReflectionNamespace, newType.Name); xamlType.ResolveNamespace(elem, ctx); elem.Name = xamlType.ToXName(ctx); var attrName = ctx.GetXamlNsName("Class", elem); var attrs = elem.Attributes().ToList(); if (typeDef.IsNotPublic) { var classModifierName = ctx.GetXamlNsName("ClassModifier", elem); attrs.Insert(0, new XAttribute(classModifierName, ctx.BamlDecompilerOptions.InternalClassModifier)); } attrs.Insert(0, new XAttribute(attrName, type.ResolvedType.ReflectionFullName)); elem.ReplaceAttributes(attrs); }
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) { var record = (ElementStartRecord)((BamlBlockNode)node).Header; var doc = new BamlElement(node); var elemType = ctx.ResolveType(record.TypeId); doc.Xaml = new XElement(elemType.ToXName(ctx)); doc.Xaml.Element.AddAnnotation(elemType); parent.Xaml.Element.Add(doc.Xaml.Element); HandlerMap.ProcessChildren(ctx, (BamlBlockNode)node, doc); var key = node.Annotation as XamlResourceKey; if (key != null && key.KeyNode.Record != node.Record) { var handler = (IDeferHandler)HandlerMap.LookupHandler(key.KeyNode.Record.Type); var keyElem = handler.TranslateDefer(ctx, key.KeyNode, doc); doc.Children.Add(keyElem); keyElem.Parent = doc; } elemType.ResolveNamespace(doc.Xaml, ctx); doc.Xaml.Element.Name = elemType.ToXName(ctx); return doc; }
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) { var record = (DeferableContentStartRecord)((BamlRecordNode)node).Record; Debug.Assert(record.Record == ((BamlBlockNode)parent.Node).Footer); return null; }
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) { var record = (TextRecord)((BamlRecordNode)node).Record; parent.Xaml.Element.Add(record.Value); return null; }
public void ResolveNamespace(XElement elem, XamlContext ctx) { if (Namespace != null) return; // Since XmlnsProperty records are inside the element, // the namespace is resolved after processing the element body. string xmlNs = null; if (elem.Annotation<XmlnsScope>() != null) xmlNs = elem.Annotation<XmlnsScope>().LookupXmlns(Assembly, TypeNamespace); if (xmlNs == null) xmlNs = ctx.XmlNs.LookupXmlns(Assembly, TypeNamespace); if (xmlNs == null) { var nsSeg = TypeNamespace.Split('.'); var nsName = nsSeg[nsSeg.Length - 1].ToLowerInvariant(); var prefix = nsName; int count = 0; while (elem.GetNamespaceOfPrefix(prefix) != null) { count++; prefix = nsName + count; } xmlNs = string.Format("clr-namespace:{0};assembly={1}", TypeNamespace, Assembly); elem.Add(new XAttribute(XNamespace.Xmlns + XmlConvert.EncodeLocalName(prefix), ctx.GetXmlNamespace(xmlNs))); } Namespace = xmlNs; }
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) { var record = (DefAttributeRecord)((BamlRecordNode)node).Record; var attrName = ctx.ResolveString(record.NameId); parent.Xaml.Element.Add(new XAttribute(ctx.GetXamlNsName(attrName), record.Value)); return null; }
bool ProcessElement(XamlContext ctx, XElement elem) { bool doWork = false; foreach (var child in elem.Elements()) { doWork |= RewriteElement(ctx, elem, child); doWork |= ProcessElement(ctx, child); } return doWork; }
public void Run(XamlContext ctx, XDocument document) { key = ctx.GetXamlNsName("Key"); bool doWork; do { doWork = false; foreach (var elem in document.Elements()) { doWork |= ProcessElement(ctx, elem); } } while (doWork); }
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) { var record = (LiteralContentRecord)((BamlRecordNode)node).Record; var elem = new XElement(ctx.GetXamlNsName("XData", parent.Xaml)); var content = XElement.Parse(record.Value); elem.Add(content); parent.Xaml.Element.Add(elem); return null; }
public BamlElement TranslateDefer(XamlContext ctx, BamlNode node, BamlElement parent) { var record = (KeyElementStartRecord)((BamlBlockNode)node).Header; var key = (XamlResourceKey)node.Annotation; var bamlElem = new BamlElement(node); bamlElem.Xaml = new XElement(ctx.GetXamlNsName("Key", parent.Xaml)); parent.Xaml.Element.Add(bamlElem.Xaml.Element); key.KeyElement = bamlElem; base.Translate(ctx, node, bamlElem); return bamlElem; }
public BamlElement TranslateDefer(XamlContext ctx, BamlNode node, BamlElement parent) { var record = (DefAttributeKeyStringRecord)((BamlRecordNode)node).Record; var key = (XamlResourceKey)node.Annotation; var bamlElem = new BamlElement(node); bamlElem.Xaml = new XElement(ctx.GetXamlNsName("Key", parent.Xaml)); parent.Xaml.Element.Add(bamlElem.Xaml.Element); bamlElem.Xaml.Element.Value = ctx.ResolveString(record.ValueId); key.KeyElement = bamlElem; return bamlElem; }
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) { var record = (PropertyRecord)((BamlRecordNode)node).Record; var elemType = parent.Xaml.Element.Annotation<XamlType>(); var xamlProp = ctx.ResolveProperty(record.AttributeId); var value = XamlUtils.Escape(record.Value); var attr = new XAttribute(xamlProp.ToXName(ctx, parent.Xaml, xamlProp.IsAttachedTo(elemType)), value); parent.Xaml.Element.Add(attr); return null; }
public void Run(XamlContext ctx, XDocument document) { foreach (var elem in document.Elements(ctx.GetPseudoName("Document")).ToList()) { if (elem.Elements().Count() != 1) continue; var docElem = elem.Elements().Single(); foreach (var attr in elem.Attributes()) { Debug.Assert(attr.IsNamespaceDeclaration); attr.Remove(); docElem.Add(attr); } elem.ReplaceWith(docElem); } }
public XName ToXName(XamlContext ctx, XElement parent, bool isFullName = true) { var typeName = DeclaringType.ToXName(ctx); XName name; if (!isFullName) name = XmlConvert.EncodeLocalName(PropertyName); else name = typeName.LocalName + "." + XmlConvert.EncodeLocalName(PropertyName); if (parent == null || (parent.GetDefaultNamespace() != typeName.Namespace && parent.Name.Namespace != typeName.Namespace)) name = typeName.Namespace + name.LocalName; return name; }
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) { var record = (PropertyComplexStartRecord)((BamlBlockNode)node).Header; var doc = new BamlElement(node); var elemAttr = ctx.ResolveProperty(record.AttributeId); doc.Xaml = new XElement(elemAttr.ToXName(ctx, null)); doc.Xaml.Element.AddAnnotation(elemAttr); parent.Xaml.Element.Add(doc.Xaml.Element); HandlerMap.ProcessChildren(ctx, (BamlBlockNode)node, doc); elemAttr.DeclaringType.ResolveNamespace(doc.Xaml, ctx); doc.Xaml.Element.Name = elemAttr.ToXName(ctx, null); return doc; }
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) { var record = (ConstructorParameterTypeRecord)((BamlRecordNode)node).Record; var elem = new XElement(ctx.GetXamlNsName("TypeExtension", parent.Xaml)); elem.AddAnnotation(ctx.ResolveType(0xfd4d)); // Known type - TypeExtension var bamlElem = new BamlElement(node); bamlElem.Xaml = elem; parent.Xaml.Element.Add(elem); var type = ctx.ResolveType(record.TypeId); var typeName = ctx.ToString(parent.Xaml, type); elem.Add(new XElement(ctx.GetPseudoName("Ctor"), typeName)); return bamlElem; }
public void ResolveNamespace(XElement elem, XamlContext ctx) { if (Namespace != null) return; // Since XmlnsProperty records are inside the element, // the namespace is resolved after processing the element body. string xmlNs = null; if (elem.Annotation<XmlnsScope>() != null) xmlNs = elem.Annotation<XmlnsScope>().LookupXmlns(Assembly, TypeNamespace); if (xmlNs == null) xmlNs = ctx.XmlNs.LookupXmlns(Assembly, TypeNamespace); // Sometimes there's no reference to System.Xaml even if x:Type is used if (xmlNs == null) xmlNs = ctx.TryGetXmlNamespace(Assembly, TypeNamespace); if (xmlNs == null) { if (AssemblyNameComparer.CompareAll.Equals(Assembly, ctx.Module.Assembly)) xmlNs = $"clr-namespace:{TypeNamespace}"; else xmlNs = $"clr-namespace:{TypeNamespace};assembly={Assembly.Name}"; var nsSeg = TypeNamespace.Split('.'); var prefix = nsSeg[nsSeg.Length - 1].ToLowerInvariant(); if (string.IsNullOrEmpty(prefix)) { if (string.IsNullOrEmpty(TypeNamespace)) prefix = "global"; else prefix = "empty"; } int count = 0; var truePrefix = prefix; XNamespace prefixNs, ns = ctx.GetXmlNamespace(xmlNs); while ((prefixNs = elem.GetNamespaceOfPrefix(truePrefix)) != null && prefixNs != ns) { count++; truePrefix = prefix + count; } if (prefixNs == null) { elem.Add(new XAttribute(XNamespace.Xmlns + XmlConvert.EncodeLocalName(truePrefix), ns)); if (string.IsNullOrEmpty(TypeNamespace)) elem.AddBeforeSelf(new XComment(string.Format(dnSpy_BamlDecompiler_Resources.Msg_GlobalNamespace, truePrefix))); } } Namespace = ctx.GetXmlNamespace(xmlNs); }
void CheckConnectionId(XamlContext ctx, XElement elem, Dictionary <int, Action <XamlContext, XElement> > connIds) { var connId = elem.Annotation <BamlConnectionId>(); if (connId == null) { return; } Action <XamlContext, XElement> cb; if (!connIds.TryGetValue((int)connId.Id, out cb)) { elem.AddBeforeSelf(new XComment("Unknown connection ID: " + connId.Id)); } cb(ctx, elem); }
public void AncestorDetectionTest1() { string xaml = File.ReadAllText("Test5.xaml"); int offset = 881; XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset); string[] ancestors = new string[] { "DoubleAnimation", "Storyboard", "BeginStoryboard", "EventTrigger", "Button.Triggers", "Button", "Grid", "Window" }; Assert.AreEqual("DoubleAnimation", context.ActiveElement.Name); Assert.AreEqual("Storyboard", context.ParentElement.Name); Assert.AreEqual(8, context.Ancestors.Count); Assert.AreEqual(ancestors, context.Ancestors.Select(item => item.Name).ToArray()); }
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) { var record = (PropertyComplexStartRecord)((BamlBlockNode)node).Header; var doc = new BamlElement(node); var elemAttr = ctx.ResolveProperty(record.AttributeId); doc.Xaml = new XElement(elemAttr.ToXName(ctx, null)); doc.Xaml.Element.AddAnnotation(elemAttr); parent.Xaml.Element.Add(doc.Xaml.Element); HandlerMap.ProcessChildren(ctx, (BamlBlockNode)node, doc); elemAttr.DeclaringType.ResolveNamespace(doc.Xaml, ctx); doc.Xaml.Element.Name = elemAttr.ToXName(ctx, null); return(doc); }
static IMember Resolve(XAttribute attribute, ITextEditor editor) { XamlContext context = CompletionDataHelper.ResolveCompletionContext(editor, default(char), editor.Document.PositionToOffset(attribute.GetLineNumber(), attribute.GetLinePosition())); string prefix = context.XmlnsDefinitions.GetKeyByValue(attribute.Name.NamespaceName); if (!string.IsNullOrEmpty(prefix)) { prefix += ":"; } var mrr = XamlResolver.Resolve(prefix + attribute.Name.LocalName, context) as MemberResolveResult; if (mrr != null) { return(mrr.ResolvedMember); } return(null); }
object[] InlineCtor(XamlContext ctx, XElement ctor) { if (ctor.HasAttributes) { return(null); } var args = new List <object>(); foreach (var child in ctor.Nodes()) { var arg = InlineObject(ctx, child); if (arg == null) { return(null); } args.Add(arg); } return(args.ToArray()); }
public BamlElement TranslateDefer(XamlContext ctx, BamlNode node, BamlElement parent) { var record = (DefAttributeKeyTypeRecord)((BamlRecordNode)node).Record; var type = ctx.ResolveType(record.TypeId); var typeName = ctx.ToString(parent.Xaml, type); var key = (XamlResourceKey)node.Annotation; var bamlElem = new BamlElement(node); bamlElem.Xaml = new XElement(ctx.GetXamlNsName("Key", parent.Xaml)); parent.Xaml.Element.Add(bamlElem.Xaml.Element); var typeElem = new XElement(ctx.GetXamlNsName("TypeExtension", parent.Xaml)); typeElem.AddAnnotation(ctx.ResolveType(0xfd4d)); // Known type - TypeExtension typeElem.Add(new XElement(ctx.GetPseudoName("Ctor"), typeName)); bamlElem.Xaml.Element.Add(typeElem); key.KeyElement = bamlElem; return bamlElem; }
void CheckConnectionId(XamlContext ctx, XElement elem, Dictionary <int, Action <XamlContext, XElement> > connIds) { var connId = elem.Annotation <BamlConnectionId>(); if (connId == null) { return; } Action <XamlContext, XElement> cb; if (!connIds.TryGetValue((int)connId.Id, out cb)) { elem.AddBeforeSelf(new XComment(string.Format(dnSpy_BamlDecompiler_Resources.Error_UnknownConnectionId, connId.Id))); return; } cb(ctx, elem); }
public void Run(XamlContext ctx, XDocument document) { var xClass = document.Root.Elements().First().Attribute(ctx.GetXamlNsName("Class")); if (xClass == null) return; var type = ctx.Module.Find(xClass.Value, true); if (type == null) return; var wbAsm = new AssemblyNameInfo("WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35").ToAssemblyRef(); var ifaceRef = new TypeRefUser(ctx.Module, "System.Windows.Markup", "IComponentConnector", wbAsm); var iface = ctx.Module.Context.Resolver.ResolveThrow(ifaceRef); var connect = iface.FindMethod("Connect"); foreach (MethodDef method in type.Methods) { if (Impl(method, connect)) { connect = method; iface = null; break; } } if (iface != null) return; Dictionary<int, Action<XamlContext, XElement>> connIds = null; try { connIds = ExtractConnectionId(ctx, connect); } catch { } if (connIds == null) { var msg = dnSpy_BamlDecompiler_Resources.Error_IComponentConnectorConnetCannotBeParsed; document.Root.AddBeforeSelf(new XComment(string.Format(msg, type.ReflectionFullName))); return; } foreach (var elem in document.Elements()) { ProcessElement(ctx, elem, connIds); } }
public XName ToXName(XamlContext ctx, XElement parent, bool isFullName = true) { var typeName = DeclaringType.ToXName(ctx); XName name; if (!isFullName) { name = XmlConvert.EncodeLocalName(PropertyName); } else { name = typeName.LocalName + "." + XmlConvert.EncodeLocalName(PropertyName); if (parent == null || parent.GetDefaultNamespace() != typeName.Namespace) { name = typeName.Namespace + name.LocalName; } } return(name); }
public void Run(XamlContext ctx, XDocument document) { foreach (var elem in document.Elements(ctx.GetPseudoName("Document")).ToList()) { if (elem.Elements().Count() != 1) { continue; } var docElem = elem.Elements().Single(); foreach (var attr in elem.Attributes()) { Debug.Assert(attr.IsNamespaceDeclaration); attr.Remove(); docElem.Add(attr); } elem.ReplaceWith(docElem); } }
void FinalizeReferences(XamlContext txt) { IGrouping <int, XamlRef>[] refers = txt.refers .GroupBy(_ => _.lineNum) .OrderBy(_ => _.Key).ToArray(); object[][] lines = new object[txt.lines.Length][]; foreach (var i in refers) { int lineNum = i.Key; string line = txt.lines[lineNum]; List <object> segs = new List <object>(); int prev = 0; foreach (var j in i.OrderBy(_ => _.index)) //No overlapping { if (j.index != prev) { segs.Add(line.Substring(prev, j.index - prev)); } segs.Add(j.name); j.refer.Context = txt; j.refer.Line = lineNum; j.refer.Segment = segs.Count - 1; prev = j.index + j.length; } if (line.Length != prev) { segs.Add(line.Substring(prev, line.Length - prev)); } lines[lineNum] = segs.ToArray(); } for (int i = 0; i < lines.Length; i++) { if (lines[i] == null) { lines[i] = new object[] { txt.lines[i] } } } ; txt.segments = lines; }
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) { var record = (ConstructorParameterTypeRecord)((BamlRecordNode)node).Record; var elem = new XElement(ctx.GetXamlNsName("TypeExtension", parent.Xaml)); elem.AddAnnotation(ctx.ResolveType(0xfd4d)); // Known type - TypeExtension var bamlElem = new BamlElement(node); bamlElem.Xaml = elem; parent.Xaml.Element.Add(elem); var type = ctx.ResolveType(record.TypeId); var typeName = ctx.ToString(parent.Xaml, type); elem.Add(new XElement(ctx.GetPseudoName("Ctor"), typeName)); return(bamlElem); }
bool RewriteElement(XamlContext ctx, XElement parent, XElement elem) { var property = elem.Annotation<XamlProperty>(); if (property == null && elem.Name != key) return false; if (elem.HasAttributes || elem.HasElements) return false; ctx.CancellationToken.ThrowIfCancellationRequested(); var value = elem.Value; var attrName = elem.Name; if (attrName != key) attrName = property.ToXName(ctx, parent, property.IsAttachedTo(parent.Annotation<XamlType>())); var attr = new XAttribute(attrName, value); parent.Add(attr); elem.Remove(); return true; }
void AnalyzeXaml(AssemblyDefinition asm, Stream stream) { string s = new StreamReader(stream).ReadToEnd(); var doc = XDocument.Parse(s, LoadOptions.SetLineInfo); XamlContext txt = new XamlContext() { context = asm, xaml = s, lines = s.Split('\n') }; LoadDependencies(asm, txt.asms = new List <AssemblyDefinition>(), i => { foreach (var attr in i.CustomAttributes.Where(_ => _.AttributeType.FullName == "System.Windows.Markup.XmlnsDefinitionAttribute" )) { List <XmlNsDef> map; if (!txt.uri2nsDef.TryGetValue((string)attr.ConstructorArguments[0].Value, out map)) { map = txt.uri2nsDef[(string)attr.ConstructorArguments[0].Value] = new List <XmlNsDef>(); } var asmNameProp = attr.Properties .Cast <CustomAttributeNamedArgument?>() .FirstOrDefault(_ => _.Value.Name == "AssemblyName"); map.Add(new XmlNsDef() { ClrNamespace = (string)attr.ConstructorArguments[1].Value, Assembly = asmNameProp == null ? i : GlobalAssemblyResolver.Instance.Resolve((string)asmNameProp.Value.Argument.Value) }); } }); foreach (var i in doc.Elements()) { AnalyzeElement(txt, i); } FinalizeReferences(txt); }
void RewriteClass(XamlContext ctx, XElement elem) { var type = elem.Annotation <XamlType>(); if (type == null || type.ResolvedType == null) { return; } var typeDef = type.ResolvedType.GetDefinition(); if (typeDef == null || !typeDef.ParentModule.IsMainModule) { return; } var newType = typeDef.DirectBaseTypes.First().GetDefinition(); if (newType == null) { return; } var xamlType = new XamlType(newType.ParentModule, newType.ParentModule.FullAssemblyName, newType.Namespace, newType.Name); xamlType.ResolveNamespace(elem, ctx); elem.Name = xamlType.ToXName(ctx); var attrName = ctx.GetKnownNamespace("Class", XamlContext.KnownNamespace_Xaml, elem); var attrs = elem.Attributes().ToList(); if (typeDef.Accessibility != ICSharpCode.Decompiler.TypeSystem.Accessibility.Public) { var classModifierName = ctx.GetKnownNamespace("ClassModifier", XamlContext.KnownNamespace_Xaml, elem); attrs.Insert(0, new XAttribute(classModifierName, "internal")); } attrs.Insert(0, new XAttribute(attrName, type.ResolvedType.FullName)); ctx.XClassNames.Add(type.ResolvedType.FullName); elem.ReplaceAttributes(attrs); }
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) { var record = (XmlnsPropertyRecord)((BamlRecordNode)node).Record; foreach (var asmId in record.AssemblyIds) { var assembly = ctx.Baml.ResolveAssembly(asmId); ctx.XmlNs.Add(new NamespaceMap(record.Prefix, assembly, record.XmlNamespace)); if (assembly is AssemblyDef) { foreach (var clrNs in ResolveCLRNamespaces((AssemblyDef)assembly, record.XmlNamespace)) ctx.XmlNs.Add(new NamespaceMap(record.Prefix, assembly, record.XmlNamespace, clrNs)); } } XName xmlnsDef; if (string.IsNullOrEmpty(record.Prefix)) xmlnsDef = "xmlns"; else xmlnsDef = XNamespace.Xmlns + XmlConvert.EncodeLocalName(record.Prefix); parent.Xaml.Element.Add(new XAttribute(xmlnsDef, ctx.GetXmlNamespace(record.XmlNamespace))); return null; }
bool RewriteElement(XamlContext ctx, XElement parent, XElement elem) { var property = elem.Annotation <XamlProperty>(); if (property is null && elem.Name != key) { return(false); } if (elem.HasAttributes || elem.HasElements) { return(false); } ctx.CancellationToken.ThrowIfCancellationRequested(); var value = elem.Value; var attrName = elem.Name; if (attrName != key) { attrName = property.ToXName(ctx, parent, property.IsAttachedTo(parent.Annotation <XamlType>())); } var attr = new XAttribute(attrName, value); var list = new List <XAttribute>(parent.Attributes()); if (attrName == key) { list.Insert(0, attr); } else { list.Add(attr); } parent.RemoveAttributes(); parent.ReplaceAttributes(list); elem.Remove(); return(true); }
void AnalyzePropertyElem(TypeDefinition typeDef, XamlContext txt, XElement elem) { XamlPropertyName name = XamlPropertyName.Parse(typeDef, elem.Name, txt); name.Xmlns = elem.GetPrefixOfNamespace(name.Xmlns); var prop = ResolveProperty(name.TypeDef, name.PropertyName); if (prop != null && Assemblies.Contains(prop.DeclaringType.Module.Assembly)) { IXmlLineInfo li = elem as IXmlLineInfo; string line = txt.lines[li.LineNumber - 1]; int end = line.IndexOf('>', li.LinePosition - 1); string str = line.Substring(li.LinePosition - 1, end - li.LinePosition + 1); var r = new XamlPropertyNameReference() { Name = name }; txt.refers.Add(new XamlRef() { lineNum = li.LineNumber - 1, index = li.LinePosition - 1, length = end - li.LinePosition + 1, name = name, refer = r }); ((prop as IAnnotationProvider).Annotations[RenRef] as List <IReference>).Add(r); } foreach (var i in elem.Elements()) { if (i.Name.LocalName.Contains(".")) { AnalyzePropertyElem(name.TypeDef, txt, i); } else { AnalyzeElement(txt, i); } } }
bool CanInlineExt(XamlContext ctx, XElement ctxElement) { var type = ctxElement.Annotation <XamlType>(); if (!(type is null) && !(type.ResolvedType is null)) { var typeDef = type.ResolvedType.GetBaseType(); bool isExt = false; while (!(typeDef is null)) { if (typeDef.FullName == "System.Windows.Markup.MarkupExtension") { isExt = true; break; } typeDef = typeDef.GetBaseType(); } if (!isExt) { return(false); } }
public BamlElement TranslateDefer(XamlContext ctx, BamlNode node, BamlElement parent) { var record = (DefAttributeKeyTypeRecord)((BamlRecordNode)node).Record; var type = ctx.ResolveType(record.TypeId); var typeName = ctx.ToString(parent.Xaml, type); var key = (XamlResourceKey)node.Annotation; var bamlElem = new BamlElement(node); bamlElem.Xaml = new XElement(ctx.GetKnownNamespace("Key", XamlContext.KnownNamespace_Xaml, parent.Xaml)); parent.Xaml.Element.Add(bamlElem.Xaml.Element); var typeElem = new XElement(ctx.GetKnownNamespace("TypeExtension", XamlContext.KnownNamespace_Xaml, parent.Xaml)); typeElem.AddAnnotation(ctx.ResolveType(0xfd4d)); // Known type - TypeExtension typeElem.Add(new XElement(ctx.GetPseudoName("Ctor"), typeName)); bamlElem.Xaml.Element.Add(typeElem); key.KeyElement = bamlElem; return(bamlElem); }
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) { var record = (PropertyRecord)((BamlRecordNode)node).Record; var elemType = parent.Xaml.Element.Annotation <XamlType>(); var xamlProp = ctx.ResolveProperty(record.AttributeId); var value = XamlUtils.Escape(record.Value); XAttribute attr; if (xamlProp.PropertyName == "Name" && elemType.ResolvedType.GetDefinition()?.ParentModule.IsMainModule == true) { attr = new XAttribute(ctx.GetXamlNsName("Name"), value); } else { attr = new XAttribute(xamlProp.ToXName(ctx, parent.Xaml, xamlProp.IsAttachedTo(elemType)), value); } parent.Xaml.Element.Add(attr); return(null); }
public void ResolveNamespace(XElement elem, XamlContext ctx) { if (Namespace != null) { return; } // Since XmlnsProperty records are inside the element, // the namespace is resolved after processing the element body. string xmlNs = null; if (elem.Annotation <XmlnsScope>() != null) { xmlNs = elem.Annotation <XmlnsScope>().LookupXmlns(Assembly, TypeNamespace); } if (xmlNs == null) { xmlNs = ctx.XmlNs.LookupXmlns(Assembly, TypeNamespace); } if (xmlNs == null) { var nsSeg = TypeNamespace.Split('.'); var nsName = nsSeg[nsSeg.Length - 1].ToLowerInvariant(); var prefix = nsName; int count = 0; while (elem.GetNamespaceOfPrefix(prefix) != null) { count++; prefix = nsName + count; } xmlNs = string.Format("clr-namespace:{0};assembly={1}", TypeNamespace, Assembly); elem.Add(new XAttribute(XNamespace.Xmlns + XmlConvert.EncodeLocalName(prefix), ctx.GetXmlNamespace(xmlNs))); } Namespace = xmlNs; }
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) { var record = (PropertyWithStaticResourceIdRecord)((BamlRecordNode)node).Record; var doc = new BamlElement(node); var elemAttr = ctx.ResolveProperty(record.AttributeId); doc.Xaml = new XElement(elemAttr.ToXName(ctx, null)); doc.Xaml.Element.AddAnnotation(elemAttr); parent.Xaml.Element.Add(doc.Xaml.Element); BamlNode found = node; XamlResourceKey key; do { key = XamlResourceKey.FindKeyInAncestors(found.Parent, out found); } while (key != null && record.StaticResourceId >= key.StaticResources.Count); if (key == null) { throw new Exception("Cannot find StaticResource @" + node.Record.Position); } var resNode = key.StaticResources[record.StaticResourceId]; var handler = (IDeferHandler)HandlerMap.LookupHandler(resNode.Type); var resElem = handler.TranslateDefer(ctx, resNode, doc); doc.Children.Add(resElem); resElem.Parent = doc; elemAttr.DeclaringType.ResolveNamespace(doc.Xaml, ctx); doc.Xaml.Element.Name = elemAttr.ToXName(ctx, null); return(doc); }
public string ToString(XamlContext ctx, XElement ctxElement) { var sb = new StringBuilder(); sb.Append('{'); var typeName = ctx.ToString(ctxElement, ExtensionType); if (typeName.EndsWith("Extension")) sb.Append(typeName.Substring(0, typeName.Length - 9)); else sb.Append(typeName); bool comma = false; if (Initializer != null && Initializer.Length > 0) { sb.Append(' '); for (int i = 0; i < Initializer.Length; i++) { if (comma) sb.Append(", "); WriteObject(sb, ctx, ctxElement, Initializer[i]); comma = true; } } if (NamedArguments.Count > 0) { foreach (var kvp in NamedArguments) { if (comma) sb.Append(", "); else { sb.Append(' '); comma = true; } sb.AppendFormat("{0}=", kvp.Key); WriteObject(sb, ctx, ctxElement, kvp.Value); } } sb.Append('}'); return sb.ToString(); }
bool CanInlineExt(XamlContext ctx, XElement ctxElement) { var type = ctxElement.Annotation <XamlType>(); if (type != null && type.ResolvedType != null) { var typeDef = type.ResolvedType.GetBaseType(); bool isExt = false; while (typeDef != null) { if (typeDef.FullName == "System.Windows.Markup.MarkupExtension") { isExt = true; break; } typeDef = typeDef.GetBaseType(); } if (!isExt) { return(false); } } else if (ctxElement.Annotation <XamlProperty>() == null && ctxElement.Name != ctor) { return(false); } foreach (var child in ctxElement.Elements()) { if (!CanInlineExt(ctx, child)) { return(false); } } return(true); }
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) { var record = (PropertyTypeReferenceRecord)((BamlRecordNode)node).Record; var attr = ctx.ResolveProperty(record.AttributeId); var type = ctx.ResolveType(record.TypeId); var typeName = ctx.ToString(parent.Xaml, type); var elem = new BamlElement(node); var elemAttr = ctx.ResolveProperty(record.AttributeId); elem.Xaml = new XElement(elemAttr.ToXName(ctx, null)); elem.Xaml.Element.AddAnnotation(elemAttr); parent.Xaml.Element.Add(elem.Xaml.Element); var typeElem = new XElement(ctx.GetXamlNsName("TypeExtension", parent.Xaml)); typeElem.AddAnnotation(ctx.ResolveType(0xfd4d)); // Known type - TypeExtension typeElem.Add(new XElement(ctx.GetPseudoName("Ctor"), typeName)); elem.Xaml.Element.Add(typeElem); elemAttr.DeclaringType.ResolveNamespace(elem.Xaml, ctx); elem.Xaml.Element.Name = elemAttr.ToXName(ctx, null); return elem; }
void RewriteClass(XamlContext ctx, XElement elem) { var type = elem.Annotation <XamlType>(); if (type == null || type.ResolvedType == null) { return; } var typeDef = type.ResolvedType.ResolveTypeDef(); var comparer = new AssemblyNameComparer(AssemblyNameComparerFlags.All); if (typeDef == null || !comparer.Equals(typeDef.DefinitionAssembly, ctx.Module.Assembly)) { return; } var newType = typeDef.BaseType; var xamlType = new XamlType(newType.DefinitionAssembly, newType.ReflectionNamespace, newType.Name); xamlType.ResolveNamespace(elem, ctx); elem.Name = xamlType.ToXName(ctx); var attrName = ctx.GetXamlNsName("Class", elem); var attrs = elem.Attributes().ToList(); if (typeDef.IsNotPublic) { var classModifierName = ctx.GetXamlNsName("ClassModifier", elem); attrs.Insert(0, new XAttribute(classModifierName, ctx.BamlDecompilerOptions.InternalClassModifier)); } attrs.Insert(0, new XAttribute(attrName, type.ResolvedType.ReflectionFullName)); elem.ReplaceAttributes(attrs); }
public static string ToString(this XamlContext ctx, XElement elem, XamlType type) { type.ResolveNamespace(elem, ctx); return(ctx.ToString(elem, type.ToXName(ctx))); }
public void ResolveNamespace(XElement elem, XamlContext ctx) { if (Namespace != null) { return; } // Since XmlnsProperty records are inside the element, // the namespace is resolved after processing the element body. string xmlNs = null; if (elem.Annotation <XmlnsScope>() != null) { xmlNs = elem.Annotation <XmlnsScope>().LookupXmlns(Assembly, TypeNamespace); } if (xmlNs == null) { xmlNs = ctx.XmlNs.LookupXmlns(Assembly, TypeNamespace); } // Sometimes there's no reference to System.Xaml even if x:Type is used if (xmlNs == null) { xmlNs = ctx.TryGetXmlNamespace(Assembly, TypeNamespace); } if (xmlNs == null) { if (AssemblyNameComparer.CompareAll.Equals(Assembly, ctx.Module.Assembly)) { xmlNs = $"clr-namespace:{TypeNamespace}"; } else { xmlNs = $"clr-namespace:{TypeNamespace};assembly={Assembly.Name}"; } var nsSeg = TypeNamespace.Split('.'); var prefix = nsSeg[nsSeg.Length - 1].ToLowerInvariant(); if (string.IsNullOrEmpty(prefix)) { if (string.IsNullOrEmpty(TypeNamespace)) { prefix = "global"; } else { prefix = "empty"; } } int count = 0; var truePrefix = prefix; XNamespace prefixNs, ns = ctx.GetXmlNamespace(xmlNs); while ((prefixNs = elem.GetNamespaceOfPrefix(truePrefix)) != null && prefixNs != ns) { count++; truePrefix = prefix + count; } if (prefixNs == null) { elem.Add(new XAttribute(XNamespace.Xmlns + XmlConvert.EncodeLocalName(truePrefix), ns)); if (string.IsNullOrEmpty(TypeNamespace)) { elem.AddBeforeSelf(new XComment(string.Format(dnSpy_BamlDecompiler_Resources.Msg_GlobalNamespace, truePrefix))); } } } Namespace = ctx.GetXmlNamespace(xmlNs); }
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) => null;
Dictionary <int, Action <XamlContext, XElement> > ExtractConnectionId(XamlContext ctx, MethodDef method) { var context = new DecompilerContext(method.Module) { CurrentType = method.DeclaringType, CurrentMethod = method, CancellationToken = ctx.CancellationToken }; var body = new ILBlock(new ILAstBuilder().Build(method, true, context)); new ILAstOptimizer().Optimize(context, body); var sw = body.GetSelfAndChildrenRecursive <ILSwitch>().FirstOrDefault(); if (sw == null) { return(null); } var connIds = new Dictionary <int, Action <XamlContext, XElement> >(); foreach (var cas in sw.CaseBlocks) { if (cas.Values == null) { continue; } Action <XamlContext, XElement> cb = null; foreach (var node in cas.Body) { var expr = node as ILExpression; if (expr == null) { continue; } switch (expr.Code) { case ILCode.Stfld: cb += new FieldAssignment { FieldName = ((IField)expr.Operand).Name }.Callback; break; case ILCode.Call: case ILCode.Callvirt: var operand = (IMethod)expr.Operand; if (operand.Name == "AddHandler" && operand.DeclaringType.FullName == "System.Windows.UIElement") { // Attached event var re = expr.Arguments[1]; var ctor = expr.Arguments[2]; var reField = re.Operand as IField; if (re.Code != ILCode.Ldsfld || ctor.Code != ILCode.Newobj || ctor.Arguments.Count != 2 || ctor.Arguments[1].Code != ILCode.Ldftn) { cb += new Error { Msg = string.Format(dnSpy_BamlDecompiler_Resources.Error_AttachedEvent, reField.Name) }.Callback; break; } var handler = (IMethod)ctor.Arguments[1].Operand; string evName = reField.Name; if (evName.EndsWith("Event")) { evName = evName.Substring(0, evName.Length - 5); } cb += new EventAttachment { AttachedType = reField.DeclaringType.ResolveTypeDefThrow(), EventName = evName, MethodName = handler.Name }.Callback; } else { // CLR event var add = operand.ResolveMethodDefThrow(); var ev = add.DeclaringType.Events.FirstOrDefault(e => e.AddMethod == add); var ctor = expr.Arguments[1]; if (ev == null || ctor.Code != ILCode.Newobj || ctor.Arguments.Count != 2 || ctor.Arguments[1].Code != ILCode.Ldftn) { cb += new Error { Msg = string.Format(dnSpy_BamlDecompiler_Resources.Error_AttachedEvent, add.Name) }.Callback; break; } var handler = (IMethod)ctor.Arguments[1].Operand; cb += new EventAttachment { EventName = ev.Name, MethodName = handler.Name }.Callback; } break; } } if (cb != null) { foreach (var id in cas.Values) { connIds[id] = cb; } } } return(connIds.Count == 0 ? null : connIds); }
public void Run(XamlContext ctx, XDocument document) { var mappings = DecompileEventMappings(ctx, document); ProcessConnectionIds(document.Root, mappings); }
void CheckConnectionId(XamlContext ctx, XElement elem, Dictionary<int, Action<XamlContext, XElement>> connIds) { var connId = elem.Annotation<BamlConnectionId>(); if (connId == null) return; Action<XamlContext, XElement> cb; if (!connIds.TryGetValue((int)connId.Id, out cb)) { elem.AddBeforeSelf(new XComment("Unknown connection ID: " + connId.Id)); return; } cb(ctx, elem); }
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) { return(null); }
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) { var record = (PropertyWithExtensionRecord)((BamlRecordNode)node).Record; var extTypeId = ((short)record.Flags & 0xfff); bool valTypeExt = ((short)record.Flags & 0x4000) == 0x4000; bool valStaticExt = ((short)record.Flags & 0x2000) == 0x2000; var elemType = parent.Xaml.Element.Annotation <XamlType>(); var xamlProp = ctx.ResolveProperty(record.AttributeId); var extType = ctx.ResolveType((ushort)-extTypeId); extType.ResolveNamespace(parent.Xaml, ctx); var ext = new XamlExtension(extType); if (valTypeExt || extTypeId == (short)KnownTypes.TypeExtension) { var value = ctx.ResolveType(record.ValueId); ext.Initializer = new object[] { ctx.ToString(parent.Xaml, value) }; } else if (extTypeId == (short)KnownTypes.TemplateBindingExtension) { var value = ctx.ResolveProperty(record.ValueId); value.DeclaringType.ResolveNamespace(parent.Xaml, ctx); var xName = value.ToXName(ctx, parent.Xaml, false); ext.Initializer = new object[] { ctx.ToString(parent.Xaml, xName) }; } else if (valStaticExt || extTypeId == (short)KnownTypes.StaticExtension) { string attrName; if (record.ValueId > 0x7fff) { bool isKey = true; short bamlId = (short)-record.ValueId; if (bamlId > 232 && bamlId < 464) { bamlId -= 232; isKey = false; } else if (bamlId > 464 && bamlId < 467) { bamlId -= 231; } else if (bamlId > 467 && bamlId < 470) { bamlId -= 234; isKey = false; } var res = ctx.Baml.KnownThings.Resources(bamlId); string name; if (isKey) { name = res.Item1 + "." + res.Item2; } else { name = res.Item1 + "." + res.Item3; } var xmlns = ctx.GetXmlNamespace("http://schemas.microsoft.com/winfx/2006/xaml/presentation"); attrName = ctx.ToString(parent.Xaml, xmlns.GetName(name)); } else { var value = ctx.ResolveProperty(record.ValueId); value.DeclaringType.ResolveNamespace(parent.Xaml, ctx); var xName = value.ToXName(ctx, parent.Xaml); attrName = ctx.ToString(parent.Xaml, xName); } ext.Initializer = new object[] { attrName }; } else { ext.Initializer = new object[] { XamlUtils.Escape(ctx.ResolveString(record.ValueId)) }; } var extValue = ext.ToString(ctx, parent.Xaml); var attr = new XAttribute(xamlProp.ToXName(ctx, parent.Xaml, xamlProp.IsAttachedTo(elemType)), extValue); parent.Xaml.Element.Add(attr); return(null); }
public void Callback(XamlContext ctx, XElement elem) { elem.AddBeforeSelf(new XComment(Msg)); }
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) { XamlResourceKey.Create(node); return(null); }