/// <summary> /// Add a new description entry. /// </summary> private static void AddDescription <T>(XDocument document, Dictionary <string, string> storage, string description, PropertyInfo property, MethodInfo target) { if (document.Root == null) { return; } var aspectSymbol = "T:" + typeof(T).FullName; var methodSymbol = "M:" + target.AsSignature(); // var declaringTypeSymbol = "T:" + target.DeclaringType.AsSignature(); var propSymbol = "P:" + property.DeclaringType.AsSignature() + "::" + property.Name + "()"; // find the target 'Class' node var classNode = document.Root .Elements() .Where(el => el.Name.LocalName == "Class") .Where(el => el.Attribute("Class") != null) .Where(el => GetSymbol(el.Attribute("Class").Value, storage) == aspectSymbol) .FirstOrDefault(); // No node found for the requested aspect, create a new one if (classNode == null) { classNode = new XElement(document.Root.Name.Namespace + "Class"); // Add the 'Class' attribute classNode.Add(new XAttribute("Class", GetSymbolId(aspectSymbol, storage) ?? "#" + GenerateSymbolId(storage) + "=" + aspectSymbol)); // Add to the root node document.Root.Add(classNode); } // Get the aspect symbol id (example: #1214) // ReSharper disable PossibleNullReferenceException string aspectSymbolId = GetSymbolId(classNode.Attribute("Class").Value, storage) ?? classNode.Attribute("Class").Value.Substring(0, classNode.Attribute("Class").Value.IndexOf("=")); // ReSharper restore PossibleNullReferenceException // Get the method symbol id (example: #1214) string methodSymbolId = GetSymbolId(methodSymbol, storage); // bool isTypeInstanceNode; // find the target 'Instance' node (first check for the declaring type) var instanceNode = classNode .Elements() .Where(el => el.Name.LocalName == "Instance") .Where(el => el.Attribute("Declaration") != null) .Where(el => GetSymbol(el.Attribute("Declaration").Value, storage) == propSymbol) .FirstOrDefault(); bool isPropertyMethod = false; // ReSharper disable PossibleNullReferenceException // if not found, check if there is one for our method if (instanceNode == null) { instanceNode = classNode .Elements() .Where(el => el.Name.LocalName == "Instance") .Where(el => el.Attribute("Declaration") != null) .Where(el => GetSymbol(el.Attribute("Declaration").Value, storage) == methodSymbol) .FirstOrDefault(); //isTypeInstanceNode = false; } else { isPropertyMethod = true; } // ReSharper restore PossibleNullReferenceException // Maybe its part of a property? if (instanceNode == null) { instanceNode = classNode .Elements() .Where(el => el.Name.LocalName == "Instance") .Where(el => el.Attribute("Declaration") != null) .Where(el => GetSymbol(el.Attribute("Declaration").Value, storage).StartsWith("P:")) .Where(el => el.Elements().Any(e => e.Name.LocalName == "Target" && e.Attribute("Target") != null && GetSymbol(e.Attribute("Target").Value, storage) == methodSymbol)) .FirstOrDefault(); if (instanceNode != null) { //isTypeInstanceNode = true; } } // if not found, check if there is one for our method @ a JoinPoint (also if it refers to a property) if (instanceNode == null) { instanceNode = classNode .Elements() .Where(el => el.Name.LocalName == "Instance") .Where(el => el.Attribute("Declaration") != null) .Where(el => GetSymbol(el.Attribute("Declaration").Value, storage).StartsWith("P:")) .Where(el => el.Elements().Any(e => e.Name.LocalName == "Target" && e.Attribute("Target") == null && e.Elements().Any(ee => ee.Attribute("Advised") != null && GetSymbol(ee.Attribute("Advised").Value, storage) == methodSymbol) )) .FirstOrDefault(); if (instanceNode != null) { isPropertyMethod = true; } } // no node found for the method, create a new one (for this method) if (instanceNode == null) { instanceNode = new XElement(document.Root.Name.Namespace + "Instance"); // Add the 'Declaration' attribute instanceNode.Add(new XAttribute("Declaration", GetSymbolId(methodSymbol, storage) ?? "#" + GenerateSymbolId(storage) + "=" + methodSymbol)); // Add the 'Token' attribute instanceNode.Add(new XAttribute("Token", GenerateSymbolId(storage))); // Add to the class node classNode.Add(instanceNode); } // find the 'Target' node (the one without a 'Target' attribute) var targetNode = instanceNode .Elements() .Where(el => el.Name.LocalName == "Target") .Where(el => el.Attribute("Target") == null) .FirstOrDefault(); // Still none found, create the node if (targetNode == null) { targetNode = new XElement(document.Root.Name.Namespace + "Target"); // Add to the class node instanceNode.Add(targetNode); } // Create the JoinPoint node var joinPoint = new XElement(document.Root.Name.Namespace + "JoinPoint"); if (isPropertyMethod) { // Add the 'Advised' attribute (points to our target) joinPoint.Add(new XAttribute("Advised", methodSymbolId)); } else { // Add the 'Advising' attribute (points to our aspect) joinPoint.Add(new XAttribute("Advising", aspectSymbolId)); } // Add the 'Description' attribute with the message to be shown joinPoint.Add(new XAttribute("Description", "#" + GenerateSymbolId(storage) + "=" + description)); // add Semantic if (isPropertyMethod) { // Add the 'Advised' attribute (points to our target) joinPoint.Add(new XAttribute("Semantic", target.Name.StartsWith("get_") ? "Getter" : "Setter")); } // Add it to the Target node targetNode.Add(joinPoint); }