예제 #1
0
        private MetadataTracker(IWpfTextView textView, double defaultFontSize = 10.0d)
        {
            this.defaultFontSize = defaultFontSize;
            this.textView        = textView;

            bool isMetadataFile = false;

            fileName = textView.TextBuffer.GetFileName();
            if (fileName.Contains('$'))//TODO: This is a very weak check, we need a better way to check this!
            {
                isMetadataFile = true;
            }

            if (!isMetadataFile)
            {
                return;
            }

            adornmentManager = AdornmentManager.GetOrCreateAdornmentManager(textView, "MetadataAdornments");

            //timer = new Timer();
            //timer.BeginInit();
            //timer.AutoReset = false;
            //timer.Elapsed += OnLayoutSettled;
            //timer.Interval = 2000;
            //timer.EndInit();
            //timer.Start();

            textView.LayoutChanged += OnLayoutChanged;

            var foo = new ContractAdornment(11, textView.TextSnapshot.CreateTrackingSpan(0, 10, SpanTrackingMode.EdgeExclusive), defaultFontSize);
        }
예제 #2
0
        void OnLayoutSettled(object sender, ElapsedEventArgs e)
        {
            var    splitFileName   = fileName.Split('$');//TODO: This may have holes, check for corner cases!
            string assemblyName    = splitFileName[1];
            string assemblyVersion = splitFileName[2];
            string typeName        = Path.GetFileNameWithoutExtension(fileName);//.Split('.').Last();

            ContractsProviderHost host     = null;
            string codeContractsInstallDir = Environment.GetEnvironmentVariable("CodeContractsInstallDir");

            if (!String.IsNullOrEmpty(codeContractsInstallDir))
            {
                string contractsDir = Path.Combine(codeContractsInstallDir, @"contracts\3.5");
                host = new ContractsProviderHost(new string[] { contractsDir });
            }

            if (host == null)
            {
                return;//TODO: Throw error?
            }
            //var assemlyIdentity = new AssemblyIdentity(host.NameTable.GetNameFor(assemblyName), null, new Version(assemblyVersion), null, null);
            //var assembly = host.FindAssembly(assemlyIdentity);
            var assembly = host.LoadUnitFrom(Path.Combine(codeContractsInstallDir, @"Contracts\v3.5", Path.GetFileNameWithoutExtension(assemblyName) + ".contracts.dll"));

            if (assembly == null || assembly == Dummy.Assembly)
            {
                return;//TODO: Throw error?
            }
            var contractsProvider = host.GetContractProvider(assembly.UnitIdentity);

            if (contractsProvider == null)
            {
                return; //TODO Throw error? Will it ever be null?
            }
            var type = UnitHelper.FindType(host.NameTable, assembly, typeName);

            var methodsToContracts = new Dictionary <string, IMethodContract>(type.Methods.Count());
            var gettersToContracts = new Dictionary <string, IMethodContract>();
            var settersToContracts = new Dictionary <string, IMethodContract>();

            System.Xml.XmlDocument doc;
            foreach (var method in type.Methods)
            {
                var methodContract = contractsProvider.GetMethodContractFor(method);
                if (methodContract != null)
                {
                    if (IsGetter(method))
                    {
                        var getterSignature = MemberHelper.GetMemberSignature(method,
                                                                              NameFormattingOptions.OmitContainingNamespace |
                                                                              NameFormattingOptions.ReturnType |
                                                                              NameFormattingOptions.TypeParameters |
                                                                              NameFormattingOptions.UseTypeKeywords |
                                                                              NameFormattingOptions.OmitContainingType |
                                                                              NameFormattingOptions.Visibility
                                                                              );
                        getterSignature = getterSignature.Substring(0, getterSignature.LastIndexOf('.'));
                        gettersToContracts.Add(getterSignature, methodContract);
                    }
                    else if (IsSetter(method))
                    {
                        var setterSignature = MemberHelper.GetMemberSignature(method,
                                                                              NameFormattingOptions.OmitContainingNamespace |
                                                                              NameFormattingOptions.ReturnType |
                                                                              NameFormattingOptions.TypeParameters |
                                                                              NameFormattingOptions.UseTypeKeywords |
                                                                              NameFormattingOptions.OmitContainingType |
                                                                              NameFormattingOptions.Visibility
                                                                              );
                        setterSignature = setterSignature.Substring(0, setterSignature.LastIndexOf('.'));
                        settersToContracts.Add(setterSignature, methodContract);
                    }
                    else
                    {
                        var methodSignature = MemberHelper.GetMemberSignature(method,
                                                                              NameFormattingOptions.OmitContainingNamespace |
                                                                              NameFormattingOptions.ReturnType |
                                                                              NameFormattingOptions.ParameterName |
                                                                              NameFormattingOptions.ParameterModifiers |
                                                                              NameFormattingOptions.TypeParameters |
                                                                              NameFormattingOptions.UseTypeKeywords |
                                                                              NameFormattingOptions.OmitContainingType |
                                                                              NameFormattingOptions.Modifiers |
                                                                              NameFormattingOptions.Signature |
                                                                              NameFormattingOptions.Visibility
                                                                              );
                        methodsToContracts.Add(methodSignature, methodContract);
                    }
                }
            }



            foreach (var line in textView.TextSnapshot.Lines)
            {
                var lineText = line.GetText();

                if (lineText.Contains("//"))
                {
                    continue;                                                                                                         //Skip comments
                }
                if (lineText.Contains('{') && (lineText.Contains(" get; ") || lineText.Contains(" set; ")) && lineText.Contains('}')) // If property
                {
                    int  endOfSig   = lineText.IndexOf('{') - 1;
                    int  startOfSig = endOfSig - 1;
                    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 propertySignature = lineText.Substring(startOfSig, endOfSig - startOfSig);

                    IMethodContract getterContract;
                    IMethodContract setterContract = null;
                    if (gettersToContracts.TryGetValue(propertySignature, out getterContract) || settersToContracts.TryGetValue(propertySignature, out setterContract))
                    {
                        var tag = propertySignature.GetHashCode();
                        int firstNonWhitespace = 0;
                        for (int i = 0; i < lineText.Count(); i++)
                        {
                            char c = lineText[i];
                            if (c != ' ')
                            {
                                firstNonWhitespace = i;
                                break;
                            }
                        }
                        var span      = textView.TextSnapshot.CreateTrackingSpan(line.Start + firstNonWhitespace, propertySignature.Length, SpanTrackingMode.EdgeExclusive);
                        var adornment = new ContractAdornment(tag, span, defaultFontSize, false, null, getterContract, setterContract, "Contracts from " + typeName + ".");
                        adornmentManager.AddAdornment(adornment, tag);//TODO: Inherit from info is wrong.
                    }
                }
                else if (lineText.Contains('(') && lineText.Contains('(') && lineText.Contains(';')) //If method
                {
                    int  endOfSig   = lineText.LastIndexOf(')') + 1;
                    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(startOfSig, endOfSig - startOfSig);

                    IMethodContract methodContract;
                    if (methodsToContracts.TryGetValue(methodSignature, out methodContract))
                    {
                        var tag = methodSignature.GetHashCode();
                        int firstNonWhitespace = 0;
                        for (int i = 0; i < lineText.Count(); i++)
                        {
                            char c = lineText[i];
                            if (c != ' ')
                            {
                                firstNonWhitespace = i;
                                break;
                            }
                        }
                        var span      = textView.TextSnapshot.CreateTrackingSpan(line.Start + firstNonWhitespace, methodSignature.Length, SpanTrackingMode.EdgeExclusive);
                        var adornment = new ContractAdornment(tag, span, defaultFontSize, false, null, methodContract, "Contracts from " + typeName + ".");
                        adornmentManager.AddAdornment(adornment, tag);//TODO: Inherit from info is wrong.
                    }
                }
            }

            if (true)
            {
            }
        }