Ejemplo n.º 1
0
        public static ReplacementDictionary PrecomputeReplacementNodes(SyntaxDictionary annotationsByNode, Compilation compilation)
        {
            #region CodeContracts
            Contract.Requires(annotationsByNode != null);
            Contract.Requires(compilation != null);
            Contract.Ensures(Contract.Result <ReplacementDictionary>() != null);
            #endregion CodeContracts

            Output.WriteLine("Precomputing the replacement nodes");

            //GetContractRequiresSymbols(comp);
            var newdict = new ReplacementDictionary();
            foreach (var oldkvp in annotationsByNode)
            {
                var oldsubdict = oldkvp.Value;
                var oldfile    = oldkvp.Key;
                var newsubdict = new Dictionary <SyntaxNode, SyntaxNode>();
                if (!oldsubdict.Any())
                {
                    continue;              /* TODO is this right? we have a node with no annotations? */
                }
                SemanticModel = compilation.GetSemanticModel(oldsubdict.First().Key.SyntaxTree);
                Compilation   = compilation;
                foreach (var oldnode in oldsubdict.Keys)
                {
                    switch (oldnode.CSharpKind())
                    {
                    case SyntaxKind.MethodDeclaration:
                    case SyntaxKind.ConstructorDeclaration:
                    case SyntaxKind.SetAccessorDeclaration:
                    case SyntaxKind.GetAccessorDeclaration:
                    case SyntaxKind.AddAccessorDeclaration:    // who knew this was a thing? maybe this will work
                    case SyntaxKind.RemoveAccessorDeclaration: // who knew this was a thing? maybe this will work
                        //var oldmethod = oldnode as BaseMethodDeclarationSyntax;
                        //var newmethod = PrecomputeNewMethod(oldmethod, oldsubdict[oldnode]);
                        //if (oldnode.GetText().ToString().Contains("ObjectInvariant")) { int x; }
                        var newmethod = PrecomputeNewMethod(oldnode, oldsubdict[oldnode]);
                        newsubdict.Add(oldnode, newmethod);
                        continue;

                    case SyntaxKind.FieldDeclaration:
                        continue; // we don't need to do anything to read only fields at this point

                    default:
                        RBLogger.Error("Unhandled SyntaxNode kind {0}", oldnode.CSharpKind());
                        // Debug.Assert(false); // unhandled annotation type
                        continue;
                    }
                }
                newdict.Add(oldfile, newsubdict);
            }
            return(newdict);
        }
