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

            #region Dequeue
            if (@this._propertiesNeedingContractLookup.Count < 1)
            {
                return;
            }
            var propertyPair = @this._propertiesNeedingContractLookup.Dequeue();
            var property     = propertyPair.Value;
            var tagTuple     = propertyPair.Key;
            #endregion
            try {
                var comp = @this._textViewTracker.LatestCompilation;
                if (comp == null)
                {
                    ContractsPackageAccessor.Current.Logger.WriteToLog("No LatestCompilation, waiting for a new semantic model.");
                    @this._textViewTracker.IsLatestCompilationStale = true;
                    Utilities.Delay(() => ContractsPackageAccessor.Current.AskForNewVSModel(), DelayOnVSModelFailedBeforeTryingAgain);
                    @this.semanticModelsFetchedCounter++;
                    goto RequeueAndAbort;
                }
                #region Get semantic property from syntactic property
                CSharpMember semanticProperty = null;
                semanticProperty = comp.GetMemberForPropertyDeclaration(property);
                if (semanticProperty == null)
                {
                    if (@this.trackingNumberOfFetchedSemanticModels && @this.semanticModelsFetchedCounter <= 3)
                    {
                        ContractsPackageAccessor.Current.Logger.WriteToLog("Failed to get semantic property from syntactic property, waiting for a new semantic model.");
                        @this._textViewTracker.IsLatestCompilationStale = true;
                        Utilities.Delay(() => ContractsPackageAccessor.Current.AskForNewVSModel(), DelayOnVSModelFailedBeforeTryingAgain);
                        @this.semanticModelsFetchedCounter++;
                        goto RequeueAndAbort;
                    }
                    else
                    {
                        ContractsPackageAccessor.Current.Logger.WriteToLog("Failed to get semantic property from syntactic property. Too many semantic models have already been fetched, skipping this property...");
                        goto Continue;
                    }
                }
                #endregion
                #region Try get the property that this property is inherited from
                CSharpMember inheritedFromProperty;
                if (!TryGetIheritedFromMember(semanticProperty, property.Parent as TypeDeclarationNode, out inheritedFromProperty))
                {
                    goto Continue;
                }
                #endregion
                #region Uninstantiated property
                semanticProperty = semanticProperty.Uninstantiate();
                #endregion
                #region Get our tool tip
                var toolTip = "";
                if (!semanticProperty.IsAbstract && !semanticProperty.ContainingType.IsInterface)
                {
                    toolTip = String.Format("Contracts inherited from {0}.", inheritedFromProperty.ContainingType.Name.Text);
                }
                #endregion
                #region Try get accessor contracts and update adornment
                IMethodReference getterReference = null;
                IMethodReference setterReference = null;
                if (((ContractsProvider)@this._textViewTracker.ProjectTracker.ContractsProvider).TryGetPropertyAccessorReferences(inheritedFromProperty, out getterReference, out setterReference))
                {
                    if (tagTuple.Item1 != null && getterReference != null)
                    {
                        IMethodContract getterContracts;
                        if (((ContractsProvider)@this._textViewTracker.ProjectTracker.ContractsProvider).TryGetMethodContract(getterReference, out getterContracts))
                        {
                            var possibleAdornment = @this._adornmentManager.GetAdornment(tagTuple.Item1);
                            if (possibleAdornment != null)
                            {
                                var adornment = possibleAdornment as ContractAdornment;
                                if (adornment != null)
                                {
                                    adornment.SetContracts(getterContracts, toolTip);
                                }
                                else
                                {
                                    ContractsPackageAccessor.Current.Logger.WriteToLog("Placeholder adornment isn't a ContractAdornment (not good!), skipping getter...");
                                }
                            }
                            else
                            {
                                ContractsPackageAccessor.Current.Logger.WriteToLog("Placeholder adornment not found, skipping getter...");
                            }
                        }
                    }
                    if (tagTuple.Item2 != null && setterReference != null)
                    {
                        IMethodContract setterContracts;
                        if (((ContractsProvider)@this._textViewTracker.ProjectTracker.ContractsProvider).TryGetMethodContract(setterReference, out setterContracts))
                        {
                            var possibleAdornment = @this._adornmentManager.GetAdornment(tagTuple.Item2);
                            if (possibleAdornment != null)
                            {
                                var adornment = possibleAdornment as ContractAdornment;
                                if (adornment != null)
                                {
                                    adornment.SetContracts(setterContracts, toolTip);
                                }
                                else
                                {
                                    ContractsPackageAccessor.Current.Logger.WriteToLog("Placeholder adornment isn't a ContractAdornment (not good!), skipping setter...");
                                }
                            }
                            else
                            {
                                ContractsPackageAccessor.Current.Logger.WriteToLog("Placeholder adornment not found, skipping setter...");
                            }
                        }
                    }
                }
                else
                {
                    ContractsPackageAccessor.Current.Logger.WriteToLog("Failed to get CCI reference for: " + inheritedFromProperty.Name.Text);
                }
                #endregion
            }
            #region Exception handeling
            catch (IllFormedSemanticModelException e) {
                if (@this.trackingNumberOfFetchedSemanticModels && @this.semanticModelsFetchedCounter <= 2)
                {
                    ContractsPackageAccessor.Current.Logger.WriteToLog("Error: An 'IllFormedSemanticModelException' occured: '" + e.Message + "' Asking for a new semantic model...");
                    @this._textViewTracker.IsLatestCompilationStale = true;
                    ContractsPackageAccessor.Current.AskForNewVSModel();
                    @this.semanticModelsFetchedCounter++;
                    goto RequeueAndAbort;
                }
                else
                {
                    ContractsPackageAccessor.Current.Logger.WriteToLog("An 'IllFormedSemanticModelException' occured: '" + e.Message + "' Too many semantic models have been fetched, skipping this property...");
                    goto Continue;
                }
            } catch (InvalidOperationException e) {
                if (e.Message.Contains(ContractsPackageAccessor.InvalidOperationExceptionMessage_TheSnapshotIsOutOfDate))
                {
                    if (@this.trackingNumberOfFetchedSemanticModels && @this.semanticModelsFetchedCounter <= 5)
                    {
                        ContractsPackageAccessor.Current.Logger.WriteToLog("The Visual Studio Semantic/Syntactic model threw an exception (it's snapshot is out of date) while looking up contracts, getting new compilation...");
                        @this._textViewTracker.IsLatestCompilationStale = true;
                        ContractsPackageAccessor.Current.AskForNewVSModel();
                        @this.semanticModelsFetchedCounter++;
                        goto RequeueAndAbort;
                    }
                    else
                    {
                        ContractsPackageAccessor.Current.Logger.WriteToLog("The Visual Studio Semantic/Syntactic model threw an exception (it's snapshot is out of date) while looking up contracts. Too many compilations have already been fetched, skipping this property...");
                        goto Continue;
                    }
                }
                else
                {
                    throw e;
                }
            } catch (COMException e) {
                if (e.Message.Contains(ContractsPackageAccessor.COMExceptionMessage_BindingFailed))
                {
                    if (@this.trackingNumberOfFetchedSemanticModels && @this.semanticModelsFetchedCounter <= 5)
                    {
                        ContractsPackageAccessor.Current.Logger.WriteToLog("The Visual Studio Semantic/Syntactic model threw an exception (it's snapshot is out of date) while looking up contracts, getting new compilation...");
                        @this._textViewTracker.IsLatestCompilationStale = true;
                        ContractsPackageAccessor.Current.AskForNewVSModel();
                        @this.semanticModelsFetchedCounter++;
                        goto RequeueAndAbort;
                    }
                    else
                    {
                        ContractsPackageAccessor.Current.Logger.WriteToLog("The Visual Studio Semantic/Syntactic model threw an exception (it's snapshot is out of date) while looking up contracts. Too many compilations have already been fetched, skipping this property...");
                        goto Continue;
                    }
                }
                else
                {
                    throw e;
                }
            }
            #endregion
