public void Execute()
        {
            var xmlSchemaWeaver = new XmlSchemasWeaver(_msCoreReferenceFinder);

            foreach (var catelTypeNode in _catelTypeNodeBuilder.CatelTypes)
            {
                try
                {
                    if (!CatelVersionSupportsXmlSchemaManager(catelTypeNode))
                    {
                        return;
                    }

                    xmlSchemaWeaver.Execute(catelTypeNode);
                }
                catch (Exception ex)
                {
#if DEBUG
                    System.Diagnostics.Debugger.Launch();
#endif

                    string error = $"An error occurred while weaving type '{catelTypeNode.TypeDefinition.FullName}'";
                    FodyEnvironment.LogError(error);
                }
            }
        }
Ejemplo n.º 2
0
        private void ProcessProperty(CatelType catelType, CatelTypeProperty modelProperty, CustomAttribute exposeAttribute)
        {
            var modelName             = modelProperty.Name;
            var viewModelPropertyName = (string)exposeAttribute.ConstructorArguments[0].Value;
            var modelPropertyName     = viewModelPropertyName;

            if (exposeAttribute.ConstructorArguments.Count > 1)
            {
                modelPropertyName = (string)(exposeAttribute.ConstructorArguments[1].Value ?? viewModelPropertyName);
            }

            bool isReadOnly         = false;
            var  isReadOnlyProperty = (from property in exposeAttribute.Properties
                                       where string.Equals(property.Name, "IsReadOnly")
                                       select property).FirstOrDefault();

            if (isReadOnlyProperty.Argument.Value != null)
            {
                isReadOnly = (bool)isReadOnlyProperty.Argument.Value;
            }

            // Check property definition on model
            var modelType          = modelProperty.PropertyDefinition.PropertyType;
            var modelPropertyToMap = modelType.GetProperty(modelPropertyName);

            if (modelPropertyToMap == null)
            {
                FodyEnvironment.LogError($"Exposed property '{modelPropertyName}' does not exist on model '{modelType.FullName}', make sure to set the right mapping");
                return;
            }

            var modelPropertyType = modelPropertyToMap.PropertyType;

            var viewModelPropertyDefinition = new PropertyDefinition(viewModelPropertyName, PropertyAttributes.None, FodyEnvironment.ModuleDefinition.Import(modelPropertyType));

            viewModelPropertyDefinition.DeclaringType = catelType.TypeDefinition;

            catelType.TypeDefinition.Properties.Add(viewModelPropertyDefinition);

            viewModelPropertyDefinition.MarkAsCompilerGenerated(_msCoreReferenceFinder);

            var catelTypeProperty = new CatelTypeProperty(catelType.TypeDefinition, viewModelPropertyDefinition);

            catelTypeProperty.IsReadOnly = isReadOnly;

            var catelPropertyWeaver = new CatelPropertyWeaver(catelType, catelTypeProperty, _msCoreReferenceFinder);

            catelPropertyWeaver.Execute(true);

            var stringType           = _msCoreReferenceFinder.GetCoreTypeReference("String");
            var stringTypeDefinition = catelType.TypeDefinition.Module.Import(stringType);

            var attributeConstructor      = catelType.TypeDefinition.Module.Import(ViewModelToModelAttributeTypeDefinition.Constructor(false));
            var viewModelToModelAttribute = new CustomAttribute(attributeConstructor);

            viewModelToModelAttribute.ConstructorArguments.Add(new CustomAttributeArgument(stringTypeDefinition, modelName));
            viewModelToModelAttribute.ConstructorArguments.Add(new CustomAttributeArgument(stringTypeDefinition, modelPropertyName));
            viewModelPropertyDefinition.CustomAttributes.Add(viewModelToModelAttribute);
        }
Ejemplo n.º 3
0
        private bool IsPrivateReference(string assemblyName)
        {
            var privateReferences = FindPrivateReferences();

            var userProfilePath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
            var nuGetRoot       = Path.Combine(userProfilePath, ".nuget", "packages");

            // For now, ignore the target version, just check whether the package (version) contains the assembly
            foreach (var privateReference in privateReferences)
            {
                try
                {
                    // For some packages (such as Fody), there is no /lib folder, in that case we don't need
                    // to check anything
                    var path = Path.Combine(nuGetRoot, privateReference.PackageName, privateReference.Version, "lib");
                    if (!Directory.Exists(path))
                    {
                        continue;
                    }

                    FodyEnvironment.LogDebug($"Checking private reference '{privateReference}' using '{path}'");

                    var isDll = Directory.GetFiles(path, $"{assemblyName}.dll", SearchOption.AllDirectories).Any();
                    if (isDll)
                    {
                        return(true);
                    }

                    var isExe = Directory.GetFiles(path, $"{assemblyName}.exe", SearchOption.AllDirectories).Any();
                    if (isExe)
                    {
                        return(true);
                    }
                }
                catch (Exception ex)
                {
                    FodyEnvironment.LogError($"Failed to check private reference '{privateReference}':\n{ex}");
                }
            }

            return(false);
        }
