Exemplo n.º 1
0
        static void RevaluateMethodInheritanceAdornments(InheritanceTracker @this)
        {
            Contract.Requires(@this != null);

            var workingSnapshot = @this._textViewTracker.TextView.TextSnapshot; //Save the current snapshot so it doesn't change while you work, we assume that the snapshot is the same as the source file.

            //Check if model is ready
            var parseTree = @this._textViewTracker.LatestSourceFile == null ? null : @this._textViewTracker.LatestSourceFile.GetParseTree();

            if (parseTree == null || !parseTree.IsModelReady())
            {
                @this._textViewTracker.IsLatestSourceFileStale = true;
                Utilities.Delay(() => ContractsPackageAccessor.Current.AskForNewVSModel(), DelayOnVSModelFailedBeforeTryingAgain);
                return;
            }

            //Collect all the methods in this text view
            var methodCollector = new MethodCollector(workingSnapshot);

            methodCollector.Visit(parseTree.RootNode);
            var methods = methodCollector.GetMethods();

            //Calculate which methods are new
            var newKeys = new List <object>(methods.Keys.Where((k) => !@this._methodKeys.Contains(k)));

            ContractsPackageAccessor.Current.Logger.WriteToLog(String.Format("Found {0} new methods.", newKeys.Count));

            //Update our method keys
            @this._methodKeys.Clear();
            @this._methodKeys.AddAll(methods.Keys);

            ContractsPackageAccessor.Current.QueueWorkItem(() => {
                if (@this._textViewTracker.TextView.IsClosed)
                {
                    return;
                }
                var adornmentKeys = new List <object>(@this._adornmentManager.Adornments.Keys);
                foreach (var key in adornmentKeys)
                {
                    var keyAsString = key as string;
                    if (keyAsString == null)
                    {
                        ContractsPackageAccessor.Current.Logger.WriteToLog("Unexpected: A key in the AdornmentManager wasn't a string! key: " + key.ToString());
                        continue;
                    }
                    if (!@this._methodKeys.Contains(key) && keyAsString.EndsWith(MethodCollector.MethodTagSuffix))
                    {
                        @this._adornmentManager.RemoveAdornment(key);
                        ContractsPackageAccessor.Current.Logger.WriteToLog("Removing obsolete method adornment with tag: " + keyAsString);
                    }
                }
            }, () => @this._textViewTracker.TextView.IsClosed || @this._textViewTracker.TextView.HasAggregateFocus);

            //Create placeholder adornments for our new methods and queue them for contract lookup
            ContractsPackageAccessor.Current.QueueWorkItem(() => {
                foreach (var key in newKeys)
                {
                    MethodDeclarationNode method;
                    if (methods.TryGetValue(key, out method))
                    {
                        ContractsPackageAccessor.Current.Logger.WriteToLog("Creating placeholder adornment and enqueueing for future contract lookup for: " + key.ToString());
                        #region Create placeholder adornment
                        //We add the placeholder adornment here because our workingSnapshot corresponds most closely to the syntactic model's text
                        var snapshotSpan = new SnapshotSpan(method.GetSpan().Convert(workingSnapshot).Start, 1);
                        var trackingSpan = workingSnapshot.CreateTrackingSpan(snapshotSpan.Span, SpanTrackingMode.EdgeExclusive);
                        var ops          = AdornmentOptionsHelper.GetAdornmentOptions(ContractsPackageAccessor.Current.VSOptionsPage);
                        @this._adornmentManager.AddAdornment(new InheritanceContractAdornment(trackingSpan, @this._textViewTracker.VSTextProperties, ContractsPackageAccessor.Current.Logger, @this._adornmentManager.QueueRefreshLineTransformer, ops), key);
                        #endregion
                        @this._methodsNeedingContractLookup.Enqueue(new KeyValuePair <object, MethodDeclarationNode>(key, method));
                    }
                }
            });

            //Most likely we've changed something (and this is a pretty cheap call), so let's ask for a refresh
            Utilities.Delay(() => ContractsPackageAccessor.Current.QueueWorkItem(@this._adornmentManager.QueueRefreshLineTransformer), DelayAfterMembersRevalutation);

            //Ask for the new VS model so we can look up contracts
            Utilities.Delay(() => ContractsPackageAccessor.Current.QueueWorkItem(ContractsPackageAccessor.Current.AskForNewVSModel), DelayAfterMembersRevalutation);
        }
    static void RevaluateMethodInheritanceAdornments(InheritanceTracker @this) {
      Contract.Requires(@this != null);

      var workingSnapshot = @this._textViewTracker.TextView.TextSnapshot;  //Save the current snapshot so it doesn't change while you work, we assume that the snapshot is the same as the source file.

      //Check if model is ready
      var parseTree = @this._textViewTracker.LatestSourceFile == null ? null : @this._textViewTracker.LatestSourceFile.GetParseTree();
      if (parseTree == null || !parseTree.IsModelReady()) {
        @this._textViewTracker.IsLatestSourceFileStale = true;
        Utilities.Delay(() => ContractsPackageAccessor.Current.AskForNewVSModel(), DelayOnVSModelFailedBeforeTryingAgain);
        return;
      }

      //Collect all the methods in this text view
      var methodCollector = new MethodCollector(workingSnapshot);
      methodCollector.Visit(parseTree.RootNode);
      var methods = methodCollector.GetMethods();

      //Calculate which methods are new
      var newKeys = new List<object>(methods.Keys.Where((k) => !@this._methodKeys.Contains(k)));
      ContractsPackageAccessor.Current.Logger.WriteToLog(String.Format("Found {0} new methods.", newKeys.Count));

      //Update our method keys
      @this._methodKeys.Clear();
      @this._methodKeys.AddAll(methods.Keys);

      ContractsPackageAccessor.Current.QueueWorkItem(() => {
        if (@this._textViewTracker.TextView.IsClosed)
          return;
        var adornmentKeys = new List<object>(@this._adornmentManager.Adornments.Keys);
        foreach (var key in adornmentKeys) {
          var keyAsString = key as string;
          if (keyAsString == null) {
            ContractsPackageAccessor.Current.Logger.WriteToLog("Unexpected: A key in the AdornmentManager wasn't a string! key: " + key.ToString());
            continue;
          }
          if (!@this._methodKeys.Contains(key) && keyAsString.EndsWith(MethodCollector.MethodTagSuffix)) {
            @this._adornmentManager.RemoveAdornment(key);
            ContractsPackageAccessor.Current.Logger.WriteToLog("Removing obsolete method adornment with tag: " + keyAsString);
          }
        }
      }, () => @this._textViewTracker.TextView.IsClosed || @this._textViewTracker.TextView.HasAggregateFocus);

      //Create placeholder adornments for our new methods and queue them for contract lookup
      ContractsPackageAccessor.Current.QueueWorkItem(() => {
        foreach (var key in newKeys) {
          MethodDeclarationNode method;
          if (methods.TryGetValue(key, out method)) {
            ContractsPackageAccessor.Current.Logger.WriteToLog("Creating placeholder adornment and enqueueing for future contract lookup for: " + key.ToString());
            #region Create placeholder adornment
            //We add the placeholder adornment here because our workingSnapshot corresponds most closely to the syntactic model's text
            var snapshotSpan = new SnapshotSpan(method.GetSpan().Convert(workingSnapshot).Start, 1);
            var trackingSpan = workingSnapshot.CreateTrackingSpan(snapshotSpan.Span, SpanTrackingMode.EdgeExclusive);
            var ops = AdornmentOptionsHelper.GetAdornmentOptions(ContractsPackageAccessor.Current.VSOptionsPage);
            @this._adornmentManager.AddAdornment(new InheritanceContractAdornment(trackingSpan, @this._textViewTracker.VSTextProperties, ContractsPackageAccessor.Current.Logger, @this._adornmentManager.QueueRefreshLineTransformer, ops), key);
            #endregion
            @this._methodsNeedingContractLookup.Enqueue(new KeyValuePair<object, MethodDeclarationNode>(key, method));
          }
        }
      });

      //Most likely we've changed something (and this is a pretty cheap call), so let's ask for a refresh
      Utilities.Delay(() => ContractsPackageAccessor.Current.QueueWorkItem(@this._adornmentManager.QueueRefreshLineTransformer), DelayAfterMembersRevalutation);

      //Ask for the new VS model so we can look up contracts
      Utilities.Delay(() => ContractsPackageAccessor.Current.QueueWorkItem(ContractsPackageAccessor.Current.AskForNewVSModel), DelayAfterMembersRevalutation);
    }