Beispiel #1
0
        /// <summary>
        /// Implements the .GetTypes method which returns a list of all annotated RDF classes for a given type.
        /// </summary>
        /// <param name="parameter">A type defintion.</param>
        /// <returns><c>true</c> on success, <c>false</c> otherwise.</returns>
        public override bool Execute(object parameter = null)
        {
            List <string> uris = new List <string>();

            // Accumulate the annotated RDF classes.
            foreach (CustomAttribute attribute in Type.TryGetCustomAttribute("RdfClassAttribute"))
            {
                uris.Insert(0, attribute.ConstructorArguments.First().Value.ToString());
            }

            if (uris.Count == 0)
            {
                if (!Type.Methods.Any(m => m.Name == "GetTypes"))
                {
                    string msg = "{0}: Mapped type has no annotated RDF classes and no overridden GetTypes() method.";

                    throw new Exception(string.Format(msg, Type.FullName));
                }

                return(false);
            }

            TypeDefinition[] types       = { Type };
            MethodDefinition getTypes    = null;
            MethodReference  getTypeBase = null;

            // We iterate through the type hierarchy from top to bottom and find the first GetTypes
            // method. That one serves as a template for the override method of the current type in
            // which the instructions are being replaced.
            foreach (TypeDefinition t in types.Union(Type.GetBaseTypes()).Reverse())
            {
                getTypes = t.TryGetInheritedMethod("GetTypes");

                if (getTypes != null && getTypeBase == null)
                {
                    getTypeBase = getTypes;

                    break;
                }
            }

            if (getTypes == null)
            {
                throw new ArgumentException("{0}: Found no GetTypes() method for type.", Type.FullName);
            }

            if (getTypeBase == null)
            {
                throw new ArgumentException(string.Format("{0}: Failed to find virtual base method of {1}", Type.FullName, getTypes.FullName));
            }

            // The override method must be created in the module where the type is defined.
            getTypes = getTypeBase.GetOverrideMethod(MainModule);

            MethodGeneratorTask generator = new MethodGeneratorTask(getTypes);

            generator.Instructions.AddRange(GenerateGetTypesInstructions(generator.Processor, uris));

            if (generator.CanExecute())
            {
                generator.Method.Body.MaxStackSize = 3;
                generator.Method.Body.InitLocals   = true;
                generator.Method.Body.Variables.Add(new VariableDefinition(MainModule.ImportReference(getTypeBase.ReturnType)));
                generator.Method.Body.Variables.Add(new VariableDefinition(ClassArrayType));
                generator.Execute();
                MainModule.ImportReference(ClassType);
            }

            Type.Methods.Add(getTypes);

            foreach (string uri in uris)
            {
                Log.LogMessage("{0} -> <{1}>", Type.FullName, uri);
            }

            return(true);
        }