Ejemplo n.º 4
0
        private List <PrivateReference> FindPrivateReferences()
        {
            var csProj = _moduleWeaver.ProjectFilePath;

            if (string.IsNullOrWhiteSpace(csProj) || !File.Exists(csProj))
            {
                return(new List <PrivateReference>());
            }

            // Assembly name != package name, so we need to go through all *private* packages to
            // see if it's a private reference. For now we have a *simple* reference structure,
            // which means only modern sdk project style is supported, and only references directly
            // listed in the csproj will be supported

            var privateReferencesCache = CacheHelper.GetCache <Dictionary <string, List <PrivateReference> > >(csProj);

            if (!privateReferencesCache.TryGetValue(csProj, out var privateReferences))
            {
                privateReferences = new List <PrivateReference>();

                try
                {
                    var element = XElement.Parse(File.ReadAllText(csProj));

                    var packageReferenceElements = element.XPathSelectElements("//PackageReference");

                    foreach (var packageReferenceElement in packageReferenceElements)
                    {
                        var includeAttribute = packageReferenceElement.Attribute("Include");
                        if (includeAttribute is null)
                        {
                            continue;
                        }

                        var packageName = includeAttribute.Value;

                        var versionAttribute = packageReferenceElement.Attribute("Version");
                        if (versionAttribute is null)
                        {
                            FodyEnvironment.LogWarning($"Could not find version attribute for '{packageName}'");
                            continue;
                        }

                        var version = versionAttribute.Value;

                        var privateAssetsAttribute = packageReferenceElement.Attribute("PrivateAssets");
                        if (privateAssetsAttribute != null)
                        {
                            if (string.Equals(privateAssetsAttribute.Value, "all", StringComparison.OrdinalIgnoreCase))
                            {
                                privateReferences.Add(new PrivateReference(packageName, version));
                                continue;
                            }
                        }

                        var privateAssetsElement = packageReferenceElement.Element("PrivateAssets");
                        if (privateAssetsElement != null)
                        {
                            if (string.Equals(privateAssetsElement.Value, "all", StringComparison.OrdinalIgnoreCase))
                            {
                                privateReferences.Add(new PrivateReference(packageName, version));
                                continue;
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    FodyEnvironment.LogError($"Failed to search for private packages in project file '{csProj}':\n{ex}");
                }

                privateReferencesCache[csProj] = privateReferences;
            }

            return(privateReferences);
        }
        public bool Execute(TypeDefinition type, MethodDefinition methodDefinition, object parameterDefinitionOrFieldDefinition, CustomAttribute attribute,
                            int instructionIndex)
        {
            TypeReference    targetType     = null;
            MethodDefinition selectedMethod = null;

            var parameterDefinition = parameterDefinitionOrFieldDefinition as ParameterDefinition;

            if (parameterDefinition != null)
            {
                targetType = parameterDefinition.ParameterType;
            }

            var fieldDefinition = parameterDefinitionOrFieldDefinition as FieldDefinition;

            if (fieldDefinition != null)
            {
                targetType = fieldDefinition.FieldType;
            }

            if (targetType != null)
            {
                try
                {
                    SelectMethod(_argumentTypeDefinition, targetType, out selectedMethod);
                }
                catch (Exception ex)
                {
                    var error = $"[{type.FullName}.{methodDefinition.Name}] {ex.Message}";

                    var sequencePoint = methodDefinition.Body.Instructions[instructionIndex].SequencePoint;
                    if (sequencePoint != null)
                    {
                        FodyEnvironment.LogErrorPoint(error, sequencePoint);
                    }
                    else
                    {
                        FodyEnvironment.LogError(error);
                    }

                    return(false);
                }
            }

            if (selectedMethod == null)
            {
                return(false);
            }

            var moduleDefinition = type.Module;
            var importedMethod   = moduleDefinition.Import(selectedMethod);

            var instructions = new List <Instruction>();

            if (parameterDefinition != null)
            {
                BuildInstructions(moduleDefinition, type, methodDefinition, parameterDefinition, attribute, instructions);
            }

            if (fieldDefinition != null)
            {
                BuildInstructions(moduleDefinition, type, methodDefinition, fieldDefinition, attribute, instructions);
            }

            if (importedMethod.HasGenericParameters)
            {
                var genericInstanceMethod = new GenericInstanceMethod(importedMethod);
                genericInstanceMethod.GenericArguments.Add(targetType);
                instructions.Add(Instruction.Create(OpCodes.Call, genericInstanceMethod));
            }
            else
            {
                instructions.Add(Instruction.Create(OpCodes.Call, importedMethod));
            }

            methodDefinition.Body.Instructions.Insert(instructionIndex, instructions);

            return(true);
        }