示例#1
0
        public IAssemblyReference Map(IAssemblySymbol assembly)
        {
            Contract.Requires(assembly != null);
            Contract.Ensures(Contract.Result <IAssemblyReference>() != null);

            IAssemblyReference cciAssembly = null;

            if (!assemblySymbolCache.TryGetValue(assembly, out cciAssembly))
            {
                var an = assembly.Identity;
                IEnumerable <byte> pkt = an.PublicKeyToken.AsEnumerable();
                if (pkt == null)
                {
                    pkt = new byte[0];
                }
                var identity = new Microsoft.Cci.AssemblyIdentity(
                    this.nameTable.GetNameFor(an.Name),
                    an.CultureName == null ? "" : an.CultureName, // REVIEW: This can't be right
                    an.Version,
                    pkt,
                    "unknown://location" // BUGBUG an.Location == null ? "unknown://location" : an.Location
                    );
                cciAssembly = new Microsoft.Cci.Immutable.AssemblyReference(this.host, identity);
                assemblySymbolCache[assembly] = cciAssembly;
            }
            Contract.Assume(cciAssembly != null);
            return(cciAssembly);
        }
    public IAssemblyReference Map(R.IAssemblySymbol assembly) {
      Contract.Requires(assembly != null);
      Contract.Ensures(Contract.Result<IAssemblyReference>() != null);

      IAssemblyReference cciAssembly = null;
      if (!assemblySymbolCache.TryGetValue(assembly, out cciAssembly)) {
        var an = assembly.Identity;
        IEnumerable<byte> pkt = an.PublicKeyToken.AsEnumerable();
        if (pkt == null)
          pkt = new byte[0];
        var identity = new Microsoft.Cci.AssemblyIdentity(
          this.nameTable.GetNameFor(an.Name),
          an.CultureName == null ? "" : an.CultureName, // REVIEW: This can't be right
          an.Version,
          pkt,
          an.Location == null ? "unknown://location" : an.Location
          );
        cciAssembly = new Microsoft.Cci.Immutable.AssemblyReference(this.host, identity);
        assemblySymbolCache[assembly] = cciAssembly;
      }
      Contract.Assume(cciAssembly != null);
      return cciAssembly;
    }
