Esempio n. 1
0
 internal TypeNode GetTypeNodeFor(AssemblyNode assembly, Type t) {
   if (t.IsArray) {
     int rank = t.GetArrayRank();
     Type et = t.GetElementType();
     TypeNode type = assembly.GetType(Identifier.For(et.Namespace), Identifier.For(et.Name));
     return type.GetArrayType(rank);
   } else {        
     return assembly.GetType(Identifier.For(t.Namespace), Identifier.For(t.Name));
   }    
 }
 public static TypeNode FindShadow(this TypeNode typeNode, AssemblyNode shadowAssembly)
 {
     if (typeNode.DeclaringType != null)
     {
         // nested type
         var parent = typeNode.DeclaringType.FindShadow(shadowAssembly);
         
         if (parent == null) return null;
         
         return parent.GetNestedType(typeNode.Name);
     }
     
     // namespace type
     return shadowAssembly.GetType(typeNode.Namespace, typeNode.Name);
 }
Esempio n. 3
0
 public static TypeNode FindType(AssemblyNode startingPoint, Identifier ns, Identifier name)
 {
     return startingPoint.GetType(ns, name, true);
 }
Esempio n. 4
0
    /// <summary>
    /// Tries to reuse or create the attribute
    /// </summary>
    private static InstanceInitializer GetRuntimeContractsAttributeCtor(AssemblyNode assembly)
    {
      EnumNode runtimeContractsFlags = assembly.GetType(ContractNodes.ContractNamespace, Identifier.For("RuntimeContractsFlags")) as EnumNode;
      Class RuntimeContractsAttributeClass = assembly.GetType(ContractNodes.ContractNamespace, Identifier.For("RuntimeContractsAttribute")) as Class;

      if (runtimeContractsFlags == null)
      {
        #region Add [Flags]
        Member flagsConstructor = RewriteHelper.flagsAttributeNode.GetConstructor();
        AttributeNode flagsAttribute = new AttributeNode(new MemberBinding(null, flagsConstructor), null, AttributeTargets.Class);
        #endregion Add [Flags]
        runtimeContractsFlags = new EnumNode(assembly,
          null, /* declaringType */
          new AttributeList(2),
          TypeFlags.Sealed,
          ContractNodes.ContractNamespace,
          Identifier.For("RuntimeContractsFlags"),
          new InterfaceList(),
          new MemberList());
        runtimeContractsFlags.Attributes.Add(flagsAttribute);
        RewriteHelper.TryAddCompilerGeneratedAttribute(runtimeContractsFlags);
        runtimeContractsFlags.UnderlyingType = SystemTypes.Int32;

        Type copyFrom = typeof(RuntimeContractEmitFlags);
        foreach (System.Reflection.FieldInfo fi in copyFrom.GetFields())
        {
          if (fi.IsLiteral)
          {
            AddEnumValue(runtimeContractsFlags, fi.Name, fi.GetRawConstantValue());
          }
        }
        assembly.Types.Add(runtimeContractsFlags);

      }


      InstanceInitializer ctor = (RuntimeContractsAttributeClass == null) ? null : RuntimeContractsAttributeClass.GetConstructor(runtimeContractsFlags);

      if (RuntimeContractsAttributeClass == null)
      {
        RuntimeContractsAttributeClass = new Class(assembly,
          null, /* declaringType */
          new AttributeList(),
          TypeFlags.Sealed,
          ContractNodes.ContractNamespace,
          Identifier.For("RuntimeContractsAttribute"),
          SystemTypes.Attribute,
          new InterfaceList(),
          new MemberList(0));

        RewriteHelper.TryAddCompilerGeneratedAttribute(RuntimeContractsAttributeClass);
        assembly.Types.Add(RuntimeContractsAttributeClass);
      }
      if (ctor == null) {

        Block returnBlock = new Block(new StatementList(new Return()));

        Block body = new Block(new StatementList());
        Block b = new Block(new StatementList());
        ParameterList pl = new ParameterList();
        Parameter levelParameter = new Parameter(Identifier.For("contractFlags"), runtimeContractsFlags);
        pl.Add(levelParameter);

        ctor = new InstanceInitializer(RuntimeContractsAttributeClass, null, pl, body);
        ctor.Flags = MethodFlags.Assembly | MethodFlags.HideBySig | MethodFlags.SpecialName | MethodFlags.RTSpecialName;

        Method baseCtor = SystemTypes.Attribute.GetConstructor();

        b.Statements.Add(new ExpressionStatement(new MethodCall(new MemberBinding(null, baseCtor), new ExpressionList(ctor.ThisParameter))));
        b.Statements.Add(returnBlock);
        body.Statements.Add(b);

        RuntimeContractsAttributeClass.Members.Add(ctor);
      }

      return ctor;
    }
