Ejemplo n.º 1
0
    public void ReplaceOperator(TypeDefinition type, Operator @operator)
    {
        var method = WeavingInstruction.RetrieveOperatorAndAssertHasWeavingInstruction(type, @operator);

        MarkAsGeneratedCode(method.CustomAttributes);

        var body = method.Body;
        var ins  = body.Instructions;

        ins.Clear();

        AddStaticEqualsCall(type, ins);
        ins.AddReturnValue(@operator.IsEquality);

        body.OptimizeMacros();
    }
Ejemplo n.º 2
0
    public bool FindReferencesAndDetermineWhetherEqualsIsReferenced(Func <string, TypeDefinition> typeFinder)
    {
        var typeDefinition = typeFinder("System.Type");

        GetTypeFromHandle = ModuleDefinition.ImportReference(typeDefinition.FindMethod("GetTypeFromHandle", "RuntimeTypeHandle"));

        GetHashcode     = ModuleDefinition.ImportReference(TypeSystem.ObjectDefinition.FindMethod("GetHashCode"));
        GetType         = ModuleDefinition.ImportReference(TypeSystem.ObjectDefinition.FindMethod("GetType"));
        StaticEquals    = ModuleDefinition.ImportReference(TypeSystem.ObjectDefinition.FindMethod("Equals", "Object", "Object"));
        ReferenceEquals = ModuleDefinition.ImportReference(TypeSystem.ObjectDefinition.FindMethod("ReferenceEquals", "Object", "Object"));

        var enumerableType = typeFinder("System.Collections.IEnumerable");

        IEnumerableType = ModuleDefinition.ImportReference(enumerableType);
        GetEnumerator   = ModuleDefinition.ImportReference(enumerableType.FindMethod("GetEnumerator"));

        var ienumeratorDefinition = typeFinder("System.Collections.IEnumerator");

        IEnumeratorType = ModuleDefinition.ImportReference(ienumeratorDefinition);
        MoveNext        = ModuleDefinition.ImportReference(ienumeratorDefinition.FindMethod("MoveNext"));
        GetCurrent      = ModuleDefinition.ImportReference(ienumeratorDefinition.FindMethod("get_Current"));

        IEquatableType = ModuleDefinition.ImportReference(typeFinder("System.IEquatable`1"));

        var generatedCodeType = typeFinder("System.CodeDom.Compiler.GeneratedCodeAttribute");

        GeneratedCodeAttributeConstructor = ModuleDefinition.ImportReference(generatedCodeType.FindMethod(".ctor", "String", "String"));

        var debuggerNonUserCodeType = typeFinder("System.Diagnostics.DebuggerNonUserCodeAttribute");

        DebuggerNonUserCodeAttributeConstructor = ModuleDefinition.ImportReference(debuggerNonUserCodeType.FindMethod(".ctor"));

        var equalsAssemblyReference = ModuleDefinition.AssemblyReferences.SingleOrDefault(x => x.Name == "Equals");

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

        var equalsAssembly = ModuleDefinition.AssemblyResolver.Resolve(equalsAssemblyReference);
        var operatorType   = equalsAssembly.MainModule.Types.Single(x => x.Name == "Operator");
        var weaveMethod    = operatorType.Methods.Single(x => x.Name == "Weave");

        WeavingInstruction = new WeavingInstruction(weaveMethod);

        return(true);
    }
Ejemplo n.º 3
0
    public override void Execute()
    {
        if (!FindReferencesAndDetermineWhetherEqualsIsReferenced(FindType))
        {
            LogDebug("Assembly does not reference 'Equals' assembly. No work to do - exiting.");
            return;
        }

        var collectionEquals = InjectCollectionEquals(ModuleDefinition);

        var matchingTypes = GetMatchingTypes().ToArray();

        foreach (var type in matchingTypes)
        {
            var props = type.Properties;
            foreach (var prop in props)
            {
                ModuleDefinition.ImportReference(prop.PropertyType).Resolve();
            }

            var attribute = type.CustomAttributes.Single(x => x.AttributeType.Name == attributeName);
            var typeRef   = GetGenericType(type);
            var ignoreBaseClassProperties = IsPropertySet(attribute, IgnoreBaseClassProperties);

            if (!IsPropertySet(attribute, DoNotAddEquals))
            {
                var typeCheck         = 0;
                var typeCheckProperty = attribute.Properties.SingleOrDefault(x => x.Name == "TypeCheck");
                if (typeCheckProperty.Name != null)
                {
                    typeCheck = (int)typeCheckProperty.Argument.Value;
                }

                var newEquals = InjectEqualsInternal(type, typeRef, collectionEquals, ignoreBaseClassProperties);
                InjectEqualsType(type, typeRef, newEquals);
                InjectEqualsObject(type, typeRef, newEquals, typeCheck);

                var typeInterface = IEquatableType.MakeGenericInstanceType(typeRef);
                if (type.Interfaces.All(x => x.InterfaceType.FullName != typeInterface.FullName))
                {
                    type.Interfaces.Add(new InterfaceImplementation(typeInterface));
                }
            }

            if (!IsPropertySet(attribute, DoNotAddGetHashCode))
            {
                InjectGetHashCode(type, ignoreBaseClassProperties);
            }

            if (IsPropertySet(attribute, DoNotAddEqualityOperators))
            {
                WeavingInstruction.AssertNotHasWeavingInstruction(type, Operator.Equality);
                WeavingInstruction.AssertNotHasWeavingInstruction(type, Operator.Inequality);
            }
            else
            {
                ReplaceOperator(type, Operator.Equality);
                ReplaceOperator(type, Operator.Inequality);
            }
        }

        foreach (var type in matchingTypes)
        {
            RemoveFodyAttributes(type);
        }
    }