/// <summary>
        /// Returns the method contract, if any, that has been associated with the given object. Returns null if no association exits.
        /// </summary>
        /// <param name="method">An object that might have been associated with a method contract. This can be any kind of object.</param>
        /// <returns></returns>
        public IMethodContract /*?*/ GetMethodContractFor(object method)
        {
            if (this.methodsBeingExtracted.Contains(method))
            {
                // hit a cycle while chasing validators/abbreviators
                // TODO: signal error
                return(null);
            }
            else
            {
                this.methodsBeingExtracted.Add(method);
            }

            try {
                IMethodContract contract = this.underlyingContractProvider.GetMethodContractFor(method);
                if (contract != null)
                {
                    return(contract == ContractDummy.MethodContract ? null : contract);
                }

                MethodContract  result          = new MethodContract();
                IMethodContract primaryContract = null;
                if (this.oobExtractors == null)
                {
                    primaryContract = this.primaryExtractor.GetMethodContractFor(method);
                }
                bool found = false;
                if (primaryContract != null)
                {
                    found = true;
                    Microsoft.Cci.MutableContracts.ContractHelper.AddMethodContract(result, primaryContract);
                }
                if (this.oobExtractors != null)
                {
                    foreach (var oobProvider in this.oobExtractors)
                    {
                        IMethodReference methodReference = method as IMethodReference;
                        if (methodReference == null)
                        {
                            continue;              // REVIEW: Is there anything else it could be and still find a contract for it?
                        }
                        MappingMutator primaryToOobMapper = this.mapperForPrimaryToOob[oobProvider];
                        var            oobMethod          = primaryToOobMapper.Map(methodReference);

                        if (oobMethod == null)
                        {
                            continue;
                        }

                        var oobContract = oobProvider.GetMethodContractFor(oobMethod);

                        if (oobContract == null)
                        {
                            continue;
                        }

                        MappingMutator oobToPrimaryMapper = this.mapperForOobToPrimary[oobProvider];
                        oobContract = oobToPrimaryMapper.Map(oobContract);

                        var sps = new Microsoft.Cci.MutableContracts.SubstituteParameters(this.host, oobMethod.ResolvedMethod, methodReference.ResolvedMethod);
                        oobContract = sps.Rewrite(oobContract);

                        Microsoft.Cci.MutableContracts.ContractHelper.AddMethodContract(result, oobContract);
                        found = true;
                    }
                }

                // always cache so we don't try to extract more than once
                if (found)
                {
                    this.underlyingContractProvider.AssociateMethodWithContract(method, result);
                }
                else
                {
                    this.underlyingContractProvider.AssociateMethodWithContract(method, ContractDummy.MethodContract);
                    result = null;
                }
                return(result);
            } finally {
                this.methodsBeingExtracted.RemoveAt(this.methodsBeingExtracted.Count - 1);
            }
        }
