예제 #1
0
 private static Method GetMatchingMethod(TypeNode targetType, Method templateMethod, Method wrapperMethod)
 {
   var argCount = templateMethod.Parameters == null?0:templateMethod.Parameters.Count;
   TypeNode[] argTypes = new TypeNode[argCount];
   var argOffset = 0;
   if (!IsProtected(templateMethod) && !templateMethod.IsStatic) {
     argOffset = 1;
   }
   for (int i = 0; i < argCount; i++) {
     argTypes[i] = wrapperMethod.Parameters[i + argOffset].Type;
   }
   var methods = targetType.GetMethods(templateMethod.Name, argTypes);
   for (int i = 0; i < methods.Count; i++) {
     if (TypeParameterCount(methods[i]) == TypeParameterCount(templateMethod)) {
       return methods[i];
     }
   }
   Debug.Assert(false, "Wrapper instance method not found");
   return null;
 }
예제 #2
0
    public RuntimeContractMethods(TypeNode userContractType, ContractNodes contractNodes, AssemblyNode targetAssembly,
                                  bool throwOnFailure, int rewriteLevel, bool publicSurfaceOnly, bool callSiteRequires,
                                  int recursionGuard, bool hideFromDebugger,
                                  bool userExplicitValidation
                                 )
    {
      this.contractNodes = contractNodes;
      this.targetAssembly = targetAssembly;
      this.ThrowOnFailure = throwOnFailure;
      this.RewriteLevel = rewriteLevel;
      this.PublicSurfaceOnly = publicSurfaceOnly;
      this.CallSiteRequires = callSiteRequires;
      this.regularRecursionGuard = recursionGuard;
      this.HideFromDebugger = hideFromDebugger;
      this.UseExplicitValidation = userExplicitValidation;

      // extract methods from user methods
      #region Get the user-specified rewriter methods (optional) REVIEW!! Needs a lot of error handling
      if (userContractType != null)
      {
        Method method = null;
        MethodList reqMethods = userContractType.GetMethods(Identifier.For("Requires"), SystemTypes.Boolean, SystemTypes.String, SystemTypes.String);
        for (int i = 0; i < reqMethods.Count; i++)
        {
          method = reqMethods[i];
          if (method != null)
          {
            if (method.TemplateParameters == null || method.TemplateParameters.Count != 1)
            {
              /*if (method != null) */ this.requiresMethod = method;
            }
            else
            {
              this.requiresWithExceptionMethod = method;
            }
          }
        }
        method = userContractType.GetMethod(Identifier.For("Ensures"), SystemTypes.Boolean, SystemTypes.String, SystemTypes.String);
        if (method != null) this.ensuresMethod = method;
        method = userContractType.GetMethod(Identifier.For("EnsuresOnThrow"), SystemTypes.Boolean, SystemTypes.String, SystemTypes.String, SystemTypes.Exception);
        if (method != null) this.ensuresOnThrowMethod = method;
        method = userContractType.GetMethod(Identifier.For("Invariant"), SystemTypes.Boolean, SystemTypes.String, SystemTypes.String);
        if (method != null) this.invariantMethod = method;
        method = userContractType.GetMethod(Identifier.For("Assert"), SystemTypes.Boolean, SystemTypes.String, SystemTypes.String);
        if (method != null) this.assertMethod = method;
        method = userContractType.GetMethod(Identifier.For("Assume"), SystemTypes.Boolean, SystemTypes.String, SystemTypes.String);
        if (method != null) this.assumeMethod = method;

        // Need to make sure that the type ContractFailureKind is the one used in the user-supplied methods, which is not necessarily
        // the one that is defined in the assembly that defines the contract class. For instance, extracting/rewriting from a 4.0 assembly
        // but where the user-supplied assembly is pre-4.0.
        var mems = userContractType.GetMembersNamed(ContractNodes.ReportFailureName);
        TypeNode contractFailureKind = contractNodes.ContractFailureKind;
        //if (mems != null) 
        {
          foreach(var mem in mems){
            method = mem as Method;
            if (method == null) continue;
            if (method.Parameters.Count != 4) continue;
            if (method.Parameters[0].Type.Name != contractNodes.ContractFailureKind.Name) continue;
            if (method.Parameters[1].Type != SystemTypes.String) continue;
            if (method.Parameters[2].Type != SystemTypes.String) continue;
            if (method.Parameters[3].Type != SystemTypes.Exception) continue;
            this.failureMethod = method;
            contractFailureKind = method.Parameters[0].Type;
            break;
          }
        }

        if (this.failureMethod == null) 
        {
          mems = userContractType.GetMembersNamed(ContractNodes.RaiseContractFailedEventName);
          // if (mems != null) 
          {
            foreach (var mem in mems) {
              method = mem as Method;
              if (method == null) continue;
              if (method.Parameters.Count != 4) continue;
              if (method.Parameters[0].Type.Name.UniqueIdKey != contractNodes.ContractFailureKind.Name.UniqueIdKey) continue;
              if (method.Parameters[1].Type != SystemTypes.String) continue;
              if (method.Parameters[2].Type != SystemTypes.String) continue;
              if (method.Parameters[3].Type != SystemTypes.Exception) continue;
              this.raiseFailureEventMethod = method;
              contractFailureKind = method.Parameters[0].Type;
              break;
            }
          }
        } else {
          method = userContractType.GetMethod(ContractNodes.RaiseContractFailedEventName, contractFailureKind, SystemTypes.String, SystemTypes.String, SystemTypes.Exception);
          if (method != null) this.raiseFailureEventMethod = method;
        }
        if (this.raiseFailureEventMethod != null) { // either take all both RaiseContractFailedEvent and TriggerFailure or neither
          method = userContractType.GetMethod(ContractNodes.TriggerFailureName, contractFailureKind, SystemTypes.String, SystemTypes.String, SystemTypes.String, SystemTypes.Exception);
          if (method != null) this.triggerFailureMethod = method;
        }

      }
      #endregion Get the user-specified rewriter methods (optional) REVIEW!! Needs a lot of error handling

    }