示例#3
0
        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 TryGetAssemblyReference(IAssemblySymbol semanticAssembly, out IAssemblyReference cciAssembly) {
      Contract.Ensures(!Contract.Result<bool>() || Contract.ValueAtReturn(out cciAssembly) != null);

      cciAssembly = null;

      #region Check input
      if (semanticAssembly == null) {
        return false;
      }
      #endregion
      #region Check cache
      if (ContractsPackageAccessor.Current.VSOptionsPage.Caching)
        if (_semanticAssemblysToCCIAssemblys.TryGetValue(semanticAssembly, out cciAssembly))
          return cciAssembly != Dummy.AssemblyReference && cciAssembly != null;
      #endregion
      // distinguish between the AssemblyName and the ProjectName

      var semanticAssemblyFileName = (semanticAssembly.Name == null) ? null : semanticAssembly.Name;
      if (string.IsNullOrWhiteSpace(semanticAssemblyFileName)) return false;
      var semanticAssemblyName = Path.GetFileName(semanticAssemblyFileName);
      if (semanticAssemblyName.EndsWith(".dll") || semanticAssemblyName.EndsWith(".exe"))
        semanticAssemblyName = semanticAssemblyName.Remove(semanticAssemblyName.Length - 4, 4);

      #region Try to get assembly from previously loaded assemblies from host
      foreach (var unit in Host.LoadedUnits) {
        if (unit == null) continue;
        if (unit is Dummy) continue;
        if (unit.Name.Value == semanticAssemblyName) {
          cciAssembly = (IAssemblyReference)unit;
          if (cciAssembly.ResolvedAssembly.Location == semanticAssemblyFileName)
          {
            goto ReturnTrue;
          }
        }
      }
      #endregion
      #region Check if assembly is the same as the current project's output assembly
      if (_projectTracker.AssemblyIdentity != null && _projectTracker.AssemblyIdentity.Name != null) {
        if (semanticAssemblyName.Equals(_projectTracker.AssemblyIdentity.Name.Value, StringComparison.OrdinalIgnoreCase) || semanticAssemblyName.Equals(_projectTracker.ProjectName, StringComparison.OrdinalIgnoreCase)) {
          cciAssembly = new Microsoft.Cci.Immutable.AssemblyReference(this.Host, _projectTracker.AssemblyIdentity);
          Host.AddLibPath(Path.Combine(Path.GetDirectoryName(semanticAssemblyFileName), "CodeContracts"));
          Host.AddLibPath(Path.Combine(Path.GetDirectoryName(semanticAssemblyFileName), @"..\Debug\CodeContracts"));
          goto ReturnTrue;
        }
      } else
        ContractsPackageAccessor.Current.Logger.WriteToLog("Assembly identity for the project: " + _projectTracker.ProjectName + " was null.");
      #endregion
      #region Build assembly reference
      if (semanticAssembly.Name == null || string.IsNullOrWhiteSpace(semanticAssembly.Name)) goto ReturnFalseNoOutput; // because we have no name.
      var projectName = Path.GetFileName(semanticAssembly.Name);
      if (projectName.EndsWith(".dll") || projectName.EndsWith(".exe"))
          projectName = projectName.Remove(projectName.Length - 4, 4);
      var references = _projectTracker.References;
      VSLangProj.Reference reference = null;
      for (int i = 1, refcount = references == null ? 0 : references.Count; i <= refcount; i++)
      {
        var tempRef = references.Item(i);
        if (tempRef == null) continue;
        string refName = tempRef.Name;//Path.GetFileNameWithoutExtension(tempRef.Name);
        if (refName == null) continue;
        if (refName.Equals(projectName, StringComparison.OrdinalIgnoreCase)) {
          reference = tempRef;
          break;
        }
      }
      if (reference != null) {
        IName iName = Host.NameTable.GetNameFor(Path.GetFileNameWithoutExtension(reference.Path));
        string culture = reference.Culture ?? "en";
        Version version = new Version(reference.MajorVersion, reference.MinorVersion, reference.BuildNumber, reference.RevisionNumber);
        string location = reference.Path;
        if (!string.IsNullOrEmpty(location))
        {
          Host.AddLibPath(Path.Combine(location.Substring(0, location.Length - Path.GetFileName(location).Length), "CodeContracts"));
          var assemblyIdentity = new AssemblyIdentity(iName, culture, version, Enumerable<byte>.Empty, location);
          cciAssembly = new Microsoft.Cci.Immutable.AssemblyReference(this.Host, assemblyIdentity);
          goto ReturnTrue;
        }
      }
      goto ReturnFalse;
      #endregion
      #region ReturnTrue:
    ReturnTrue:
      if (ContractsPackageAccessor.Current.VSOptionsPage.Caching)
        _semanticAssemblysToCCIAssemblys[semanticAssembly] = cciAssembly;
      EnsureAssemblyIsLoaded(semanticAssembly, ref cciAssembly);
      return true;
      #endregion
      #region ReturnFalse:
    ReturnFalse:
      ContractsPackageAccessor.Current.Logger.WriteToLog("Failed to build assembly reference for: " + semanticAssembly.Name);
    ReturnFalseNoOutput:
      if (ContractsPackageAccessor.Current.VSOptionsPage.Caching)
        _semanticAssemblysToCCIAssemblys[semanticAssembly] = Dummy.AssemblyReference;
      return false;
      #endregion
    }