Continue:
            ContractsPackageAccessor.Current.QueueWorkItem(() => RecursivelyLookupContractsForProperties(@this));
            return;

RequeueAndAbort:
            @this._propertiesNeedingContractLookup.Enqueue(propertyPair);
            return;
        }
        static void RecursivelyLookupContractsForMethods(InheritanceTracker @this)
        {
            Contract.Requires(@this != null);

            #region Dequeue
            if (@this._methodsNeedingContractLookup.Count < 1)
            {
                return;
            }
            var methodPair = @this._methodsNeedingContractLookup.Dequeue();
            var method     = methodPair.Value;
            var tag        = methodPair.Key;
            #endregion
            try {
                VSServiceProvider.Current.Logger.WriteToLog(String.Format("Attempting to lookup contracts for '{0}'", tag.ToString()));
                var comp = @this._textViewTracker.LatestCompilation;
                if (comp == null)
                {
                    VSServiceProvider.Current.Logger.WriteToLog("No LatestCompilation, waiting for a new semantic model.");
                    @this._textViewTracker.IsLatestCompilationStale = true;
                    Utilities.Delay(() => VSServiceProvider.Current.AskForNewVSModel(), DelayOnVSModelFailedBeforeTryingAgain);
                    @this.semanticModelsFetchedCounter++;
                    goto RequeueAndAbort;
                }
                #region Get semantic method from syntactic method
                CSharpMember semanticMethod = null;
                semanticMethod = comp.GetMemberForMethodDeclaration(method);
                if (semanticMethod == null)
                {
                    if (@this.trackingNumberOfFetchedSemanticModels && @this.semanticModelsFetchedCounter <= 3)
                    {
                        VSServiceProvider.Current.Logger.WriteToLog("Failed to get semantic method from syntactic method, waiting for a new semantic model.");
                        @this._textViewTracker.IsLatestCompilationStale = true;
                        Utilities.Delay(() => VSServiceProvider.Current.AskForNewVSModel(), DelayOnVSModelFailedBeforeTryingAgain);
                        @this.semanticModelsFetchedCounter++;
                        goto RequeueAndAbort;
                    }
                    else
                    {
                        VSServiceProvider.Current.Logger.WriteToLog("Failed to get semantic method from syntactic method. Too many semantic models have already been fetched, skipping this method...");
                        goto Continue;
                    }
                }
                #endregion
                #region Try get the method that this method is inherited from
                CSharpMember inheritedFromMethod;
                if (!TryGetIheritedFromMember(semanticMethod, method.Parent as TypeDeclarationNode, out inheritedFromMethod))
                {
                    goto Continue;
                }
                #endregion
                #region Uninstantiated method
                semanticMethod = semanticMethod.Uninstantiate();
                #endregion
                #region Get our tool tip
                var toolTip = "";
                if (!semanticMethod.IsAbstract && !semanticMethod.ContainingType.IsInterface)
                {
                    toolTip = String.Format("Contracts inherited from {0}.", inheritedFromMethod.ContainingType.Name.Text);
                }
                #endregion
                #region Try get method contracts and update adornment
                IMethodContract contracts = null;
                if (@this._textViewTracker.ProjectTracker.ContractsProvider.TryGetMethodContract(inheritedFromMethod, out contracts))
                {
                    var possibleAdornment = @this._adornmentManager.GetAdornment(tag);
                    if (possibleAdornment != null)
                    {
                        var adornment = possibleAdornment as ContractAdornment;
                        if (adornment != null)
                        {
                            adornment.SetContracts(contracts, toolTip);
                        }
                        else
                        {
                            VSServiceProvider.Current.Logger.WriteToLog("Placeholder adornment isn't a ContractAdornment (not good!), skipping method...");
                        }
                    }
                    else
                    {
                        VSServiceProvider.Current.Logger.WriteToLog("Placeholder adornment not found, skipping method...");
                    }
                }
                #endregion
            }
            #region Exception handeling
            catch (IllFormedSemanticModelException e) {
                if (@this.trackingNumberOfFetchedSemanticModels && @this.semanticModelsFetchedCounter <= 2)
                {
                    VSServiceProvider.Current.Logger.WriteToLog("Error: An 'IllFormedSemanticModelException' occured: '" + e.Message + "' Asking for a new semantic model...");
                    @this._textViewTracker.IsLatestCompilationStale = true;
                    VSServiceProvider.Current.AskForNewVSModel();
                    @this.semanticModelsFetchedCounter++;
                    goto RequeueAndAbort;
                }
                else
                {
                    VSServiceProvider.Current.Logger.WriteToLog("An 'IllFormedSemanticModelException' occured: '" + e.Message + "' Too many semantic models have been fetched, skipping this method...");
                    goto Continue;
                }
            } catch (InvalidOperationException e) {
                if (e.Message.Contains(VSServiceProvider.InvalidOperationExceptionMessage_TheSnapshotIsOutOfDate))
                {
                    if (@this.trackingNumberOfFetchedSemanticModels && @this.semanticModelsFetchedCounter <= 5)
                    {
                        VSServiceProvider.Current.Logger.WriteToLog("The Visual Studio Semantic/Syntactic model threw an exception (it's snapshot is out of date) while looking up contracts, getting new compilation...");
                        @this._textViewTracker.IsLatestCompilationStale = true;
                        VSServiceProvider.Current.AskForNewVSModel();
                        @this.semanticModelsFetchedCounter++;
                        goto RequeueAndAbort;
                    }
                    else
                    {
                        VSServiceProvider.Current.Logger.WriteToLog("The Visual Studio Semantic/Syntactic model threw an exception (it's snapshot is out of date) while looking up contracts. Too many compilations have already been fetched, skipping this method...");
                        goto Continue;
                    }
                }
                else
                {
                    throw e;
                }
            } catch (COMException e) {
                if (e.Message.Contains(VSServiceProvider.COMExceptionMessage_BindingFailed))
                {
                    if (@this.trackingNumberOfFetchedSemanticModels && @this.semanticModelsFetchedCounter <= 5)
                    {
                        VSServiceProvider.Current.Logger.WriteToLog("The Visual Studio Semantic/Syntactic model threw an exception (it's snapshot is out of date) while looking up contracts, getting new compilation...");
                        @this._textViewTracker.IsLatestCompilationStale = true;
                        VSServiceProvider.Current.AskForNewVSModel();
                        @this.semanticModelsFetchedCounter++;
                        goto RequeueAndAbort;
                    }
                    else
                    {
                        VSServiceProvider.Current.Logger.WriteToLog("The Visual Studio Semantic/Syntactic model threw an exception (it's snapshot is out of date) while looking up contracts. Too many compilations have already been fetched, skipping this method...");
                        goto Continue;
                    }
                }
                else
                {
                    throw e;
                }
            }
            #endregion
Continue:
            VSServiceProvider.Current.QueueWorkItem(() => RecursivelyLookupContractsForMethods(@this));
            return;

RequeueAndAbort:
            @this._methodsNeedingContractLookup.Enqueue(methodPair);
            return;
        }