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