/// <summary> /// Take all the annotations, select only the interface annotations, create their contract classes (if necessary), /// resolve the contract class name and contract class method names /// </summary> /// <param name="annotations"></param> /// <param name="project"></param> /// <param name="compilation"></param> /// <param name="resolvedannotations">All the annotations with the interface annotation fields completed</param> /// <returns>The compilation with potentially new empty contract classes</returns> internal static Compilation CreateOrFindContractsClasses(IEnumerable <BaseAnnotation> annotations, Project project, Compilation compilation, out IEnumerable <BaseAnnotation> resolvedannotations) { #region CodeContracts Contract.Requires(annotations != null); Contract.Requires(project != null); Contract.Requires(compilation != null); Contract.Ensures(Contract.ValueAtReturn <IEnumerable <BaseAnnotation> >(out resolvedannotations) != null); Contract.Ensures(Contract.Result <Compilation>() != null); #endregion CodeContracts Output.WriteLine("Gathering (and creating) contract classes for interfaces and abstract classes"); var resolvedList = annotations.Where(x => !(x is UnresolvedInterfaceAnnotation)).ToList(); foreach (var interfaceGroup in annotations.OfType <UnresolvedInterfaceAnnotation>().GroupBy(x => x.InterfaceName)) { var first = interfaceGroup.First(); var interfaceSymbol = InterfaceAnnotationHelpers.GetInterfaceSymbol(project, compilation, first.InterfaceName, first.InterfaceShortName); string contractName, fileName, interfaceName; interfaceName = first.InterfaceName; if (!InterfaceAnnotationHelpers.TryFindContractsClass(compilation, interfaceSymbol, out contractName, out fileName)) { //fileName = first.FileName; fileName = interfaceSymbol.Locations[0].SourceTree.FilePath; // hopefully index 0 is where the declaration is? var interfaceMethod = first.InterfaceMethod; contractName = GetCreatedContractClassName(interfaceName, interfaceMethod); compilation = InterfaceAnnotationHelpers.MakeContractsClassFor(project, compilation, interfaceName, fileName, first.ParametersString); compilation = InterfaceAnnotationHelpers.ImplementContractsClass(project, compilation, fileName, interfaceName, contractName); var syntaxTree = compilation.SyntaxTrees.First(x => x.FilePath.Equals(fileName, StringComparison.OrdinalIgnoreCase)); var newSyntaxTree = Replacer.AddUsingsContracts(syntaxTree); compilation = compilation.ReplaceSyntaxTree(syntaxTree, SyntaxFactory.SyntaxTree(newSyntaxTree.GetRoot(), null, fileName)); compilation = InterfaceAnnotationHelpers.AddContractsClassAttributeToInterface(project, compilation, fileName, interfaceName, first.ParametersString); } foreach (var methodgroup in interfaceGroup.GroupBy(annotation => annotation.InterfaceMethod)) { first = methodgroup.First(); var methodName = InterfaceAnnotationHelpers.GetMethodName(first.InterfaceName, first.InterfaceMethod, contractName); resolvedList.AddRange(methodgroup.Select(x => new ResolvedInterfaceAnnotation(fileName, methodName, x.Annotation, x.Squiggle, x.Kind, x))); } //var methodName = InterfaceAnnotationHelpers.GetMethodName(first.InterfaceName, first.InterfaceMethod, contractName); //resolvedList.AddRange(interfaceGroup.Select(x => new ResolvedInterfaceAnnotation(fileName, methodName, x.Annotation, x.Squiggle, x.Kind, x))); //return compilation; //compilation = first.MakeOrFindContractsClass(project, compilation); //foreach (var intf in interfaceGroup) //{ // //intf.CopyFileNameAndContractsClass(first); // //} //foreach (var grp in interfaceGroup.GroupBy(x => x.MethodName)) //{ // first = grp.First(); // first.FindMethodName(compilation); // foreach (var intf in grp) // { // intf.CopyMethodName(first); // } //} } resolvedannotations = resolvedList.AsReadOnly(); return(compilation); }