Esempio n. 5
0
        private static TypeNode GetPossiblyNestedType(AssemblyNode assem, string namespaceName, string className)
        {
            Contract.Requires(assem != null);
            Contract.Requires(className != null);

            var ns = Identifier.For(namespaceName);

            string[] pieces = className.Split('.');

            // Get outermost type
            string outerMost = pieces[0];
            TypeNode t = assem.GetType(ns, Identifier.For(outerMost));

            if (t == null) return null;

            for (int i = 1; i < pieces.Length; i++)
            {
                var piece = pieces[i];
                t = t.GetNestedType(Identifier.For(piece));
                
                if (t == null) return null;
            }

            return t;
        }
Esempio n. 6
0
    internal static void Initialize(){
      RuntimeAssembly = Runtime.GetRuntimeAssembly();

      PostCompilationPluginAttributeType = RuntimeAssembly.GetType(Identifier.For("Microsoft.SpecSharp"), Identifier.For("PostCompilationPluginAttribute"));
      ObjectConstructor = SystemTypes.Object.GetConstructor(); 
      IListAdd = SystemTypes.IList.GetMethod(StandardIds.Add, SystemTypes.Object);

#if CCINamespace
      const string ContractsNs = "Microsoft.Contracts";
#else
      const string ContractsNs = "Microsoft.Contracts";
#endif

      MustOverrideAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "MustOverrideAttribute");
    
    }