Ejemplo n.º 2
0
        public static SyntaxDictionary GetSyntaxNodeToAnnotationDict(Compilation compilation, IEnumerable <BaseAnnotation> annotations)
        {
            #region CodeContracts
            Contract.Requires(compilation != null);
            Contract.Requires(annotations != null);
            Contract.Ensures(Contract.Result <SyntaxDictionary>() != null);
            #endregion CodeContracts

            Output.WriteLine("Creating the SyntaxNode to annotations dictionary");

            var annotations_by_node = new SyntaxDictionary();
            foreach (var st in compilation.SyntaxTrees)
            {
                var fp        = st.FilePath;
                var curr_anns = annotations.Where(x => x.FileName.Equals(fp, StringComparison.OrdinalIgnoreCase));
                var fields    = curr_anns.OfType <ReadonlyField>();
                curr_anns = curr_anns.Except(fields);
                //Dictionary<MethodNameId, List<BaseAnnotation>> curr_anns;
                //if (annotations.TryGetValue(fp, out curr_anns)) // does the syntax tree have any annotations?
                if (curr_anns.Any())
                {
                    annotations_by_node.Add(fp, new Dictionary <SyntaxNode, List <BaseAnnotation> >());
                    var sm     = compilation.GetSemanticModel(st);
                    var mf     = new MethodsFinder(curr_anns, sm);
                    var before = curr_anns.Count();
                    var after  = mf.methods_to_annotate.Count;
                    if (before != after)
                    {
                        Output.WriteWarning("Didn't match all methods for " + fp + " There were " + before + " but now " + after, "ERROR");
                        Output.WriteLine("Next the list of those we failed to match");
                        foreach (var orig in curr_anns.Select(x => x.MethodName))
                        {
                            var matched = false;
                            foreach (var newguy in mf.methods_to_annotate.Keys)
                            {
                                if (newguy is FieldDeclarationSyntax)
                                {
                                    continue;
                                }                                   // this way of finding missing annotations doesn't really work for readonly fields
                                var sym = sm.GetDeclaredSymbol(newguy) as ISymbol;
                                var dci = sym.GetDocumentationCommentId();
                                if (dci.Equals(orig))
                                {
                                    matched = true;
                                }
                            }
                            if (!matched)
                            {
                                Output.WriteLine("Failed to find {0}", orig);
                            }
                        }
                    }
                    else
                    {
                        Output.WriteLine("Matched all methods in {0}", fp);
                    }
                    //before = DictionaryHelpers.CountTotalItems(curr_anns);
                    before = curr_anns.Count();
                    after  = DictionaryHelpers.CountTotalItems(mf.methods_to_annotate);
                    if (before != after)
                    {
                        Output.WriteWarning("Lost some annotations for " + fp + " There were " + before + " but now " + after, "ERROR");
                    }
                    else
                    {
                        Output.WriteLine("Matched all annotations in {0}", fp);
                    }
                    foreach (var key in mf.methods_to_annotate.Keys)
                    {
                        annotations_by_node[fp].Add(key, mf.methods_to_annotate[key]);
                    }
                }
            }
            int total = 0;
            foreach (var dict in annotations_by_node.Values)
            {
                total += DictionaryHelpers.CountTotalItems(dict);
            }

            Output.WriteLine("I started with {0} annotations and I found {1}", annotations.Count().ToString(), total.ToString());
            if (annotations.Count() != total)
            {
                var interfaces = annotations.OfType <ResolvedInterfaceAnnotation>();
                var fields     = annotations.OfType <ReadonlyField>();
                var invariants = annotations.OfType <ResolvedObjectInvariant>();
                var other      = annotations.OfType <Precondition>();
                var found      = new List <BaseAnnotation>();
                foreach (var file in annotations_by_node)
                {
                    foreach (var sugs in file.Value.Values)
                    {
                        found = found.Concat(sugs).ToList();
                    }
                }
                var interfacesFound = found.OfType <ResolvedInterfaceAnnotation>();
                var fieldsFound     = found.OfType <ReadonlyField>();
                var invariantsFound = found.OfType <ResolvedObjectInvariant>();
                var otherFound      = found.OfType <Precondition>();
                RBLogger.Info("Interfaces found {0} of {1}", interfacesFound.Count(), interfaces.Count());
                RBLogger.Info("fields found {0} of {1}", fieldsFound.Count(), fields.Count());
                RBLogger.Info("invariants found {0} of {1}", invariantsFound.Count(), invariants.Count());
                RBLogger.Info("other found {0} of {1}", otherFound.Count(), other.Count());
                var lost = other.Except(otherFound);
                RBLogger.Info("Missing annotations:");
                RBLogger.Indent();
                foreach (var group in lost.GroupBy(x => x.MethodName))
                {
                    RBLogger.Info(group.First().MethodName);
                    RBLogger.Indent();
                    foreach (var ann in group)
                    {
                        RBLogger.Info(ann);
                    }
                    RBLogger.Unindent();
                }
                RBLogger.Unindent();
                //RBLogger.Info("Found annotations {0}", found.Count());
                //RBLogger.Info("Unmatched annotations:");
                //RBLogger.Indent();
                //foreach (var annotation in other)
                //{
                //  RBLogger.Info(annotation.MethodName);
                //  RBLogger.Indent();
                //  RBLogger.Info(annotation);
                //  RBLogger.Unindent();
                //}
                //RBLogger.Unindent();
            }
            return(annotations_by_node);
        }