예제 #1
0
        /// <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);
        }