Example #1
0
        /// <summary>
        /// Adds a new Warning message.
        /// </summary>
        /// <param name="aspect">The aspect writing the Warning message</param>
        /// <param name="code">The 'code' of this specific message</param>
        /// <param name="message">The message</param>
        /// <param name="location">The location where the aspect applies to. Will show full signature.</param>
        public static void RaiseWarning(this IAspect aspect, int code, string message, MethodBase location)
        {
            if (aspect == null || message == null)
            {
                return;
            }

            Message.Write(SeverityType.Warning, aspect.GetType().Name + "[" + code + "]",
                          location != null ? "[{0}] {1}".F(location.AsSignature(true), message) : "{0}".F(message));
        }
Example #2
0
        ///<summary>
        /// Validate the aspect usage
        ///</summary>
        ///<param name="method">The method that the aspect is applied on</param>
        ///<returns>Returns true if all checks pass</returns>
        public override bool CompileTimeValidate(MethodBase method)
        {
            if (method == null)
            {
                this.RaiseError(1, "The PostCompile aspect can only be applied on methods.", method.AsSignature());

                return(false);
            }

            if (!method.IsStatic)
            {
                this.RaiseError(2, "The PostCompile aspect can only be applied on static methods.", method.AsSignature());

                return(false);
            }

            if (method.GetParameters().Length > 0)
            {
                this.RaiseError(3, "The PostCompile aspect can only be applied on methods without arguments.", method.AsSignature());

                return(false);
            }

            if (method as MethodInfo == null)
            {
                this.RaiseError(4, "The PostCompile aspect can not be applied on constructor/deconstructors", method.AsSignature());

                return(false);
            }

            if (((MethodInfo)method).ReturnType != typeof(void))
            {
                this.RaiseError(5, "The PostCompile aspect can only be applied on methods returning nothing.", method.AsSignature());

                return(false);
            }

            this.Describe("On compilation, this method will be invoked", method);

            try
            {
                method.Invoke(null, null);
                this.Describe("Last post-compile run succeeded at {0}".F(DateTime.Now), method);
            }
            catch (TargetInvocationException ex)             // when this exception is thrown, consider it a success, and optionally check if it has more descriptions to add
            {
                if (ex.InnerException is PostCompileSuccessException)
                {
                    this.Describe("Last post-compile run succeeded at {0}".F(DateTime.Now), method);

                    foreach (var d in (ex.InnerException as PostCompileSuccessException).Descriptions)
                    {
                        this.Describe(d, method);
                    }
                }
                else
                {
                    this.Describe("Last post-compile run failed at {0}".F(DateTime.Now), method);
                    this.Describe(ex.ToString(), method);
                }
            }
            catch (Exception ex)
            {
                this.Describe("Last post-compile run failed at {0}".F(DateTime.Now), method);
                this.Describe(ex.ToString(), method);
            }

            return(true);
        }
        /// <summary>
        /// Add a new description entry.
        /// </summary>
        private static void AddDescription <T>(XDocument document, Dictionary <string, string> storage, string description, MethodBase target)
        {
            if (document.Root == null)
            {
                return;
            }

            var aspectSymbol        = "T:" + typeof(T).FullName;
            var methodSymbol        = "M:" + target.AsSignature();
            var declaringTypeSymbol = "T:" + target.DeclaringType.AsSignature();

            // 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));
                //classNode.Add(new XAttribute("ClassX", GenerateSymbolId(storage) + "=" + aspectSymbol));

                // Add to the root node
                document.Root.Add(classNode);
            }

            // Get the aspect symbol id (example: #1214)
            string aspectSymbolId = GetSymbolId(classNode.Attribute("Class").Value, storage) ??
                                    classNode.Attribute("Class").Value.Substring(0,
                                                                                 classNode.Attribute("Class").Value.IndexOf("="));

            // Get the method symbol id (example: #1214)
            string methodSymbolId = GetSymbolId(methodSymbol, storage);


            bool isTypeInstanceNode = true;

            // 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) == declaringTypeSymbol)
                               .FirstOrDefault();

            // 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;
            }

            // 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;
                }
            }

            bool isPropertyMethod = false;

            // 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 - first try to find a specific match (one that has a 'Target' attribute)
            var targetNode = instanceNode
                             .Elements()
                             .Where(el => el.Name.LocalName == "Target")
                             .Where(el => el.Attribute("Target") != null)
                             .Where(el => GetSymbol(el.Attribute("Target").Value, storage) == methodSymbol)
                             .FirstOrDefault();

            // None found, try to find a 'Target' node that does not have a target,
            // but ONLY if the instance node is not a 'type' node
            if (targetNode == null && !isTypeInstanceNode)
            {
                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");

                // if its an 'type instance node', add a Target attribute
                if (isTypeInstanceNode)
                {
                    // Add the 'Declaration' attribute
                    targetNode.Add(new XAttribute("Target",
                                                  GetSymbolId(methodSymbol, storage) ??
                                                  "#" + GenerateSymbolId(storage) + "=" + methodSymbol));
                }
                // 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
            {
                if (target.Name.StartsWith("get_") || target.Name.StartsWith("set_"))
                {
                    isPropertyMethod = true;
                }
                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"));

                var oe = targetNode.Elements().FirstOrDefault(e => e.Attribute("Ordinal") != null);
                if (oe != null)
                {
                    joinPoint.Add(new XAttribute("Ordinal", oe.Attribute("Ordinal").Value));
                }
            }

            // Add it to the Target node
            targetNode.Add(joinPoint);
        }