internal IMethodContract Map(IMethodContract methodContract) { var result = new CodeAndContractDeepCopier(host).Copy(methodContract); var rewriter = new ActualMutator(host, targetUnit, sourceUnitIdentity); return(rewriter.Rewrite(result)); }
void WriteExceptions(XElement member, IMethodContract methodContract) { Contract.Requires(member != null); Contract.Requires(methodContract != null); Contract.Assume(methodContract.Preconditions != null, "lack of CCI2 contracts"); foreach (IPrecondition pre in methodContract.Preconditions) { if (pre.ExceptionToThrow != null) { Contract.Assume(pre.ExceptionToThrow.Type != null, "lack of CCI2 contracts"); string conditionText = ""; if (pre.OriginalSource != null) { conditionText = String.Format("If \"{0}\".", DocHelper.NegatePredicate(pre.OriginalSource)); } WriteException(member, pre.ExceptionToThrow.Type, conditionText); } } foreach (IThrownException exc in methodContract.ThrownExceptions) { Contract.Assume(exc.ExceptionType != null, "lack of CCI2 contracts"); string conditionText = ""; if (exc.Postcondition.OriginalSource != null) { conditionText = String.Format("\"{0}\" will be true.", exc.Postcondition.OriginalSource); } WriteException(member, exc.ExceptionType, conditionText); } }
/// <summary> /// Updates this's visual based on new contract information. /// </summary> public void SetContracts(IMethodContract getterContract, IMethodContract setterContract, string toolTip) { #region Disable if contracts are null or dummy if ((getterContract == null && setterContract == null) || (getterContract == ContractDummy.MethodContract && setterContract == ContractDummy.MethodContract)) { Visibility = Visibility.Collapsed; return; } #endregion #region Set tooltip if (!string.IsNullOrEmpty(toolTip)) { ToolTipContent = toolTip; } #endregion ClearContracts(); //IsPure = true; //Properties should always be pure. IsPure = (getterContract != null && getterContract.IsPure) || (setterContract != null && setterContract.IsPure); _hasNonPurityContracts = getterContract.Preconditions.Count() > 0 || getterContract.Postconditions.Count() > 0 || getterContract.ThrownExceptions.Count() > 0 || setterContract.Preconditions.Count() > 0 || setterContract.Postconditions.Count() > 0 || setterContract.ThrownExceptions.Count() > 0; StartFormatContracts(); FormatContracts(getterContract, setterContract); EndFormatContracts(); if (ShouldBeVisible) { Visibility = Visibility.Visible; } else { Visibility = Visibility.Collapsed; } ShouldRefreshLineTransformer = true; }
public bool TryGetPropertyContract(CSharpMember semanticMember, out IMethodContract getterContract, out IMethodContract setterContract) { Contract.Requires(semanticMember == null || semanticMember.IsProperty || semanticMember.IsIndexer); getterContract = null; setterContract = null; #region Check input if (semanticMember == null) { return(false); } #endregion IMethodReference getter, setter; if (!TryGetPropertyAccessorReferences(semanticMember, out getter, out setter)) { return(false); } var success = false; if (getter != null) { success |= TryGetMethodContract(getter, out getterContract); } if (setter != null) { success |= TryGetMethodContract(setter, out setterContract); } return(success); }
/// <summary> /// Updates this's visual based on new contract information. /// </summary> public void SetContracts(IMethodContract contracts, string toolTip) { #region Disable if contracts are null or dummy if (contracts == null || contracts == ContractDummy.MethodContract) { Visibility = Visibility.Collapsed; return; } #endregion #region Set tooltip if (!string.IsNullOrEmpty(toolTip)) { ToolTipContent = toolTip; } #endregion ClearContracts(); IsPure = contracts.IsPure; _hasNonPurityContracts = contracts.Preconditions.Count() > 0 || contracts.Postconditions.Count() > 0 || contracts.ThrownExceptions.Count() > 0; StartFormatContracts(); FormatContracts(contracts); EndFormatContracts(); if (ShouldBeVisible) { Visibility = Visibility.Visible; } else { Visibility = Visibility.Collapsed; } ShouldRefreshLineTransformer = true; }
private void PrintMethodContract(IMethodContract /*?*/ methodContract) { if (methodContract == null) { this.Indent(); Console.WriteLine("no contract"); return; } this.Indent(); Console.WriteLine(methodContract.IsPure ? "pure" : "not pure"); if (IteratorHelper.EnumerableIsEmpty(methodContract.Preconditions) && IteratorHelper.EnumerableIsEmpty(methodContract.Postconditions) && IteratorHelper.EnumerableIsEmpty(methodContract.ThrownExceptions)) { return; } foreach (var p in methodContract.Preconditions) { this.Indent(); Console.Write("requires "); if (!String.IsNullOrEmpty(p.OriginalSource)) { Console.Write(p.OriginalSource); } else { Console.Write(PrintExpression(p.Condition)); } Console.WriteLine(); } foreach (var p in methodContract.Postconditions) { Indent(); Console.Write("ensures "); if (!String.IsNullOrEmpty(p.OriginalSource)) { Console.Write(p.OriginalSource); } else { Console.Write(PrintExpression(p.Condition)); } Console.WriteLine(); } foreach (var p in methodContract.ThrownExceptions) { Indent(); Console.Write("throws "); Console.Write(TypeHelper.GetTypeName(p.ExceptionType, NameFormattingOptions.OmitContainingNamespace)); Console.Write(" when "); if (!String.IsNullOrEmpty(p.Postcondition.OriginalSource)) { Console.Write(p.Postcondition.OriginalSource); } else { Console.Write(PrintExpression(p.Postcondition.Condition)); } Console.WriteLine(); } }
public CciAction(IMethodDefinition method, IMethodContract contract) { System.Diagnostics.Contracts.Contract.Requires(method != null); this.method = method; this.contract = contract; }
/// <summary> /// Accumulates all elements from <paramref name="sourceContract"/> into <paramref name="targetContract"/> /// </summary> /// <param name="targetContract">Contract which is target of accumulator</param> /// <param name="sourceContract">Contract which is source of accumulator</param> public static void AddMethodContract(MethodContract targetContract, IMethodContract sourceContract) { targetContract.Locations.AddRange(sourceContract.Locations); targetContract.Preconditions.AddRange(sourceContract.Preconditions); targetContract.Postconditions.AddRange(sourceContract.Postconditions); targetContract.ThrownExceptions.AddRange(sourceContract.ThrownExceptions); targetContract.IsPure |= sourceContract.IsPure; // need the disjunction return; }
/// <summary> /// Traverses the method contract. /// </summary> public void Traverse(IMethodContract methodContract) { Contract.Requires(methodContract != null); preorderVisitor.Visit(methodContract); if (StopTraversal) { return; } TraverseChildren(methodContract); }
private static bool IsEmptyContract(IMethodContract methodContracts) { Contract.Ensures(Contract.Result <bool>() || methodContracts != null); return(methodContracts == null || (methodContracts == ContractDummy.MethodContract) || (!methodContracts.IsPure && methodContracts.Preconditions.Count() < 1 && methodContracts.Postconditions.Count() < 1 && methodContracts.ThrownExceptions.Count() < 1)); }
public IEnumerable<Bpl.Requires> getPreconditionTranslation(IMethodContract contract) { ICollection<Bpl.Requires> translatedPres = new List<Bpl.Requires>(); foreach (IPrecondition pre in contract.Preconditions) { var stmtTraverser = this.Factory.MakeStatementTraverser(sink, null, true); ExpressionTraverser exptravers = this.Factory.MakeExpressionTraverser(sink, stmtTraverser, true); exptravers.Traverse(pre.Condition); // TODO // Todo: Deal with Descriptions var req = new Bpl.Requires(pre.Token(), false, exptravers.TranslatedExpressions.Pop(), ""); translatedPres.Add(req); } return translatedPres; }
/// <summary> /// Formats this's contracts grid based on the given contract information. /// </summary> protected virtual void FormatContracts(IMethodContract getterContract, IMethodContract setterContract) { if (getterContract != null && getterContract != ContractDummy.MethodContract) { //FormatContract("Getter Contracts:", " "); FormatContracts(getterContract, "get "); } if (setterContract != null && setterContract != ContractDummy.MethodContract) { //FormatContract("Setter Contracts:", " "); FormatContracts(setterContract, "set "); } }
public IEnumerable<Bpl.Ensures> getPostconditionTranslation(IMethodContract contract) { ICollection<Bpl.Ensures> translatedPosts = new List<Bpl.Ensures>(); foreach (IPostcondition post in contract.Postconditions) { var stmtTraverser = this.Factory.MakeStatementTraverser(sink, null, true); ExpressionTraverser exptravers = this.Factory.MakeExpressionTraverser(sink, stmtTraverser, true); exptravers.Traverse(post.Condition); // Todo: Deal with Descriptions var ens = new Bpl.Ensures(post.Token(), false, exptravers.TranslatedExpressions.Pop(), ""); translatedPosts.Add(ens); } return translatedPosts; }
public IEnumerable<Bpl.IdentifierExpr> getModifiedIdentifiers(IMethodContract contract) { ICollection<Bpl.IdentifierExpr> modifiedExpr = new List<Bpl.IdentifierExpr>(); foreach (IAddressableExpression mod in contract.ModifiedVariables) { ExpressionTraverser exptravers = this.Factory.MakeExpressionTraverser(sink, null, true); exptravers.Traverse(mod); Bpl.IdentifierExpr idexp = exptravers.TranslatedExpressions.Pop() as Bpl.IdentifierExpr; if (idexp == null) { throw new TranslationException(String.Format("Cannot create IdentifierExpr for Modifyed Variable {0}", mod.ToString())); } modifiedExpr.Add(idexp); } return modifiedExpr; }
public bool TryGetMethodContractSafe(CSharpMember semanticMehod, out IMethodContract methodContract) { Contract.Requires(semanticMehod == null || semanticMehod.IsMethod || semanticMehod.IsConstructor); Contract.Ensures(!Contract.Result <bool>() || (Contract.ValueAtReturn(out methodContract) != null)); methodContract = null; #region Check input if (semanticMehod == null) { return(false); } #endregion #region Call TryGetMethodContract cautiously try { //Can we get contracts? if (!TryGetMethodContract(semanticMehod, out methodContract)) { return(false); } } #endregion #region Abort on exception //Give up on our contracts if we get an exception catch (IllFormedSemanticModelException) { return(false); } catch (InvalidOperationException e) { if (!e.Message.Contains(ContractsPackageAccessor.InvalidOperationExceptionMessage_TheSnapshotIsOutOfDate)) { throw e; } else { return(false); } } catch (System.Runtime.InteropServices.COMException e) { if (!e.Message.Contains(ContractsPackageAccessor.COMExceptionMessage_BindingFailed)) { throw e; } else { return(false); } } #endregion return(methodContract != null); }
/// <summary> /// /// </summary> /// <param name="methodContract"></param> public MethodContract(IMethodContract methodContract) { this.allocates = new List <IExpression>(methodContract.Allocates); this.frees = new List <IExpression>(methodContract.Frees); this.locations = new List <ILocation>(methodContract.Locations); this.modifiedVariables = new List <IAddressableExpression>(methodContract.ModifiedVariables); this.mustInline = methodContract.MustInline; this.postconditions = new List <IPostcondition>(methodContract.Postconditions); this.preconditions = new List <IPrecondition>(methodContract.Preconditions); this.reads = new List <IExpression>(methodContract.Reads); this.thrownExceptions = new List <IThrownException>(methodContract.ThrownExceptions); this.variants = new List <IExpression>(methodContract.Variants); this.writes = new List <IExpression>(methodContract.Writes); this.isPure = methodContract.IsPure; }
public IEnumerable <Bpl.Requires> getPreconditionTranslation(IMethodContract contract) { ICollection <Bpl.Requires> translatedPres = new List <Bpl.Requires>(); foreach (IPrecondition pre in contract.Preconditions) { var stmtTraverser = this.Factory.MakeStatementTraverser(sink, null, true); ExpressionTraverser exptravers = this.Factory.MakeExpressionTraverser(sink, stmtTraverser, true); exptravers.Traverse(pre.Condition); // TODO // Todo: Deal with Descriptions var req = new Bpl.Requires(pre.Token(), false, exptravers.TranslatedExpressions.Pop(), ""); translatedPres.Add(req); } return(translatedPres); }
/// <summary> /// Formats this's contracts grid based on the given contract information. /// </summary> protected virtual void FormatContracts(IMethodContract contracts, string headerPrefix = "") { Contract.Requires(contracts != null); foreach (var pre in contracts.Preconditions) { FormatContract(headerPrefix + "requires", pre.OriginalSource); } foreach (var post in contracts.Postconditions) { FormatContract(headerPrefix + "ensures", post.OriginalSource); } foreach (var thrown in contracts.ThrownExceptions) { FormatContract(headerPrefix + "ensures on throw", "of " + TypeHelper.GetTypeName(thrown.ExceptionType, NameFormattingOptions.OmitContainingType | NameFormattingOptions.OmitContainingNamespace) + " that " + thrown.Postcondition.OriginalSource); } }
public IEnumerable <Bpl.Ensures> getPostconditionTranslation(IMethodContract contract) { ICollection <Bpl.Ensures> translatedPosts = new List <Bpl.Ensures>(); foreach (IPostcondition post in contract.Postconditions) { var stmtTraverser = this.Factory.MakeStatementTraverser(sink, null, true); ExpressionTraverser exptravers = this.Factory.MakeExpressionTraverser(sink, stmtTraverser, true); exptravers.Traverse(post.Condition); // Todo: Deal with Descriptions var ens = new Bpl.Ensures(post.Token(), false, exptravers.TranslatedExpressions.Pop(), ""); translatedPosts.Add(ens); } return(translatedPosts); }
void PackageMethodContracts(IMethodContract methodContract, string methodId, string typeName) { Contract.Requires(methodContract != null); if (IteratorHelper.EnumerableIsNotEmpty <IPrecondition>(methodContract.Preconditions)) { PackagePreconditions(methodContract.Preconditions, methodId, typeName); } if (IteratorHelper.EnumerableIsNotEmpty <IPostcondition>(methodContract.Postconditions)) { PackagePostconditions(methodContract.Postconditions, methodId, typeName); } if (IteratorHelper.EnumerableIsNotEmpty <IThrownException>(methodContract.ThrownExceptions)) { PackageThrownExceptions(methodContract.ThrownExceptions, methodId, typeName); } }
public IEnumerable <Bpl.IdentifierExpr> getModifiedIdentifiers(IMethodContract contract) { ICollection <Bpl.IdentifierExpr> modifiedExpr = new List <Bpl.IdentifierExpr>(); foreach (IAddressableExpression mod in contract.ModifiedVariables) { ExpressionTraverser exptravers = this.Factory.MakeExpressionTraverser(sink, null, true); exptravers.Traverse(mod); Bpl.IdentifierExpr idexp = exptravers.TranslatedExpressions.Pop() as Bpl.IdentifierExpr; if (idexp == null) { throw new TranslationException(String.Format("Cannot create IdentifierExpr for Modifyed Variable {0}", mod.ToString())); } modifiedExpr.Add(idexp); } return(modifiedExpr); }
public static string FormatContracts(IMethodContract methodContracts) { //Did we get proper contracts? if (methodContracts == null) { //Return a message saying we failed to get contracts return("(Failed to properly get contracts)"); } //Do we have any contracts? if (IsEmptyContract(methodContracts)) { //Return a message saying we don't have any contracts return(null); } //Initialize our string builder var sb = new StringBuilder(); //Append the 'Contracts' header sb.Append("Contracts: "); sb.Append('\n'); //Append purity if (methodContracts.IsPure) { sb.Append(" "); sb.Append("[Pure]"); sb.Append('\n'); } FormatPrePostThrows(methodContracts, sb); //Can we get our result from the string builder? var result = sb.ToString(); //Trim the new lines from the end result = result.TrimEnd('\n'); result = SmartFormat(result); //Return our result return(result); }
public bool TryGetMethodContract(IMethodReference method, out IMethodContract methodContract) { Contract.Ensures(!Contract.Result <bool>() || (Contract.ValueAtReturn(out methodContract) != null)); methodContract = null; #region Check input if (method == null) { return(false); } #endregion try { // Resolving the method works *only* if the unit it is defined in has already been loaded. // That should have happened as part of creating the IMethodReference. var resolvedMethod = method.ResolvedMethod; if (resolvedMethod != Dummy.Method) { methodContract = ContractHelper.GetMethodContractForIncludingInheritedContracts(Host, resolvedMethod); if (methodContract == null) { methodContract = ContractDummy.MethodContract; ContractsPackageAccessor.Current.Logger.WriteToLog(String.Format("Did not find any method contract(s) for '{0}'", method.Name)); } else { ContractsPackageAccessor.Current.Logger.WriteToLog( String.Format("Got method contract(s) for '{0}': {1} preconditions, {2} postconditions", method.Name, Microsoft.Cci.IteratorHelper.EnumerableCount(methodContract.Preconditions), Microsoft.Cci.IteratorHelper.EnumerableCount(methodContract.Postconditions))); } } else { ContractsPackageAccessor.Current.Logger.WriteToLog(String.Format("Method '{0}' resolved to dummy", method.Name)); } } catch (NullReferenceException) { methodContract = null; ContractsPackageAccessor.Current.Logger.WriteToLog(String.Format("NullReferenceException thrown when getting contracts for '{0}'", method.Name)); } return(methodContract != null); }
/// <summary> /// Traverses the children of the method contract. /// </summary> public virtual void TraverseChildren(IMethodContract methodContract) { Contract.Requires(methodContract != null); Traverse(methodContract.Allocates); if (StopTraversal) { return; } Traverse(methodContract.Frees); if (StopTraversal) { return; } Traverse(methodContract.ModifiedVariables); if (StopTraversal) { return; } Traverse(methodContract.Postconditions); if (StopTraversal) { return; } Traverse(methodContract.Preconditions); if (StopTraversal) { return; } Traverse(methodContract.Reads); if (StopTraversal) { return; } Traverse(methodContract.ThrownExceptions); if (StopTraversal) { return; } Traverse(methodContract.Writes); }
public bool TryGetMethodContract(CSharpMember semanticMethod, out IMethodContract methodContract) { Contract.Requires(semanticMethod == null || semanticMethod.IsConstructor || semanticMethod.IsMethod); Contract.Ensures(!Contract.Result <bool>() || (Contract.ValueAtReturn(out methodContract) != null)); methodContract = null; #region Check input if (semanticMethod == null) { return(false); } #endregion #region Try get the reference then check for contracts IMethodReference cciMethod; if (TryGetMethodReference(semanticMethod, out cciMethod)) { if (TryGetMethodContract(cciMethod, out methodContract)) { return(true); } else { //No need, detailed logs are written at all code paths in "TryGetMethodContract" //ContractsPackageAccessor.Current.Logger.WriteToLog("Failed to get method contracts for: " + cciMethod.Name); } } else { methodContract = null; if (semanticMethod.Name != null) { ContractsPackageAccessor.Current.Logger.WriteToLog("Failed to get CCI reference for: " + semanticMethod.Name.Text); } } return(false); #endregion }
internal static string FormatPropertyContracts(IMethodContract getter, IMethodContract setter) { //Initialize our string builder var sb = new StringBuilder(); //Append the 'Contracts' header //sb.Append("Contracts: "); //sb.Append('\n'); if (!IsEmptyContract(getter)) { sb.Append("get "); sb.Append('\n'); FormatPrePostThrows(getter, sb); } if (!IsEmptyContract(setter)) { sb.Append("set "); sb.Append('\n'); FormatPrePostThrows(setter, sb); } //Can we get our result from the string builder? var result = sb.ToString(); if (result == "") { return(null); } //Trim the new lines from the end result = result.TrimEnd('\n'); result = SmartFormat(result); //Return our result return(result); }
//^ ensures this.path.Count == old(this.path.Count); /// <summary> /// Traverses the given method contract. /// </summary> public virtual void Visit(IMethodContract methodContract) { if (this.stopTraversal) return; //^ int oldCount = this.path.Count; this.path.Push(methodContract); this.Visit(methodContract.Allocates); this.Visit(methodContract.Frees); this.Visit(methodContract.ModifiedVariables); this.Visit(methodContract.Postconditions); this.Visit(methodContract.Preconditions); this.Visit(methodContract.Reads); this.Visit(methodContract.ThrownExceptions); this.Visit(methodContract.Writes); //^ assume this.path.Count == oldCount+1; //True because all of the virtual methods of this class promise not decrease this.path.Count. this.path.Pop(); }
/// <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) { IMethodContract contract = this.underlyingContractProvider.GetMethodContractFor(method); if (contract != null) { return(contract == ContractDummy.MethodContract ? null : contract); } IMethodReference methodReference = method as IMethodReference; if (methodReference == null) { this.underlyingContractProvider.AssociateMethodWithContract(method, ContractDummy.MethodContract); return(null); } IMethodDefinition methodDefinition = methodReference.ResolvedMethod; if (methodDefinition is Dummy) { this.underlyingContractProvider.AssociateMethodWithContract(method, ContractDummy.MethodContract); return(null); } if (methodDefinition.IsAbstract || methodDefinition.IsExternal) // precondition of Body getter // Need to see if the method is marked with any attributes that impact the contract { if (ContractHelper.IsPure(this.host, methodDefinition)) { var pureMC = new MethodContract() { IsPure = true, }; this.underlyingContractProvider.AssociateMethodWithContract(method, pureMC); return(pureMC); } else { this.underlyingContractProvider.AssociateMethodWithContract(method, ContractDummy.MethodContract); return(null); } } var unspecializedMethodDefintion = ContractHelper.UninstantiateAndUnspecializeMethodDefinition(methodDefinition); if (unspecializedMethodDefintion != methodDefinition) { contract = this.underlyingContractProvider.GetMethodContractFor(unspecializedMethodDefintion); if (contract != null) { return(ContractHelper.InstantiateAndSpecializeContract(this.host, contract, methodDefinition, unspecializedMethodDefintion)); } } IMethodBody methodBody = unspecializedMethodDefintion.Body; if (methodBody is Dummy) { this.underlyingContractProvider.AssociateMethodWithContract(method, ContractDummy.MethodContract); return(null); } ISourceMethodBody /*?*/ sourceMethodBody = methodBody as ISourceMethodBody; if (sourceMethodBody == null) { sourceMethodBody = Decompiler.GetCodeModelFromMetadataModel(this.host, methodBody, this.pdbReader, DecompilerOptions.AnonymousDelegates); } MethodContractAndMethodBody result = this.SplitMethodBodyIntoContractAndCode(sourceMethodBody); var methodContract = result.MethodContract; if (methodContract != null && unspecializedMethodDefintion != methodDefinition) { var instantiatedContract = ContractHelper.InstantiateAndSpecializeContract(this.host, result.MethodContract, methodDefinition, unspecializedMethodDefintion); methodContract = instantiatedContract; } #region Auto-properties get their contract from mining the invariant if (ContractHelper.IsAutoPropertyMember(host, unspecializedMethodDefintion)) { var tc = this.GetTypeContractFor(unspecializedMethodDefintion.ContainingTypeDefinition); MethodContract mc = ContractHelper.GetAutoPropertyContract(this.host, tc, unspecializedMethodDefintion); if (mc != null) { if (unspecializedMethodDefintion != methodDefinition) { var mutableContract = ContractHelper.InstantiateAndSpecializeContract(this.host, mc, methodDefinition, unspecializedMethodDefintion); mc = mutableContract; } if (methodContract == null) { methodContract = mc; } else { ContractHelper.AddMethodContract(mc, methodContract); } } } #endregion if (methodContract == null) { this.underlyingContractProvider.AssociateMethodWithContract(method, ContractDummy.MethodContract); // so we don't try to extract more than once } else { this.underlyingContractProvider.AssociateMethodWithContract(method, methodContract); } // Notify all interested parties foreach (var c in this.callbacks) { c.ProvideResidualMethodBody(methodDefinition, result.BlockStatement); } return(methodContract); }
/// <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) { var cachedContract = this.contractProviderCache.GetMethodContractFor(method); if (cachedContract != null) { return(cachedContract == ContractDummy.MethodContract ? null : cachedContract); } IMethodReference methodReference = method as IMethodReference; if (methodReference == null) { this.contractProviderCache.AssociateMethodWithContract(method, ContractDummy.MethodContract); return(null); } IMethodDefinition methodDefinition = methodReference.ResolvedMethod; if (methodDefinition is Dummy) { this.contractProviderCache.AssociateMethodWithContract(method, ContractDummy.MethodContract); return(null); } var underlyingContract = this.underlyingContractProvider.GetMethodContractFor(method); if (!methodDefinition.IsAbstract) { if (underlyingContract != null) { return(underlyingContract); } else { this.contractProviderCache.AssociateMethodWithContract(method, ContractDummy.MethodContract); return(null); } } // The method is definitely an abstract method, so either: // (a) we've never looked for a contract for it before, or else // (b) it is a specialized/instantiated method and the uninstantiated version has already // had its contract extracted. var unspecializedMethodDefinition = ContractHelper.UninstantiateAndUnspecializeMethodDefinition(methodDefinition); cachedContract = this.contractProviderCache.GetMethodContractFor(unspecializedMethodDefinition); if (cachedContract == null) // (a) // Check to see if its containing type points to a class holding the contract { IMethodDefinition /*?*/ proxyMethod = ContractHelper.GetMethodFromContractClass(this.host, unspecializedMethodDefinition); if (proxyMethod == null) { this.contractProviderCache.AssociateMethodWithContract(method, ContractDummy.MethodContract); return(null); } MethodContract cumulativeContract = new MethodContract(); if (underlyingContract != null) { ContractHelper.AddMethodContract(cumulativeContract, underlyingContract); } IMethodContract proxyContract = this.underlyingContractProvider.GetMethodContractFor(proxyMethod); ITypeReference contractClass = proxyMethod.ContainingTypeDefinition; var gtir = contractClass as IGenericTypeInstanceReference; if (gtir != null) { contractClass = gtir.GenericType; } if (proxyContract == null) { if (underlyingContract == null) { // then there was nothing on the abstract method (like purity markings) this.contractProviderCache.AssociateMethodWithContract(method, ContractDummy.MethodContract); return(null); } else { // nothing on proxy, but something on abstract method this.contractProviderCache.AssociateMethodWithContract(method, cumulativeContract); return(cumulativeContract); } } var copier = new CodeAndContractDeepCopier(this.host); proxyContract = copier.Copy(proxyContract); var cccc = new ConvertContractClassContract(this.host, contractClass, unspecializedMethodDefinition.ContainingType); proxyContract = cccc.Rewrite(proxyContract); proxyContract = ContractHelper.CopyContractIntoNewContext(this.host, proxyContract, unspecializedMethodDefinition, proxyMethod); ContractHelper.AddMethodContract(cumulativeContract, proxyContract); // Cache the unspecialized contract: specialize and instantiate on demand this.contractProviderCache.AssociateMethodWithContract(unspecializedMethodDefinition, cumulativeContract); cachedContract = cumulativeContract; } if (unspecializedMethodDefinition == methodDefinition) { return(cachedContract == ContractDummy.MethodContract ? null : cachedContract); } else // (b) { var mc = ContractHelper.InstantiateAndSpecializeContract(this.host, cachedContract, methodDefinition, unspecializedMethodDefinition); mc = (MethodContract)ContractHelper.CopyContractIntoNewContext(this.host, mc, methodDefinition, unspecializedMethodDefinition); return(mc); } }
/// <summary> /// Makes a shallow copy of the given method contract. /// </summary> public virtual MethodContract Copy(IMethodContract methodContract) { Contract.Requires(methodContract != null); Contract.Ensures(Contract.Result<MethodContract>() != null); return new MethodContract(methodContract); }
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 }
public void Visit(IMethodContract methodContract) { Contract.Assume(false); }
public void Visit(IMethodContract methodContract) { Contract.Requires(methodContract != null); throw new NotImplementedException(); }
/// <summary> /// Returns a deep copy of the <param name="methodContract"/>. /// </summary> public virtual IMethodContract Substitute(IMethodContract methodContract) { this.coneAlreadyFixed = true; return this.DeepCopy(new MethodContract(methodContract)); }
/// <summary> /// Makes a deep copy of the given method contract. /// </summary> public MethodContract Copy(IMethodContract methodContract) { var mutableCopy = this.shallowCopier.Copy(methodContract); mutableCopy.Allocates = this.Copy(mutableCopy.Allocates); mutableCopy.Frees = this.Copy(mutableCopy.Frees); mutableCopy.ModifiedVariables = this.Copy(mutableCopy.ModifiedVariables); mutableCopy.Postconditions = this.Copy(mutableCopy.Postconditions); mutableCopy.Preconditions = this.Copy(mutableCopy.Preconditions); mutableCopy.Reads = this.Copy(mutableCopy.Reads); mutableCopy.ThrownExceptions = this.Copy(mutableCopy.ThrownExceptions); mutableCopy.Writes = this.Copy(mutableCopy.Writes); return mutableCopy; }
internal static string FormatPropertyContracts(IMethodContract getter, IMethodContract setter) { //Initialize our string builder var sb = new StringBuilder(); //Append the 'Contracts' header //sb.Append("Contracts: "); //sb.Append('\n'); if (!IsEmptyContract(getter)) { sb.Append("get "); sb.Append('\n'); FormatPrePostThrows(getter, sb); } if (!IsEmptyContract(setter)) { sb.Append("set "); sb.Append('\n'); FormatPrePostThrows(setter, sb); } //Can we get our result from the string builder? var result = sb.ToString(); if (result == "") return null; //Trim the new lines from the end result = result.TrimEnd('\n'); result = SmartFormat(result); //Return our result return result; }
/// <summary> /// Returns a deep mutable copy of the given method contract. /// </summary> /// <param name="host">An object representing the application that is hosting this mutator. It is used to obtain access to some global /// objects and services such as the shared name table and the table for interning references. For the purposes of this call, the /// table for interning is what is needed.</param> /// <param name="methodContract">The method contract to copy.</param> public static MethodContract DeepCopy(IMetadataHost host, IMethodContract methodContract) { return (MethodContract)new CodeAndContractCopier(host, null).Substitute(methodContract); }
/// <summary> /// Makes a deep copy of the given method contract. /// </summary> public MethodContract Copy(IMethodContract methodContract) { Contract.Requires(methodContract != null); Contract.Ensures(Contract.Result<MethodContract>() != null); var mutableCopy = this.shallowCopier.Copy(methodContract); mutableCopy.Allocates = this.Copy(mutableCopy.Allocates); mutableCopy.Frees = this.Copy(mutableCopy.Frees); mutableCopy.ModifiedVariables = this.Copy(mutableCopy.ModifiedVariables); mutableCopy.Postconditions = this.Copy(mutableCopy.Postconditions); mutableCopy.Preconditions = this.Copy(mutableCopy.Preconditions); mutableCopy.Reads = this.Copy(mutableCopy.Reads); mutableCopy.ThrownExceptions = this.Copy(mutableCopy.ThrownExceptions); mutableCopy.Writes = this.Copy(mutableCopy.Writes); return mutableCopy; }
void PackageMethodContracts(IMethodContract methodContract, string methodId, string typeName) { Contract.Requires(methodContract != null); if (IteratorHelper.EnumerableIsNotEmpty<IPrecondition>(methodContract.Preconditions)) PackagePreconditions(methodContract.Preconditions, methodId, typeName); if (IteratorHelper.EnumerableIsNotEmpty<IPostcondition>(methodContract.Postconditions)) PackagePostconditions(methodContract.Postconditions, methodId, typeName); if (IteratorHelper.EnumerableIsNotEmpty<IThrownException>(methodContract.ThrownExceptions)) PackageThrownExceptions(methodContract.ThrownExceptions, methodId, typeName); }
/// <summary> /// /// </summary> /// <param name="methodContract"></param> public MethodContract(IMethodContract methodContract) { this.allocates = new List<IExpression>(methodContract.Allocates); this.frees = new List<IExpression>(methodContract.Frees); this.locations = new List<ILocation>(methodContract.Locations); this.modifiedVariables = new List<IAddressableExpression>(methodContract.ModifiedVariables); this.mustInline = methodContract.MustInline; this.postconditions = new List<IPostcondition>(methodContract.Postconditions); this.preconditions = new List<IPrecondition>(methodContract.Preconditions); this.reads = new List<IExpression>(methodContract.Reads); this.thrownExceptions = new List<IThrownException>(methodContract.ThrownExceptions); this.variants = new List<IExpression>(methodContract.Variants); this.writes = new List<IExpression>(methodContract.Writes); this.isPure = methodContract.IsPure; }
/// <summary> /// Traverses the method contract. /// </summary> public void Traverse(IMethodContract methodContract) { Contract.Requires(methodContract != null); if (this.preorderVisitor != null) this.preorderVisitor.Visit(methodContract); if (this.StopTraversal) return; this.TraverseChildren(methodContract); if (this.postorderVisitor != null) this.postorderVisitor.Visit(methodContract); if (this.StopTraversal) return; }
/// <summary> /// Makes a shallow copy of the given method contract. /// </summary> public virtual MethodContract Copy(IMethodContract methodContract) { return new MethodContract(methodContract); }
/// <summary> /// Traverses the children of the method contract. /// </summary> public virtual void TraverseChildren(IMethodContract methodContract) { Contract.Requires(methodContract != null); this.Traverse(methodContract.Allocates); if (this.StopTraversal) return; this.Traverse(methodContract.Frees); if (this.StopTraversal) return; this.Traverse(methodContract.ModifiedVariables); if (this.StopTraversal) return; this.Traverse(methodContract.Postconditions); if (this.StopTraversal) return; this.Traverse(methodContract.Preconditions); if (this.StopTraversal) return; this.Traverse(methodContract.Reads); if (this.StopTraversal) return; this.Traverse(methodContract.ThrownExceptions); if (this.StopTraversal) return; this.Traverse(methodContract.Writes); }
/// <summary> /// Visits the given method contract. /// </summary> public virtual void Visit(IMethodContract methodContract) { }
public bool TryGetPropertyContract(ISymbol semanticMember, out IMethodContract getterContract, out IMethodContract setterContract) { Contract.Requires(semanticMember == null || semanticMember.Kind == SymbolKind.Property); getterContract = null; setterContract = null; #region Check input if (semanticMember == null) { return false; } #endregion IMethodReference getter, setter; if (!TryGetPropertyAccessorReferences(semanticMember, out getter, out setter)) { return false; } var success = false; if (getter != null) { success |= TryGetMethodContract(getter, out getterContract); } if (setter != null) { success |= TryGetMethodContract(setter, out setterContract); } return success; }
void DoWork() { string assemblyName; Version assemblyVersion; string assemblyLocation; string typeName; int genericParameterCount; GetNecessaryInfo(out assemblyName, out assemblyVersion, out assemblyLocation, out typeName, out genericParameterCount); #region Create host var host = this._projectTracker.Host; if (host == null) { VSServiceProvider.Current.Logger.WriteToLog("Couldn't create host."); return; } #endregion #region Find and load assembly IAssembly iAssembly = null; if (assemblyName.Equals(host.CoreAssemblySymbolicIdentity.Name.Value, StringComparison.OrdinalIgnoreCase) && assemblyVersion.Equals(host.CoreAssemblySymbolicIdentity.Version)) { iAssembly = host.FindAssembly(host.CoreAssemblySymbolicIdentity); } else { var references = _projectTracker.References; VSLangProj.Reference reference = null; var assemblyNameWithoutExtension = Path.GetFileNameWithoutExtension(assemblyName); for (int i = 1; i <= references.Count; i++)//TODO: Unify this code. This process of looking up a reference from a name is also done in ContractsProvider.TryGetAssemblyReference { var tempRef = references.Item(i); string refName = tempRef.Name; if (refName.Equals(assemblyNameWithoutExtension, StringComparison.OrdinalIgnoreCase)) { reference = tempRef; break; } } if (reference != null) { IName iName = host.NameTable.GetNameFor(Path.GetFileNameWithoutExtension(reference.Path)); string culture = reference.Culture; Version version = new Version(reference.MajorVersion, reference.MinorVersion, reference.BuildNumber, reference.RevisionNumber); string location = reference.Path; var tempRef2 = new Microsoft.Cci.Immutable.AssemblyReference(host, new AssemblyIdentity(iName, culture, version, Enumerable <byte> .Empty, location)); iAssembly = host.LoadAssembly(tempRef2.AssemblyIdentity); } else { VSServiceProvider.Current.Logger.WriteToLog("Couldn't find reference for metadata file."); return; } } if (iAssembly == null || iAssembly == Dummy.Assembly) { VSServiceProvider.Current.Logger.WriteToLog("Couldn't get assembly for metadata file."); return; } #endregion #region Get contracts provider var contractsProvider = host.GetContractExtractor(iAssembly.UnitIdentity); if (contractsProvider == null) { VSServiceProvider.Current.Logger.WriteToLog("Couldn't get contracts provider."); return; } #endregion #region Collect contracts var type = UnitHelper.FindType(host.NameTable, iAssembly, typeName, genericParameterCount); if (type == null || type is Dummy) { VSServiceProvider.Current.Logger.WriteToLog("Couldn't find metadata type '" + typeName + "' in assembly."); return; } //This dictionaries will map the method/property signature to the contracts for the method/property var methodsToContracts = new Dictionary <string, IMethodContract>(type.Methods.Count()); var gettersToContracts = new Dictionary <string, IMethodContract>(); var settersToContracts = new Dictionary <string, IMethodContract>(); //Set the formatting options for property getters and setters var propertySignatureFormattingOptions = NameFormattingOptions.OmitContainingNamespace | // NameFormattingOptions.ReturnType | NameFormattingOptions.TypeParameters | NameFormattingOptions.UseTypeKeywords | NameFormattingOptions.OmitContainingType; //NameFormattingOptions.Visibility; //Set the formating options for methods var methodSignatureFormattingOptions = NameFormattingOptions.OmitContainingNamespace | NameFormattingOptions.ReturnType | NameFormattingOptions.ParameterName | NameFormattingOptions.ParameterModifiers | NameFormattingOptions.TypeParameters | NameFormattingOptions.UseTypeKeywords | NameFormattingOptions.OmitContainingType | //NameFormattingOptions.Modifiers | NameFormattingOptions.Signature //NameFormattingOptions.Visibility ; //var sourceEmitterOutput = new SourceEmitterOutputString();//TODO: Use source emitter for all my printing? Instead of the whole NameFormattingOptions ordeal. //var csSourceEmitter = new SourceEmitter(sourceEmitterOutput); foreach (var method in type.Methods) { var methodContract = ContractHelper.GetMethodContractForIncludingInheritedContracts(host, method); if (methodContract != null && methodContract != ContractDummy.MethodContract) { if (IsGetter(method)) { if (method.ParameterCount > 0) //We have an indexer! { var indexerSignature = PrintIndexer(method, true); gettersToContracts.Add(indexerSignature, methodContract); } else { var getterSignature = MemberHelper.GetMemberSignature(method, propertySignatureFormattingOptions);//Example: "XmlSchemaSet Schemas.get" getterSignature = getterSignature.Substring(0, getterSignature.LastIndexOf('.')); gettersToContracts.Add(getterSignature, methodContract); } } else if (IsSetter(method)) { if (method.ParameterCount > 1) //We have an indexer! { var indexerSignature = PrintIndexer(method, false); settersToContracts.Add(indexerSignature, methodContract); } else { var setterSignature = MemberHelper.GetMemberSignature(method, propertySignatureFormattingOptions); setterSignature = setterSignature.Substring(0, setterSignature.LastIndexOf('.')); settersToContracts.Add(setterSignature, methodContract); } } else { //#region Print method, stolen from CSharpSourceEmitter //csSourceEmitter.PrintMethodDefinitionVisibility(method); //csSourceEmitter.PrintMethodDefinitionModifiers(method); //bool conversion = csSourceEmitter.IsConversionOperator(method); //if (!conversion) { // csSourceEmitter.PrintMethodDefinitionReturnType(method); // if (!method.IsConstructor && !csSourceEmitter.IsDestructor(method)) // csSourceEmitter.PrintToken(CSharpToken.Space); //} //csSourceEmitter.PrintMethodDefinitionName(method); //if (conversion) // csSourceEmitter.PrintMethodDefinitionReturnType(method); //if (method.IsGeneric) { // csSourceEmitter.Traverse(method.GenericParameters); //} //csSourceEmitter.Traverse(method.Parameters); //#endregion //var methodSignature = sourceEmitterOutput.Data; //sourceEmitterOutput.ClearData(); var methodSignature = MemberHelper.GetMemberSignature(method, methodSignatureFormattingOptions);//Example: "XmlAttribute CreateAttribute(string name)" methodsToContracts.Add(methodSignature, methodContract); } } } #endregion var hasMethodContracts = methodsToContracts.Count > 0; var hasPropertyContracts = gettersToContracts.Count > 0 || settersToContracts.Count > 0; if (!hasMethodContracts && !hasPropertyContracts) { VSServiceProvider.Current.Logger.WriteToLog("No contracts found."); return; } int propertyCounter = 0; //Counts the number of adornments added for property contracts int methodCounter = 0; //Counts the number of adornments added for method contracts foreach (var line in _textView.TextSnapshot.Lines) { var lineText = line.GetText(); //Skip lines with comments //This assumes that no method/property decelerations in metadata files will have comments in them if (lineText.Contains("//")) { continue; } // bail out on nested types var typeNameMatch = Regex.Match(lineText, @"(class|struct|interface|enum) (\w+)"); if (typeNameMatch.Success) { if (typeNameMatch.Groups[2].Value == type.Name.Value) { continue; } break; } if (hasPropertyContracts && lineText.Contains('{') && (lineText.Contains(" get; ") || lineText.Contains(" set; ")) && lineText.Contains('}')) //Check if line is a property decleration { #region Add property contracts //Parse the property decleration to get a signature we can compare to our contract dictionaries //Example of a property decleration: " public int Build { get; }" int endOfSig = lineText.IndexOf('{') - 1; int startOfSig = endOfSig - 1; bool hasHitSpace = false; bool isInPropertyParameter = false; for (int i = startOfSig; i > 0; i--) { char c = lineText[i]; if (c == ']') { isInPropertyParameter = true; } else if (c == '[') { isInPropertyParameter = false; } else if (hasHitSpace && c == ' ') { startOfSig = i + 1; break; } else if (!isInPropertyParameter && c == ' ') { startOfSig = i + 1; break; // MAF: ignore return type of properties. //hasHitSpace = true; } } var propertySignature = lineText.Substring(startOfSig, endOfSig - startOfSig); //Example: "int Build" IMethodContract getterContract = null; IMethodContract setterContract = null; if (gettersToContracts.TryGetValue(propertySignature, out getterContract) | // yes eager evaluation!!! settersToContracts.TryGetValue(propertySignature, out setterContract)) { var tag = propertySignature.GetHashCode();//We use this to uniquely identify the particular method/property decleration //Find this first non-whitespace character. This is were we'll place the adornment. int firstNonWhitespace = 0; for (int i = 0; i < lineText.Length; i++) { char c = lineText[i]; if (c != ' ') { firstNonWhitespace = i; break; } } var span = _textView.TextSnapshot.CreateTrackingSpan(line.Start + firstNonWhitespace, propertySignature.Length, SpanTrackingMode.EdgeExclusive); _vsTextProperties.LineHeight = _textView.LineHeight; var ops = AdornmentOptionsHelper.GetAdornmentOptions(VSServiceProvider.Current.VSOptionsPage); var adornment = new MetadataContractAdornment(span, _vsTextProperties, VSServiceProvider.Current.Logger, _adornmentManager.QueueRefreshLineTransformer, ops); adornment.SetContracts(getterContract, setterContract, null /* "Contracts from " + typeName + "." */); _adornmentManager.AddAdornment(adornment, tag); propertyCounter++; } #endregion continue; } if (hasMethodContracts && lineText.Contains('(') && lineText.Contains(')') && lineText.Contains(';')) //Check if line is a method decleration { #region Add method contracts //Parse the method decleration to get a signature we can compare to our contract dictionaries //Example of a method decleration: " public static Version Parse(string input);" int endOfSig = lineText.LastIndexOf(')') + 1; //int startOfSig = !Char.IsWhiteSpace(lineText[0]) ? 0 : lineText.IndexOf(lineText.First(c => !Char.IsWhiteSpace(c))); //int startOfSig = lineText.IndexOf('('); //bool hitSpace = false; //for (int i = startOfSig; i > 0; i--) { // char c = lineText[i]; // if (c == ' ' && hitSpace) { // startOfSig = i + 1; // break; // } else if (c == ' ') { // hitSpace = true; // } //} var methodSignature = lineText.Substring(0, endOfSig); //Example: "Version Parse(string input)" // remove modifiers methodSignature = Regex.Replace(methodSignature, modifierFilter, ""); methodSignature = methodSignature.Trim(); if (methodSignature.StartsWith(type.Name.Value + "(")) { methodSignature = "void .ctor" + methodSignature.Substring(type.Name.Value.Length); } IMethodContract methodContract; if (methodsToContracts.TryGetValue(methodSignature, out methodContract)) { var tag = methodSignature.GetHashCode();//We use this to uniquely identify the particular method/property decleration //Find this first non-whitespace character. This is were we'll place the adornment. int firstNonWhitespace = 0; for (int i = 0; i < lineText.Length; i++) { char c = lineText[i]; if (c != ' ') { firstNonWhitespace = i; break; } } var span = _textView.TextSnapshot.CreateTrackingSpan(line.Start + firstNonWhitespace, methodSignature.Length, SpanTrackingMode.EdgeExclusive); _vsTextProperties.LineHeight = _textView.LineHeight; var ops = AdornmentOptionsHelper.GetAdornmentOptions(VSServiceProvider.Current.VSOptionsPage); var adornment = new MetadataContractAdornment(span, _vsTextProperties, VSServiceProvider.Current.Logger, _adornmentManager.QueueRefreshLineTransformer, ops); adornment.SetContracts(methodContract, "Contracts from " + typeName + "."); _adornmentManager.AddAdornment(adornment, tag); //if (methodContract.IsPure) { // var purityAdornment = new PurityAdornment(_vsTextProperties, adornment); // //_adornmentManager.AddAdornment(purityAdornment, null); //} methodCounter++; } #endregion continue; } } #region Add button to collapse all contracts if (propertyCounter > 0 || methodCounter > 0) { var button = new Button(); button.Content = "Hide all contracts"; button.Click += OnCollapseAllClick; button.Cursor = Cursors.Hand; var collapseAllAdornment = new StaticAdornment(false, 10d, true, 10d, button); _adornmentManager.AddStaticAdornment(collapseAllAdornment); } #endregion }
public bool TryGetMethodContract(ISymbol semanticMethod, out IMethodContract methodContract) { Contract.Requires(semanticMethod == null || semanticMethod.Kind == SymbolKind.Method); Contract.Ensures(!Contract.Result<bool>() || (Contract.ValueAtReturn(out methodContract) != null)); methodContract = null; #region Check input if (semanticMethod == null) { return false; } #endregion #region Try get the reference then check for contracts IMethodReference cciMethod; if (TryGetMethodReference(semanticMethod, out cciMethod)) { if (TryGetMethodContract(cciMethod, out methodContract)) { return true; } else { //No need, detailed logs are written at all code paths in "TryGetMethodContract" //ContractsPackageAccessor.Current.Logger.WriteToLog("Failed to get method contracts for: " + cciMethod.Name); } } else { methodContract = null; if (semanticMethod.Name != null) { ContractsPackageAccessor.Current.Logger.WriteToLog("Failed to get CCI reference for: " + semanticMethod.Name); } } return false; #endregion }
public virtual IEnumerable<Bpl.IdentifierExpr> getModifiedIdentifiers(IMethodContract contract) { return new List<Bpl.IdentifierExpr>(); }
public bool TryGetMethodContract(IMethodReference method, out IMethodContract methodContract) { Contract.Ensures(!Contract.Result<bool>() || (Contract.ValueAtReturn(out methodContract) != null)); methodContract = null; #region Check input if (method == null) { return false; } #endregion try { // Resolving the method works *only* if the unit it is defined in has already been loaded. // That should have happened as part of creating the IMethodReference. var resolvedMethod = method.ResolvedMethod; if (resolvedMethod != Dummy.Method) { methodContract = ContractHelper.GetMethodContractForIncludingInheritedContracts(Host, resolvedMethod); if (methodContract == null) { methodContract = ContractDummy.MethodContract; ContractsPackageAccessor.Current.Logger.WriteToLog(String.Format("Did not find any method contract(s) for '{0}'", method.Name)); } else { ContractsPackageAccessor.Current.Logger.WriteToLog( String.Format("Got method contract(s) for '{0}': {1} preconditions, {2} postconditions", method.Name, Microsoft.Cci.IteratorHelper.EnumerableCount(methodContract.Preconditions), Microsoft.Cci.IteratorHelper.EnumerableCount(methodContract.Postconditions))); } } else { ContractsPackageAccessor.Current.Logger.WriteToLog(String.Format("Method '{0}' resolved to dummy", method.Name)); } } catch (NullReferenceException) { methodContract = null; ContractsPackageAccessor.Current.Logger.WriteToLog(String.Format("NullReferenceException thrown when getting contracts for '{0}'", method.Name)); } return methodContract != null; }
/// <summary> /// Wraps a call to GetMethodContractFor inside of a try-catch statement. /// </summary> public static bool TryGetMethodContract(CodeContractAwareHostEnvironment host, IMethodReference method, out IMethodContract methodContract, DocTracker docTracker) { Contract.Requires(host != null); Contract.Requires(method != null); Contract.Ensures(!Contract.Result <bool>() || Contract.ValueAtReturn(out methodContract) != null); try { methodContract = ContractHelper.GetMethodContractFor(host, method.ResolvedMethod); } catch (NullReferenceException) { docTracker.WriteLine("ERROR: NullReferenceException was thrown in CCI!"); methodContract = null; } //} catch (Exception e) { // docTracker.WriteLine("ERROR: Exception of type '{0}' was thrown in CCI!", e.GetType().Name); // docTracker.WriteLine("\t'{0}'", e.Message); // methodContract = null; //} return(methodContract != null); }
public bool TryGetMethodContractSafe(ISymbol semanticMehod, out IMethodContract methodContract) { Contract.Requires(semanticMehod == null || semanticMehod.Kind == SymbolKind.Method); Contract.Ensures(!Contract.Result<bool>() || (Contract.ValueAtReturn(out methodContract) != null)); methodContract = null; #region Check input if (semanticMehod == null) { return false; } #endregion #region Call TryGetMethodContract cautiously try { //Can we get contracts? if (!TryGetMethodContract(semanticMehod, out methodContract)) return false; } #endregion #region Abort on exception //Give up on our contracts if we get an exception catch (IllFormedSemanticModelException) { return false; } catch (InvalidOperationException e) { if (!e.Message.Contains(ContractsPackageAccessor.InvalidOperationExceptionMessage_TheSnapshotIsOutOfDate)) throw e; else return false; } catch (System.Runtime.InteropServices.COMException e) { if (!e.Message.Contains(ContractsPackageAccessor.COMExceptionMessage_BindingFailed)) throw e; else return false; } #endregion return methodContract != null; }
static void RecursivelyLookupContractsForMethods(InheritanceTracker @this) { Contract.Requires(@this != null); #region Dequeue if (@this._methodsNeedingContractLookup.Count < 1) { return; } var methodPair = @this._methodsNeedingContractLookup.Dequeue(); var method = methodPair.Value; var tag = methodPair.Key; #endregion try { ContractsPackageAccessor.Current.Logger.WriteToLog(String.Format("Attempting to lookup contracts for '{0}'", tag.ToString())); var comp = @this._textViewTracker.LatestCompilation; if (comp == null) { ContractsPackageAccessor.Current.Logger.WriteToLog("No LatestCompilation, waiting for a new semantic model."); @this._textViewTracker.IsLatestCompilationStale = true; Utilities.Delay(() => ContractsPackageAccessor.Current.AskForNewVSModel(), DelayOnVSModelFailedBeforeTryingAgain); @this.semanticModelsFetchedCounter++; goto RequeueAndAbort; } #region Get semantic method from syntactic method CSharpMember semanticMethod = null; semanticMethod = comp.GetMemberForMethodDeclaration(method); if (semanticMethod == null) { if (@this.trackingNumberOfFetchedSemanticModels && @this.semanticModelsFetchedCounter <= 3) { ContractsPackageAccessor.Current.Logger.WriteToLog("Failed to get semantic method from syntactic method, waiting for a new semantic model."); @this._textViewTracker.IsLatestCompilationStale = true; Utilities.Delay(() => ContractsPackageAccessor.Current.AskForNewVSModel(), DelayOnVSModelFailedBeforeTryingAgain); @this.semanticModelsFetchedCounter++; goto RequeueAndAbort; } else { ContractsPackageAccessor.Current.Logger.WriteToLog("Failed to get semantic method from syntactic method. Too many semantic models have already been fetched, skipping this method..."); goto Continue; } } #endregion #region Try get the method that this method is inherited from CSharpMember inheritedFromMethod; if (!TryGetIheritedFromMember(semanticMethod, method.Parent as TypeDeclarationNode, out inheritedFromMethod)) { goto Continue; } #endregion #region Uninstantiated method semanticMethod = semanticMethod.Uninstantiate(); #endregion #region Get our tool tip var toolTip = ""; if (!semanticMethod.IsAbstract && !semanticMethod.ContainingType.IsInterface) { toolTip = String.Format("Contracts inherited from {0}.", inheritedFromMethod.ContainingType.Name.Text); } #endregion #region Try get method contracts and update adornment IMethodContract contracts = null; if (((ContractsProvider)@this._textViewTracker.ProjectTracker.ContractsProvider).TryGetMethodContract(inheritedFromMethod, out contracts)) { var possibleAdornment = @this._adornmentManager.GetAdornment(tag); if (possibleAdornment != null) { var adornment = possibleAdornment as ContractAdornment; if (adornment != null) { adornment.SetContracts(contracts, toolTip); } else { ContractsPackageAccessor.Current.Logger.WriteToLog("Placeholder adornment isn't a ContractAdornment (not good!), skipping method..."); } } else { ContractsPackageAccessor.Current.Logger.WriteToLog("Placeholder adornment not found, skipping method..."); } } #endregion } #region Exception handeling catch (IllFormedSemanticModelException e) { if (@this.trackingNumberOfFetchedSemanticModels && @this.semanticModelsFetchedCounter <= 2) { ContractsPackageAccessor.Current.Logger.WriteToLog("Error: An 'IllFormedSemanticModelException' occured: '" + e.Message + "' Asking for a new semantic model..."); @this._textViewTracker.IsLatestCompilationStale = true; ContractsPackageAccessor.Current.AskForNewVSModel(); @this.semanticModelsFetchedCounter++; goto RequeueAndAbort; } else { ContractsPackageAccessor.Current.Logger.WriteToLog("An 'IllFormedSemanticModelException' occured: '" + e.Message + "' Too many semantic models have been fetched, skipping this method..."); goto Continue; } } catch (InvalidOperationException e) { if (e.Message.Contains(ContractsPackageAccessor.InvalidOperationExceptionMessage_TheSnapshotIsOutOfDate)) { if (@this.trackingNumberOfFetchedSemanticModels && @this.semanticModelsFetchedCounter <= 5) { ContractsPackageAccessor.Current.Logger.WriteToLog("The Visual Studio Semantic/Syntactic model threw an exception (it's snapshot is out of date) while looking up contracts, getting new compilation..."); @this._textViewTracker.IsLatestCompilationStale = true; ContractsPackageAccessor.Current.AskForNewVSModel(); @this.semanticModelsFetchedCounter++; goto RequeueAndAbort; } else { ContractsPackageAccessor.Current.Logger.WriteToLog("The Visual Studio Semantic/Syntactic model threw an exception (it's snapshot is out of date) while looking up contracts. Too many compilations have already been fetched, skipping this method..."); goto Continue; } } else { throw e; } } catch (COMException e) { if (e.Message.Contains(ContractsPackageAccessor.COMExceptionMessage_BindingFailed)) { if (@this.trackingNumberOfFetchedSemanticModels && @this.semanticModelsFetchedCounter <= 5) { ContractsPackageAccessor.Current.Logger.WriteToLog("The Visual Studio Semantic/Syntactic model threw an exception (it's snapshot is out of date) while looking up contracts, getting new compilation..."); @this._textViewTracker.IsLatestCompilationStale = true; ContractsPackageAccessor.Current.AskForNewVSModel(); @this.semanticModelsFetchedCounter++; goto RequeueAndAbort; } else { ContractsPackageAccessor.Current.Logger.WriteToLog("The Visual Studio Semantic/Syntactic model threw an exception (it's snapshot is out of date) while looking up contracts. Too many compilations have already been fetched, skipping this method..."); goto Continue; } } else { throw e; } } #endregion Continue: ContractsPackageAccessor.Current.QueueWorkItem(() => RecursivelyLookupContractsForMethods(@this)); return; RequeueAndAbort: @this._methodsNeedingContractLookup.Enqueue(methodPair); return; }
/// <summary> /// Associates the given object with the given method contract. /// If the object is already associated with a method contract, that association will be lost as a result of this call. /// </summary> /// <param name="contract">The contract to associate with method.</param> /// <param name="method">An object to associate with the method contract. This can be any kind of object.</param> public void AssociateMethodWithContract(object method, IMethodContract contract) { lock (this.methodContractFor) { this.methodContractFor[method] = contract; } }
/// <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); } }
public static string FormatContracts(IMethodContract methodContracts) { //Did we get proper contracts? if (methodContracts == null) { //Return a message saying we failed to get contracts return "(Failed to properly get contracts)"; } //Do we have any contracts? if (IsEmptyContract(methodContracts)) { //Return a message saying we don't have any contracts return null; } //Initialize our string builder var sb = new StringBuilder(); //Append the 'Contracts' header sb.Append("Contracts: "); sb.Append('\n'); //Append purity if (methodContracts.IsPure) { sb.Append(" "); sb.Append("[Pure]"); sb.Append('\n'); } FormatPrePostThrows(methodContracts, sb); //Can we get our result from the string builder? var result = sb.ToString(); //Trim the new lines from the end result = result.TrimEnd('\n'); result = SmartFormat(result); //Return our result return result; }
/// <summary> /// Constructs a pair from the arguments. /// </summary> public MethodContractAndMethodBody(IMethodContract/*?*/ methodContract, IBlockStatement/*?*/ blockStatement) { this.methodContract = methodContract; this.blockStatement = blockStatement; }
private static bool IsEmptyContract(IMethodContract methodContracts) { Contract.Ensures(Contract.Result<bool>() || methodContracts != null); return methodContracts == null || (methodContracts == ContractDummy.MethodContract) || (!methodContracts.IsPure && methodContracts.Preconditions.Count() < 1 && methodContracts.Postconditions.Count() < 1 && methodContracts.ThrownExceptions.Count() < 1); }
/// <summary> /// Wraps a call to GetMethodContractFor inside of a try-catch statement. /// </summary> public static bool TryGetMethodContract(CodeContractAwareHostEnvironment host, IMethodReference method, out IMethodContract methodContract, DocTracker docTracker) { Contract.Requires(host != null); Contract.Requires(method != null); Contract.Ensures(!Contract.Result<bool>() || Contract.ValueAtReturn(out methodContract) != null); try { methodContract = ContractHelper.GetMethodContractFor(host, method.ResolvedMethod); } catch (NullReferenceException) { docTracker.WriteLine("ERROR: NullReferenceException was thrown in CCI!"); methodContract = null; } //} catch (Exception e) { // docTracker.WriteLine("ERROR: Exception of type '{0}' was thrown in CCI!", e.GetType().Name); // docTracker.WriteLine("\t'{0}'", e.Message); // methodContract = null; //} return methodContract != null; }
private static void FormatPrePostThrows(IMethodContract methodContracts, StringBuilder sb) { Contract.Requires(methodContracts != null); Contract.Requires(sb != null); if (methodContracts.Postconditions != null) { //Append our preconditions foreach (var pre in methodContracts.Preconditions) { if (pre == null) continue; if (pre.OriginalSource == null) continue; sb.Append(" "); sb.Append("requires "); sb.Append(pre.OriginalSource.Replace(Environment.NewLine, IndentString)); sb.Append('\n'); } } if (methodContracts.Postconditions != null) { //Append our postconditions foreach (var post in methodContracts.Postconditions) { if (post == null) continue; if (post.OriginalSource == null) continue; sb.Append(" "); sb.Append("ensures "); sb.Append(post.OriginalSource.Replace(Environment.NewLine, IndentString)); sb.Append('\n'); } } if (methodContracts.ThrownExceptions != null) { //Append our on throw conditions foreach (var onThrow in methodContracts.ThrownExceptions) { if (onThrow == null) continue; if (onThrow.ExceptionType == null) continue; if (onThrow.Postcondition == null) continue; if (onThrow.Postcondition.OriginalSource == null) continue; sb.Append(" "); sb.Append("ensures on throw of "); var onThrowType = TypeHelper.GetTypeName(onThrow.ExceptionType, NameFormattingOptions.OmitContainingType | NameFormattingOptions.OmitContainingNamespace); sb.Append(onThrowType); sb.Append(" that "); sb.Append(onThrow.Postcondition.OriginalSource.Replace(Environment.NewLine, IndentString)); sb.Append('\n'); } } }