public void Process(PropertyDefinition sourceProperty)
        {
            foreach (var bindingAttribute in sourceProperty.GetCustomAttributes <BindingAttribute>())
            {
                var declaringType     = sourceProperty.DeclaringType;
                var settings          = GetBindingSettings(bindingAttribute);
                var allBindingTargets = GetBindingTargets(declaringType);
                var bindingTargets    = FilterBindingsTargets(settings, allBindingTargets);

                if (bindingTargets.Length == 0)
                {
                    throw new MissingBindingTargetException(sourceProperty.FullName, settings.TargetId);
                }


                if (_binders.TryGetValue(settings.Type, out var binder))
                {
                    binder.Bind(sourceProperty, settings, bindingTargets);
                }
                else
                {
                    LogError($"Cannot find a binder for {settings.Type} binding. Property = {sourceProperty.FullName}");
                }
            }
        }
Example #2
0
 private IEnumerable <CilCustomAttribute> GetCustomAttributes()
 {
     foreach (var handle in _propertyDef.GetCustomAttributes())
     {
         var attribute = _readers.MdReader.GetCustomAttribute(handle);
         yield return(new CilCustomAttribute(attribute, ref _readers));
     }
 }
        public void Process(PropertyDefinition sourceProperty)
        {
            foreach (var attribute in sourceProperty.GetCustomAttributes <InvokeOnChangeAttribute>())
            {
                var attributeValues   = (CustomAttributeArgument[])attribute.ConstructorArguments[0].Value;
                var targetMethodNames = attributeValues.Select(argument => (string)argument.Value);
                var declaringType     = sourceProperty.DeclaringType;
                var fromSetter        = sourceProperty.GetSetMethodOrYeet();
                // var fromGetter = sourceProperty.GetGetMethodOrYeet();
                var fromGetter = fromSetter.Parameters[0];

                foreach (var targetMethodName in targetMethodNames)
                {
                    var method = declaringType.GetMethodsInBaseHierarchy(targetMethodName).FirstOrDefault();
                    if (method == null)
                    {
                        throw new MissingTargetMethodException(targetMethodName);
                    }

                    _weaver.Weave(new WeaveMethodParameters(fromSetter, method, null, false, null), fromGetter);
                }
            }
        }
        public static void AddDependenciesDueToCustomAttributes(ref DependencyList dependencies, NodeFactory factory, EcmaMethod method)
        {
            MetadataReader         reader       = method.MetadataReader;
            MethodDefinitionHandle methodHandle = method.Handle;
            MethodDefinition       methodDef    = reader.GetMethodDefinition(methodHandle);

            // Handle custom attributes on the method
            AddDependenciesDueToCustomAttributes(ref dependencies, factory, method.Module, methodDef.GetCustomAttributes());

            // Handle custom attributes on method parameters
            foreach (ParameterHandle parameterHandle in methodDef.GetParameters())
            {
                Parameter parameter = reader.GetParameter(parameterHandle);
                AddDependenciesDueToCustomAttributes(ref dependencies, factory, method.Module, parameter.GetCustomAttributes());
            }

            // Handle custom attributes on generic method parameters
            foreach (GenericParameterHandle genericParameterHandle in methodDef.GetGenericParameters())
            {
                GenericParameter parameter = reader.GetGenericParameter(genericParameterHandle);
                AddDependenciesDueToCustomAttributes(ref dependencies, factory, method.Module, parameter.GetCustomAttributes());
            }

            // We don't model properties and events as separate entities within the compiler, so ensuring
            // we can generate custom attributes for the associated events and properties from here
            // is as good as any other place.
            //
            // As a performance optimization, we look for associated events and properties only
            // if the method is SpecialName. This is required for CLS compliance and compilers we
            // care about emit accessors like this.
            if ((methodDef.Attributes & MethodAttributes.SpecialName) != 0)
            {
                TypeDefinition declaringType = reader.GetTypeDefinition(methodDef.GetDeclaringType());

                foreach (PropertyDefinitionHandle propertyHandle in declaringType.GetProperties())
                {
                    PropertyDefinition property  = reader.GetPropertyDefinition(propertyHandle);
                    PropertyAccessors  accessors = property.GetAccessors();

                    if (accessors.Getter == methodHandle || accessors.Setter == methodHandle)
                    {
                        AddDependenciesDueToCustomAttributes(ref dependencies, factory, method.Module, property.GetCustomAttributes());
                    }
                }

                foreach (EventDefinitionHandle eventHandle in declaringType.GetEvents())
                {
                    EventDefinition @event    = reader.GetEventDefinition(eventHandle);
                    EventAccessors  accessors = @event.GetAccessors();

                    if (accessors.Adder == methodHandle || accessors.Remover == methodHandle || accessors.Raiser == methodHandle)
                    {
                        AddDependenciesDueToCustomAttributes(ref dependencies, factory, method.Module, @event.GetCustomAttributes());
                    }
                }
            }
        }
Example #5
0
        /// <summary>
        /// Gets the C# code defining the specified property.
        /// </summary>
        public static string GetDefinition(PropertyDefinition property)
        {
            var definitionBuilder = new StringBuilder();

            AppendCustomAttributes(definitionBuilder, property.GetCustomAttributes());

            // "public"
            definitionBuilder.Append("public ");

            // "static"
            if (property.GetMethod?.IsStatic == true || property.SetMethod?.IsStatic == true)
            {
                definitionBuilder.Append("static ");
            }

            // type
            definitionBuilder.Append(GetDisplayName(property.PropertyType));
            definitionBuilder.Append(" ");

            // property name or "this" if the property is an indexer
            if (property.HasParameters)
            {
                definitionBuilder.Append("this");

                // parameters (for indexers)
                definitionBuilder.Append("[");
                definitionBuilder.AppendJoin(
                    ", ",
                    property.Parameters.Select(GetDefinition)
                    );
                definitionBuilder.Append("]");
            }
            else
            {
                definitionBuilder.Append(property.Name);
            }

            definitionBuilder.Append(" ");

            // getter and setter
            var hasGetter = property.GetMethod?.IsPublic == true;
            var hasSetter = property.SetMethod?.IsPublic == true;

            definitionBuilder.Append("{ ");
            if (hasGetter)
            {
                definitionBuilder.Append("get;");
            }

            if (hasSetter)
            {
                if (hasGetter)
                {
                    definitionBuilder.Append(" ");
                }

                definitionBuilder.Append("set;");
            }
            definitionBuilder.Append(" }");

            return(definitionBuilder.ToString());
        }