Example #2
0
      public void PackageMethodContracts(IMethodDefinition method, bool isPure) {
        Contract.Requires(method != null);

        #region Package purity
        if (isPure)
          PackageContract(new XPure(this.host, isPure, docTracker));
        //Don't package anything if it isn't pure. (That way it is easyer to deal with on the Sandcastle side)
        #endregion
        #region Package contracts from this implementation
        IMethodContract thisContract;
        if (CCDocContractHelper.TryGetMethodContract(host, method, out thisContract, docTracker)) {
          PackageMethodContracts(thisContract, null, null);
        }
        #endregion
        #region Package contracts from base overrides
        if (!method.IsNewSlot) { // REVIEW: Is there a better test?
          IMethodDefinition overriddenMethod = MemberHelper.GetImplicitlyOverriddenBaseClassMethod(method) as IMethodDefinition;
          while (overriddenMethod != null && overriddenMethod != Dummy.Method) {
            IMethodContract/*?*/ overriddenContract;
            if (CCDocContractHelper.TryGetMethodContract(host, overriddenMethod, out overriddenContract, docTracker)) {
              SubstituteParameters sps = new SubstituteParameters(this.host, method, overriddenMethod);
              IMethodContract newContract = sps.Rewrite(overriddenContract) as MethodContract;
              var unspecializedMethod = MethodHelper.Unspecialize(overriddenMethod);
              var methodId = MemberHelper.GetMemberSignature(unspecializedMethod, NameFormattingOptions.DocumentationId);
              var typeName = TypeHelper.GetTypeName(unspecializedMethod.ContainingType, NameFormattingOptions.OmitContainingNamespace | NameFormattingOptions.OmitContainingType);
              PackageMethodContracts(newContract, methodId, typeName);
            }
            overriddenMethod = MemberHelper.GetImplicitlyOverriddenBaseClassMethod(overriddenMethod) as IMethodDefinition;
          }
        }
        #endregion
        #region Package contracts from implicit interface implementations
        foreach (IMethodDefinition ifaceMethod in MemberHelper.GetImplicitlyImplementedInterfaceMethods(method)) {
          IMethodContract/*?*/ ifaceContract;
          if (!CCDocContractHelper.TryGetMethodContract(host, ifaceMethod, out ifaceContract, docTracker)) {
            continue;
          }
          SubstituteParameters sps = new SubstituteParameters(this.host, method, ifaceMethod);
          IMethodContract newContract = sps.Rewrite(ifaceContract) as MethodContract;
          var unspecializedMethod = MethodHelper.Unspecialize(ifaceMethod);
          var methodId = MemberHelper.GetMemberSignature(unspecializedMethod, NameFormattingOptions.DocumentationId);
          var typeName = TypeHelper.GetTypeName(unspecializedMethod.ContainingType, NameFormattingOptions.OmitContainingNamespace | NameFormattingOptions.OmitContainingType);
          PackageMethodContracts(newContract, methodId, typeName);
        }
        #endregion
        #region Package contracts from explicit interface implementations
        // REVIEW: Why does GetExplicitlyOverriddenMethods return IMethodReference when GetImplicitlyImplementedInterfaceMethods
        // returns IMethodDefinition?
        foreach (IMethodReference ifaceMethodRef in MemberHelper.GetExplicitlyOverriddenMethods(method)) {
          IMethodDefinition/*?*/ ifaceMethod = ifaceMethodRef.ResolvedMethod;
          if (ifaceMethod == null) continue;
          IMethodContract/*?*/ ifaceContract;
          if (!CCDocContractHelper.TryGetMethodContract(host, ifaceMethod, out ifaceContract, docTracker)) {
            continue;
          }
          SubstituteParameters sps = new SubstituteParameters(this.host, method, ifaceMethod);
          IMethodContract newContract = sps.Rewrite(ifaceContract) as MethodContract;
          var unspecializedMethod = MethodHelper.Unspecialize(ifaceMethod);
          var methodId = MemberHelper.GetMemberSignature(unspecializedMethod, NameFormattingOptions.DocumentationId);
          var typeName = TypeHelper.GetTypeName(unspecializedMethod.ContainingType, NameFormattingOptions.OmitContainingNamespace | NameFormattingOptions.OmitContainingType);
          PackageMethodContracts(newContract, methodId, typeName); ;
        }
        #endregion
      }
Example #3
0
        /// <summary>
        /// Returns the method contract, if any, that has been associated with the given object. Returns null if no association exits.
        /// </summary>
        /// <param name="method">An object that might have been associated with a method contract. This can be any kind of object.</param>
        /// <returns></returns>
        /*?*/
        public IMethodContract GetMethodContractFor(object method)
        {
            if (this.methodsBeingExtracted.Contains(method)) {
            // hit a cycle while chasing validators/abbreviators
            // TODO: signal error
            return null;
              } else {
            this.methodsBeingExtracted.Add(method);
              }

              try {

            IMethodContract contract = this.underlyingContractProvider.GetMethodContractFor(method);
            if (contract != null) return contract == ContractDummy.MethodContract ? null : contract;

            MethodContract result = new MethodContract();
            IMethodContract primaryContract = this.primaryExtractor.GetMethodContractFor(method);
            bool found = false;
            if (primaryContract != null) {
              found = true;
              Microsoft.Cci.MutableContracts.ContractHelper.AddMethodContract(result, primaryContract);
            }
            if (this.oobExtractors != null) {
              foreach (var oobProvider in this.oobExtractors) {

            IMethodReference methodReference = method as IMethodReference;
            if (methodReference == null) continue; // REVIEW: Is there anything else it could be and still find a contract for it?

            MappingMutator primaryToOobMapper = this.mapperForPrimaryToOob[oobProvider];
            var oobMethod = primaryToOobMapper.Map(methodReference);

            if (oobMethod == null) continue;

            var oobContract = oobProvider.GetMethodContractFor(oobMethod);

            if (oobContract == null) continue;

            MappingMutator oobToPrimaryMapper = this.mapperForOobToPrimary[oobProvider];
            oobContract = oobToPrimaryMapper.Map(oobContract);

            var sps = new Microsoft.Cci.MutableContracts.SubstituteParameters(this.host, oobMethod.ResolvedMethod, methodReference.ResolvedMethod);
            oobContract = sps.Visit(oobContract);

            Microsoft.Cci.MutableContracts.ContractHelper.AddMethodContract(result, oobContract);
            found = true;

              }
            }

            // always cache so we don't try to extract more than once
            if (found) {
              this.underlyingContractProvider.AssociateMethodWithContract(method, result);
            } else {
              this.underlyingContractProvider.AssociateMethodWithContract(method, ContractDummy.MethodContract);
              result = null;
            }
            return result;
              } finally {
            this.methodsBeingExtracted.RemoveAt(this.methodsBeingExtracted.Count - 1);
              }
        }