示例#5
0
        public bool TryGetAssemblyReference(CSharpAssembly semanticAssembly, out IAssemblyReference cciAssembly)
        {
            Contract.Ensures(!Contract.Result <bool>() || Contract.ValueAtReturn(out cciAssembly) != null);

            cciAssembly = null;

            #region Check input
            if (semanticAssembly == null)
            {
                return(false);
            }
            #endregion
            #region Check cache
            if (ContractsPackageAccessor.Current.VSOptionsPage.Caching)
            {
                if (_semanticAssemblysToCCIAssemblys.TryGetValue(semanticAssembly, out cciAssembly))
                {
                    return(cciAssembly != Dummy.AssemblyReference && cciAssembly != null);
                }
            }
            #endregion
            // distinguish between the AssemblyName and the ProjectName

            var semanticAssemblyFileName = semanticAssembly.BinaryFileName.Value ?? ((semanticAssembly.Name == null) ? null : semanticAssembly.Name.Text);
            if (string.IsNullOrWhiteSpace(semanticAssemblyFileName))
            {
                return(false);
            }
            var semanticAssemblyName = Path.GetFileName(semanticAssemblyFileName);
            if (semanticAssemblyName.EndsWith(".dll") || semanticAssemblyName.EndsWith(".exe"))
            {
                semanticAssemblyName = semanticAssemblyName.Remove(semanticAssemblyName.Length - 4, 4);
            }

            #region Try to get assembly from previously loaded assemblies from host
            foreach (var unit in Host.LoadedUnits)
            {
                if (unit == null)
                {
                    continue;
                }
                if (unit is Dummy)
                {
                    continue;
                }
                if (unit.Name.Value == semanticAssemblyName)
                {
                    cciAssembly = (IAssemblyReference)unit;
                    if (cciAssembly.ResolvedAssembly.Location == semanticAssemblyFileName)
                    {
                        goto ReturnTrue;
                    }
                }
            }
            #endregion
            #region Check if assembly is the same as the current project's output assembly
            if (_projectTracker.AssemblyIdentity != null && _projectTracker.AssemblyIdentity.Name != null)
            {
                if (semanticAssemblyName.Equals(_projectTracker.AssemblyIdentity.Name.Value, StringComparison.OrdinalIgnoreCase) || semanticAssemblyName.Equals(_projectTracker.ProjectName, StringComparison.OrdinalIgnoreCase))
                {
                    cciAssembly = new Microsoft.Cci.Immutable.AssemblyReference(this.Host, _projectTracker.AssemblyIdentity);
                    Host.AddLibPath(Path.Combine(Path.GetDirectoryName(semanticAssemblyFileName), "CodeContracts"));
                    Host.AddLibPath(Path.Combine(Path.GetDirectoryName(semanticAssemblyFileName), @"..\Debug\CodeContracts"));
                    goto ReturnTrue;
                }
            }
            else
            {
                ContractsPackageAccessor.Current.Logger.WriteToLog("Assembly identity for the project: " + _projectTracker.ProjectName + " was null.");
            }
            #endregion
            #region Build assembly reference
            if (semanticAssembly.Name == null || string.IsNullOrWhiteSpace(semanticAssembly.Name.Text))
            {
                goto ReturnFalseNoOutput;                                                                                   // because we have no name.
            }
            var projectName = Path.GetFileName(semanticAssembly.Name.Text);
            if (projectName.EndsWith(".dll") || projectName.EndsWith(".exe"))
            {
                projectName = projectName.Remove(projectName.Length - 4, 4);
            }
            var references = _projectTracker.References;
            VSLangProj.Reference reference = null;
            for (int i = 1, refcount = references == null ? 0 : references.Count; i <= refcount; i++)
            {
                var tempRef = references.Item(i);
                if (tempRef == null)
                {
                    continue;
                }
                string refName = tempRef.Name;//Path.GetFileNameWithoutExtension(tempRef.Name);
                if (refName == null)
                {
                    continue;
                }
                if (refName.Equals(projectName, StringComparison.OrdinalIgnoreCase))
                {
                    reference = tempRef;
                    break;
                }
            }
            if (reference != null)
            {
                IName   iName    = Host.NameTable.GetNameFor(Path.GetFileNameWithoutExtension(reference.Path));
                string  culture  = reference.Culture ?? "en";
                Version version  = new Version(reference.MajorVersion, reference.MinorVersion, reference.BuildNumber, reference.RevisionNumber);
                string  location = reference.Path;
                if (!string.IsNullOrEmpty(location))
                {
                    Host.AddLibPath(Path.Combine(location.Substring(0, location.Length - Path.GetFileName(location).Length), "CodeContracts"));
                    var assemblyIdentity = new AssemblyIdentity(iName, culture, version, Enumerable <byte> .Empty, location);
                    cciAssembly = new Microsoft.Cci.Immutable.AssemblyReference(this.Host, assemblyIdentity);
                    goto ReturnTrue;
                }
            }
            goto ReturnFalse;
            #endregion
            #region ReturnTrue:
ReturnTrue:
            if (ContractsPackageAccessor.Current.VSOptionsPage.Caching)
            {
                _semanticAssemblysToCCIAssemblys[semanticAssembly] = cciAssembly;
            }
            EnsureAssemblyIsLoaded(semanticAssembly, ref cciAssembly);
            return(true);

            #endregion
            #region ReturnFalse:
ReturnFalse:
            ContractsPackageAccessor.Current.Logger.WriteToLog("Failed to build assembly reference for: " + semanticAssembly.Name.Text);
ReturnFalseNoOutput:
            if (ContractsPackageAccessor.Current.VSOptionsPage.Caching)
            {
                _semanticAssemblysToCCIAssemblys[semanticAssembly] = Dummy.AssemblyReference;
            }
            return(false);

            #endregion
        }
    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
    }