Esempio n. 7
0
        /// <summary>
        /// Creates a new instance of this class that contains the CCI nodes for contract class.
        /// </summary>
        /// <param name="errorHandler">Delegate receiving errors. If null, errors are thrown as exceptions.</param>
        ///
        private ContractNodes(AssemblyNode assembly, Action<System.CodeDom.Compiler.CompilerError> errorHandler)
        {
            if (errorHandler != null) this.ErrorFound += errorHandler;

            AssemblyNode assemblyContainingContractClass = null;

            // Get the contract class and all of its members

            assemblyContainingContractClass = assembly;
            ContractClass = assembly.GetType(ContractNamespace, Identifier.For("Contract")) as Class;
            if (ContractClass == null)
            {
                // This is not a candidate, no warning as we try to find the right place where contracts live
                return;
            }

            ContractHelperClass = assembly.GetType(ContractInternalNamespace, Identifier.For("ContractHelper")) as Class;
            if (ContractHelperClass == null || !ContractHelperClass.IsPublic)
            {
                // look in alternate location
                var alternateNs = Identifier.For("System.Diagnostics.Contracts.Internal");
                ContractHelperClass = assembly.GetType(alternateNs, Identifier.For("ContractHelper")) as Class;
            }

            // Get ContractFailureKind

            ContractFailureKind = assemblyContainingContractClass.GetType(ContractNamespace, Identifier.For("ContractFailureKind")) as EnumNode;

            // Look for each member of the contract class

            var requiresMethods = ContractClass.GetMethods(Identifier.For("Requires"), SystemTypes.Boolean);
            for (int i = 0; i < requiresMethods.Count; i++)
            {
                var method = requiresMethods[i];
                if (method.TemplateParameters != null && method.TemplateParameters.Count == 1)
                {
                    // Requires<E>
                    RequiresExceptionMethod = method;
                }
                else if (method.TemplateParameters == null || method.TemplateParameters.Count == 0)
                {
                    RequiresMethod = method;
                }
            }

            // early test to see if the ContractClass we found has a Requires(bool) method. If it doesn't, we 
            // silently think that this is not the right place.
            // We use this because contract reference assemblies have a Contract class, but it is not the right one, as it holds
            // just the 3 argument versions of all the contract methods.
            if (RequiresMethod == null)
            {
                ContractClass = null;
                return;
            }

            var requiresMethodsWithMsg = ContractClass.GetMethods(Identifier.For("Requires"), SystemTypes.Boolean, SystemTypes.String);
            for (int i = 0; i < requiresMethodsWithMsg.Count; i++)
            {
                var method = requiresMethodsWithMsg[i];
                if (method.TemplateParameters != null && method.TemplateParameters.Count == 1)
                {
                    // Requires<E>
                    RequiresExceptionWithMsgMethod = method;
                }

                else if (method.TemplateParameters == null || method.TemplateParameters.Count == 0)
                {
                    RequiresWithMsgMethod = method;
                }
            }

            EnsuresMethod = ContractClass.GetMethod(Identifier.For("Ensures"), SystemTypes.Boolean);
            
            EnsuresWithMsgMethod = ContractClass.GetMethod(Identifier.For("Ensures"), SystemTypes.Boolean, SystemTypes.String);
            EnsuresOnThrowTemplate = ContractClass.GetMethod(Identifier.For("EnsuresOnThrow"), SystemTypes.Boolean);
            EnsuresOnThrowWithMsgTemplate = ContractClass.GetMethod(Identifier.For("EnsuresOnThrow"), SystemTypes.Boolean, SystemTypes.String);

            InvariantMethod = ContractClass.GetMethod(Identifier.For("Invariant"), SystemTypes.Boolean);
            InvariantWithMsgMethod = ContractClass.GetMethod(Identifier.For("Invariant"), SystemTypes.Boolean, SystemTypes.String);

            AssertMethod = ContractClass.GetMethod(Identifier.For("Assert"), SystemTypes.Boolean);
            AssertWithMsgMethod = ContractClass.GetMethod(Identifier.For("Assert"), SystemTypes.Boolean, SystemTypes.String);

            AssumeMethod = ContractClass.GetMethod(Identifier.For("Assume"), SystemTypes.Boolean);
            AssumeWithMsgMethod = ContractClass.GetMethod(Identifier.For("Assume"), SystemTypes.Boolean, SystemTypes.String);

            ResultTemplate = ContractClass.GetMethod(ResultName);

            TypeNode GenericPredicate = SystemTypes.SystemAssembly.GetType(
                Identifier.For("System"),
                Identifier.For("Predicate" + TargetPlatform.GenericTypeNamesMangleChar + "1"));

            if (GenericPredicate != null)
            {
                ForAllGenericTemplate = ContractClass.GetMethod(ForallName, SystemTypes.GenericIEnumerable, GenericPredicate);
                ExistsGenericTemplate = ContractClass.GetMethod(ExistsName, SystemTypes.GenericIEnumerable, GenericPredicate);

                if (ForAllGenericTemplate == null)
                {
                    // The problem might be that we are in the pre 4.0 scenario and using an out-of-band contract for mscorlib
                    // in which case the contract library is defined in that out-of-band contract assembly.
                    // If so, then ForAll and Exists are defined in terms of the System.Predicate defined in the out-of-band assembly.
                    var tempGenericPredicate = assemblyContainingContractClass.GetType(
                        Identifier.For("System"),
                        Identifier.For("Predicate" + TargetPlatform.GenericTypeNamesMangleChar + "1"));

                    if (tempGenericPredicate != null)
                    {
                        GenericPredicate = tempGenericPredicate;
                        TypeNode genericIEnum =
                            assemblyContainingContractClass.GetType(Identifier.For("System.Collections.Generic"),
                                Identifier.For("IEnumerable" + TargetPlatform.GenericTypeNamesMangleChar + "1"));

                        ForAllGenericTemplate = ContractClass.GetMethod(Identifier.For("ForAll"), genericIEnum, GenericPredicate);
                        ExistsGenericTemplate = ContractClass.GetMethod(Identifier.For("Exists"), genericIEnum, GenericPredicate);
                    }
                }

                TypeNode PredicateOfInt = GenericPredicate.GetTemplateInstance(ContractClass, SystemTypes.Int32);
                if (PredicateOfInt != null)
                {
                    ForAllTemplate = ContractClass.GetMethod(Identifier.For("ForAll"), SystemTypes.Int32, SystemTypes.Int32, PredicateOfInt);
                    ExistsTemplate = ContractClass.GetMethod(Identifier.For("Exists"), SystemTypes.Int32, SystemTypes.Int32, PredicateOfInt);
                }
            }

            foreach (Member member in ContractClass.GetMembersNamed(ValueAtReturnName))
            {
                Method method = member as Method;
                if (method != null && method.Parameters.Count == 1)
                {
                    Reference reference = method.Parameters[0].Type as Reference;
                    if (reference != null && reference.ElementType.IsTemplateParameter)
                    {
                        ParameterTemplate = method;
                        break;
                    }
                }
            }

            foreach (Member member in ContractClass.GetMembersNamed(OldName))
            {
                Method method = member as Method;
                if (method != null && method.Parameters.Count == 1 && method.Parameters[0].Type.IsTemplateParameter)
                {
                    OldTemplate = method;
                    break;
                }
            }

            EndContract = ContractClass.GetMethod(Identifier.For("EndContractBlock"));
            if (this.ContractFailureKind != null)
            {
                if (ContractHelperClass != null)
                {
                    RaiseFailedEventMethod = ContractHelperClass.GetMethod(ContractNodes.RaiseContractFailedEventName,
                        this.ContractFailureKind, SystemTypes.String, SystemTypes.String, SystemTypes.Exception);

                    TriggerFailureMethod = ContractHelperClass.GetMethod(ContractNodes.TriggerFailureName,
                        this.ContractFailureKind, SystemTypes.String, SystemTypes.String, SystemTypes.String, SystemTypes.Exception);
                }
            }

            // Get the attributes

            PureAttribute = assemblyContainingContractClass.GetType(ContractNamespace, Identifier.For("PureAttribute")) as Class;
            InvariantMethodAttribute =
                assemblyContainingContractClass.GetType(ContractNamespace, Identifier.For("ContractInvariantMethodAttribute")) as Class;

            ContractClassAttribute =
                assemblyContainingContractClass.GetType(ContractNamespace, ContractClassAttributeName) as Class;

            ContractClassForAttribute =
                assemblyContainingContractClass.GetType(ContractNamespace, ContractClassForAttributeName) as Class;

            VerifyAttribute =
                assemblyContainingContractClass.GetType(ContractNamespace, Identifier.For("ContractVerificationAttribute")) as Class;
            SpecPublicAttribute =
                assemblyContainingContractClass.GetType(ContractNamespace, SpecPublicAttributeName) as Class;

            ReferenceAssemblyAttribute =
                assemblyContainingContractClass.GetType(ContractNamespace, Identifier.For("ContractReferenceAssemblyAttribute")) as Class;
            IgnoreAtRuntimeAttribute =
                assemblyContainingContractClass.GetType(ContractNamespace, RuntimeIgnoredAttributeName) as Class;

            // Check that every field in this class has been set

            foreach (System.Reflection.FieldInfo field in typeof (ContractNodes).GetFields())
            {
                if (field.GetValue(this) == null)
                {
                    string sig = null;
                    bool required = false;

                    object[] cas = field.GetCustomAttributes(typeof (RepresentationFor), false);
                    for (int i = 0, n = cas.Length; i < n; i++)
                    {
                        // should be exactly one
                        RepresentationFor rf = cas[i] as RepresentationFor;
                        if (rf != null)
                        {
                            sig = rf.runtimeName;
                            required = rf.required;
                            break;
                        }
                    }

                    if (!required) continue;
                    
                    string msg = "Could not find contract node for '" + field.Name + "'";
                    if (sig != null)
                        msg = "Could not find the method/type '" + sig + "'";

                    if (ContractClass != null && ContractClass.DeclaringModule != null)
                    {
                        msg += " in assembly '" + ContractClass.DeclaringModule.Location + "'";
                    }

                    Module dm = ContractClass.DeclaringModule;
                    
                    ClearFields();
                    CallErrorFound(dm, msg);
                    
                    return;
                }
            }

            // Check that ContractFailureKind is okay

            if (this.ContractFailureKind.GetField(Identifier.For("Assert")) == null
                || this.ContractFailureKind.GetField(Identifier.For("Assume")) == null
                || this.ContractFailureKind.GetField(Identifier.For("Invariant")) == null
                || this.ContractFailureKind.GetField(Identifier.For("Postcondition")) == null
                || this.ContractFailureKind.GetField(Identifier.For("Precondition")) == null
                )
            {
                Module dm = ContractClass.DeclaringModule;
                
                ClearFields();
                CallErrorFound(dm, "The enum ContractFailureKind must have the values 'Assert', 'Assume', 'Invariant', 'Postcondition', and 'Precondition'.");
            }
        }
        private void FuzzilyForwardReferencesFromSource2Target(AssemblyNode targetAssembly, AssemblyNode sourceAssembly)
        {
            Contract.Requires(targetAssembly != null);
            Contract.Requires(sourceAssembly != null);

            for (int i = 1, n = sourceAssembly.Types.Count; i < n; i++)
            {
                TypeNode currentType = sourceAssembly.Types[i];
                if (currentType == null) continue;

                TypeNode targetType = targetAssembly.GetType(currentType.Namespace, currentType.Name);
                if (targetType == null)
                {
                    if (Duplicator.TypesToBeDuplicated[currentType.UniqueKey] == null)
                    {
                        Duplicator.FindTypesToBeDuplicated(new TypeNodeList(currentType));
                    }

                    Trace("COPYOOB: type to be duplicated {0}", currentType.FullName);
                }
                else
                {
                    if (HelperMethods.IsContractTypeForSomeOtherType(currentType as Class))
                    {
                        // dummy contract target type. Ignore it. 
                        targetType.Members = new MemberList();
                        targetType.ClearMemberTable();
                    }

                    Contract.Assume(TemplateParameterCount(currentType) == TemplateParameterCount(targetType),
                        "Name mangling should ensure this");

                    Duplicator.DuplicateFor[currentType.UniqueKey] = targetType;

                    Trace("COPYOOB: forwarding {1} to {0}", currentType.FullName, targetType.FullName);

                    FuzzilyForwardType(currentType, targetType);
                }
            }
        }