public IDependencyViewModel CreateRootViewModel(string providerType, bool hasUnresolvedDependency)
        {
            IProjectDependenciesSubTreeProvider provider = GetProvider(providerType);
            IDependencyModel dependencyModel             = provider.CreateRootDependencyNode();

            return(dependencyModel.ToViewModel(hasUnresolvedDependency));
        }
Example #2
0
        public void Added(IDependencyModel model)
        {
            _added ??= new HashSet <IDependencyModel>(IDependencyModelEqualityComparer.Instance);

            _added.Remove(model);
            _added.Add(model);
        }
Example #3
0
        public Dependency(IDependencyModel dependencyModel)
        {
            Requires.NotNull(dependencyModel, nameof(dependencyModel));
            Requires.NotNullOrEmpty(dependencyModel.ProviderType, nameof(dependencyModel.ProviderType));
            Requires.NotNullOrEmpty(dependencyModel.Id, nameof(dependencyModel.Id));

            Id = dependencyModel.Id;

            ProviderType     = dependencyModel.ProviderType;
            Caption          = dependencyModel.Caption ?? string.Empty;
            OriginalItemSpec = dependencyModel.OriginalItemSpec;
            FilePath         = dependencyModel.Path;
            SchemaName       = dependencyModel.SchemaName ?? Folder.SchemaName;
            _schemaItemType  = dependencyModel.SchemaItemType ?? Folder.PrimaryDataSourceItemType;
            Resolved         = dependencyModel.Resolved;
            Implicit         = dependencyModel.Implicit;
            Visible          = dependencyModel.Visible;
            Flags            = dependencyModel.Flags;

            // Just in case custom providers don't do it, add corresponding flags for Resolved state.
            // This is needed for tree update logic to track if tree node changing state from unresolved
            // to resolved or vice-versa (it helps to decide if we need to remove it or update in-place
            // in the tree to avoid flicks).
            if (Resolved)
            {
                if (!Flags.Contains(DependencyTreeFlags.Resolved))
                {
                    Flags += DependencyTreeFlags.Resolved;
                }
            }
            else
            {
                if (!Flags.Contains(DependencyTreeFlags.Unresolved))
                {
                    Flags += DependencyTreeFlags.Unresolved;
                }
            }

            // If this is one of our implementations of IDependencyModel then we can just reuse the icon
            // set rather than creating a new one.
            if (dependencyModel is DependencyModel model)
            {
                IconSet = model.IconSet;

                // For now we consider any non-empty DiagnosticLevel string as a warning. In future we
                // may differentiate visually on the node between different grades of diagnostic,
                // such as warnings and errors.
                _hasDiagnostic = model.DiagnosticLevel != DiagnosticLevel.None;
            }
            else
            {
                IconSet = DependencyIconSetCache.Instance.GetOrAddIconSet(dependencyModel.Icon, dependencyModel.ExpandedIcon, dependencyModel.UnresolvedIcon, dependencyModel.UnresolvedExpandedIcon);
            }

            BrowseObjectProperties = dependencyModel.Properties
                                     ?? ImmutableStringDictionary <string> .EmptyOrdinal
                                     .Add(Folder.IdentityProperty, Caption)
                                     .Add(Folder.FullPathProperty, FilePath ?? string.Empty);
        }
Example #4
0
 public void IncludeAddedChange(IDependencyModel model)
 {
     lock (_added)
     {
         _added.Remove(model);
         _added.Add(model);
     }
 }
Example #5
0
        public Dependency(IDependencyModel dependencyModel, ITargetFramework targetFramework)
        {
            Requires.NotNull(dependencyModel, nameof(dependencyModel));
            Requires.NotNullOrEmpty(dependencyModel.ProviderType, nameof(dependencyModel.ProviderType));
            Requires.NotNullOrEmpty(dependencyModel.Id, nameof(dependencyModel.Id));
            Requires.NotNull(targetFramework, nameof(targetFramework));

            TargetFramework = targetFramework;

            _modelId = dependencyModel.Id;

            ProviderType     = dependencyModel.ProviderType;
            Name             = dependencyModel.Name ?? string.Empty;
            Caption          = dependencyModel.Caption ?? string.Empty;
            OriginalItemSpec = dependencyModel.OriginalItemSpec ?? string.Empty;
            Path             = dependencyModel.Path ?? string.Empty;
            SchemaName       = dependencyModel.SchemaName ?? Folder.SchemaName;
            _schemaItemType  = dependencyModel.SchemaItemType ?? Folder.PrimaryDataSourceItemType;
            Resolved         = dependencyModel.Resolved;
            Implicit         = dependencyModel.Implicit;
            Visible          = dependencyModel.Visible;
            Flags            = dependencyModel.Flags;

            // Just in case custom providers don't do it, add corresponding flags for Resolved state.
            // This is needed for tree update logic to track if tree node changing state from unresolved
            // to resolved or vice-versa (it helps to decide if we need to remove it or update in-place
            // in the tree to avoid flicks).
            if (Resolved)
            {
                if (!Flags.Contains(DependencyTreeFlags.Resolved))
                {
                    Flags += DependencyTreeFlags.Resolved;
                }
            }
            else
            {
                if (!Flags.Contains(DependencyTreeFlags.Unresolved))
                {
                    Flags += DependencyTreeFlags.Unresolved;
                }
            }

            // If this is one of our implementations of IDependencyModel then we can just reuse the icon
            // set rather than creating a new one.
            if (dependencyModel is DependencyModel model)
            {
                IconSet = model.IconSet;
            }
            else
            {
                IconSet = DependencyIconSetCache.Instance.GetOrAddIconSet(dependencyModel.Icon, dependencyModel.ExpandedIcon, dependencyModel.UnresolvedIcon, dependencyModel.UnresolvedExpandedIcon);
            }

            BrowseObjectProperties = dependencyModel.Properties
                                     ?? ImmutableStringDictionary <string> .EmptyOrdinal
                                     .Add(Folder.IdentityProperty, Caption)
                                     .Add(Folder.FullPathProperty, Path);
        }
Example #6
0
        public void Added(IDependencyModel model)
        {
            if (_added == null)
            {
                _added = new HashSet <IDependencyModel>();
            }

            _added.Remove(model);
            _added.Add(model);
        }
Example #7
0
 public void IncludeRemovedChange(ITargetFramework targetFramework,
                                  IDependencyModel ruleMetadata)
 {
     lock (_changesLock)
     {
         var change = GetChanges(targetFramework) as DependenciesChanges;
         change?.ExcludeRemovedChange(ruleMetadata);
         change?.IncludeRemovedChange(ruleMetadata);
     }
 }
        private void HandleChangesForRule(
            IProjectChangeDescription projectChange,
            DependenciesRuleChangeContext ruleChangeContext,
            ITargetFramework targetFramework,
            bool resolved,
            HashSet <string> unresolvedChanges = null)
        {
            Requires.NotNull(targetFramework, nameof(targetFramework));

            if (targetFramework == null)
            {
                return;
            }

            foreach (string removedItem in projectChange.Difference.RemovedItems)
            {
                IImmutableDictionary <string, string> properties = GetProjectItemProperties(projectChange.Before, removedItem);
                IDependencyModel model = GetDependencyModel(removedItem, resolved,
                                                            properties, projectChange, unresolvedChanges, targetFramework);
                if (model == null)
                {
                    continue;
                }

                ruleChangeContext.IncludeRemovedChange(targetFramework, model);
            }

            foreach (string changedItem in projectChange.Difference.ChangedItems)
            {
                IImmutableDictionary <string, string> properties = GetProjectItemProperties(projectChange.After, changedItem);
                IDependencyModel model = GetDependencyModel(changedItem, resolved,
                                                            properties, projectChange, unresolvedChanges, targetFramework);
                if (model == null)
                {
                    continue;
                }

                ruleChangeContext.IncludeRemovedChange(targetFramework, model);
                ruleChangeContext.IncludeAddedChange(targetFramework, model);
            }

            foreach (string addedItem in projectChange.Difference.AddedItems)
            {
                IImmutableDictionary <string, string> properties = GetProjectItemProperties(projectChange.After, addedItem);
                IDependencyModel model = GetDependencyModel(addedItem, resolved,
                                                            properties, projectChange, unresolvedChanges, targetFramework);
                if (model == null)
                {
                    continue;
                }

                ruleChangeContext.IncludeAddedChange(targetFramework, model);
            }
        }
Example #9
0
        public bool Equals(IDependencyModel other)
        {
            if (other != null &&
                other.Id.Equals(Id, StringComparison.OrdinalIgnoreCase) &&
                other.ProviderType.Equals(ProviderType, StringComparison.OrdinalIgnoreCase))
            {
                return(true);
            }

            return(false);
        }
        protected virtual void HandleAddedItem(
            string addedItem,
            bool resolved,
            IProjectChangeDescription projectChange,
            DependenciesChangesBuilder changesBuilder,
            ITargetFramework targetFramework,
            Func <string, bool>?isEvaluatedItemSpec)
        {
            IDependencyModel model = CreateDependencyModelForRule(addedItem, projectChange.After, resolved);

            if (isEvaluatedItemSpec == null || isEvaluatedItemSpec(model.Id))
            {
                changesBuilder.Added(model);
            }
        }
Example #11
0
 public static IDependencyViewModel ToViewModel(this IDependencyModel self, bool hasUnresolvedDependency)
 {
     return(new DependencyViewModel
     {
         Caption = self.Caption,
         FilePath = self.Id,
         SchemaName = self.SchemaName,
         SchemaItemType = self.SchemaItemType,
         Priority = self.Priority,
         Icon = hasUnresolvedDependency ? self.UnresolvedIcon : self.Icon,
         ExpandedIcon = hasUnresolvedDependency ? self.UnresolvedExpandedIcon : self.ExpandedIcon,
         Properties = self.Properties,
         Flags = self.Flags
     });
 }
Example #12
0
        private void ProcessSharedProjectsUpdates(
            IProjectSharedFoldersSnapshot sharedFolders,
            ITargetedProjectContext targetContext,
            DependenciesRuleChangeContext dependencyChangeContext)
        {
            Requires.NotNull(sharedFolders, nameof(sharedFolders));
            Requires.NotNull(targetContext, nameof(targetContext));
            Requires.NotNull(dependencyChangeContext, nameof(dependencyChangeContext));

            IDependenciesSnapshot snapshot = _dependenciesSnapshotProvider.CurrentSnapshot;

            if (!snapshot.Targets.TryGetValue(targetContext.TargetFramework, out ITargetedDependenciesSnapshot targetedSnapshot))
            {
                return;
            }

            IEnumerable <string> sharedFolderProjectPaths = sharedFolders.Value.Select(sf => sf.ProjectPath);
            var currentSharedImportNodes = targetedSnapshot.TopLevelDependencies
                                           .Where(x => x.Flags.Contains(DependencyTreeFlags.SharedProjectFlags))
                                           .ToList();
            IEnumerable <string> currentSharedImportNodePaths = currentSharedImportNodes.Select(x => x.Path);

            // process added nodes
            IEnumerable <string> addedSharedImportPaths = sharedFolderProjectPaths.Except(currentSharedImportNodePaths);

            foreach (string addedSharedImportPath in addedSharedImportPaths)
            {
                IDependencyModel added = CreateDependencyModel(addedSharedImportPath, targetContext.TargetFramework, resolved: true);
                dependencyChangeContext.IncludeAddedChange(targetContext.TargetFramework, added);
            }

            // process removed nodes
            IEnumerable <string> removedSharedImportPaths = currentSharedImportNodePaths.Except(sharedFolderProjectPaths);

            foreach (string removedSharedImportPath in removedSharedImportPaths)
            {
                IDependency existingImportNode = currentSharedImportNodes
                                                 .Where(node => PathHelper.IsSamePath(node.Path, removedSharedImportPath))
                                                 .FirstOrDefault();

                if (existingImportNode != null)
                {
                    IDependencyModel removed = CreateDependencyModel(removedSharedImportPath, targetContext.TargetFramework, resolved: true);
                    dependencyChangeContext.IncludeRemovedChange(targetContext.TargetFramework, removed);
                }
            }
        }
        protected virtual void HandleChangedItem(
            string changedItem,
            bool resolved,
            IProjectChangeDescription projectChange,
            DependenciesChangesBuilder changesBuilder,
            ITargetFramework targetFramework,
            Func <string, bool>?isEvaluatedItemSpec)
        {
            IDependencyModel model = CreateDependencyModelForRule(changedItem, projectChange.After, resolved);

            if (isEvaluatedItemSpec == null || isEvaluatedItemSpec(model.Id))
            {
                // For changes we try to add new dependency. If it is a resolved dependency, it would just override
                // old one with new properties. If it is unresolved dependency, it would be added only when there no
                // resolved version in the snapshot.
                changesBuilder.Added(model);
            }
        }
        public static IProjectDependenciesSubTreeProvider Implement(
            string providerType = null,
            IDependencyModel createRootDependencyNode = null,
            MockBehavior mockBehavior = MockBehavior.Strict)
        {
            var mock = new Mock <IProjectDependenciesSubTreeProvider>(mockBehavior);

            if (providerType != null)
            {
                mock.Setup(x => x.ProviderType).Returns(providerType);
            }

            if (createRootDependencyNode != null)
            {
                mock.Setup(x => x.CreateRootDependencyNode()).Returns(createRootDependencyNode);
            }

            return(mock.Object);
        }
        private void HandleChangesForRule(
            bool resolved,
            IProjectChangeDescription projectChange,
            ITargetFramework targetFramework,
            DependenciesRuleChangeContext ruleChangeContext,
            Func <string, bool> shouldProcess)
        {
            foreach (string removedItem in projectChange.Difference.RemovedItems)
            {
                string dependencyId = resolved
                    ? projectChange.Before.GetProjectItemProperties(removedItem).GetStringProperty(OriginalItemSpecPropertyName)
                    : removedItem;

                if (shouldProcess(dependencyId))
                {
                    ruleChangeContext.IncludeRemovedChange(targetFramework, ProviderType, removedItem);
                }
            }

            foreach (string changedItem in projectChange.Difference.ChangedItems)
            {
                IDependencyModel model = CreateDependencyModelForRule(changedItem, resolved, projectChange.After);
                if (shouldProcess(model.Id))
                {
                    // For changes we try to add new dependency. If it is a resolved dependency, it would just override
                    // old one with new properties. If it is unresolved dependency, it would be added only when there no
                    // resolved version in the snapshot.
                    ruleChangeContext.IncludeAddedChange(targetFramework, model);
                }
            }

            foreach (string addedItem in projectChange.Difference.AddedItems)
            {
                IDependencyModel model = CreateDependencyModelForRule(addedItem, resolved, projectChange.After);
                if (shouldProcess(model.Id))
                {
                    ruleChangeContext.IncludeAddedChange(targetFramework, model);
                }
            }
        }
        private void HandleChangesForRule(
            bool resolved,
            IProjectChangeDescription projectChange,
            ITargetedProjectContext context,
            bool isActiveContext,
            DependenciesRuleChangeContext ruleChangeContext,
            Func <IDependencyModel, bool> shouldProcess)
        {
            foreach (string removedItem in projectChange.Difference.RemovedItems)
            {
                IDependencyModel model = CreateDependencyModelForRule(removedItem, resolved, projectChange.Before, context.TargetFramework);
                if (shouldProcess(model))
                {
                    ruleChangeContext.IncludeRemovedChange(context.TargetFramework, model);
                }
            }

            foreach (string changedItem in projectChange.Difference.ChangedItems)
            {
                IDependencyModel model = CreateDependencyModelForRule(changedItem, resolved, projectChange.After, context.TargetFramework);
                if (shouldProcess(model))
                {
                    // For changes we try to add new dependency. If it is a resolved dependency, it would just override
                    // old one with new properties. If it is unresolved dependency, it would be added only when there no
                    // resolved version in the snapshot.
                    ruleChangeContext.IncludeAddedChange(context.TargetFramework, model);
                }
            }

            foreach (string addedItem in projectChange.Difference.AddedItems)
            {
                IDependencyModel model = CreateDependencyModelForRule(addedItem, resolved, projectChange.After, context.TargetFramework);
                if (shouldProcess(model))
                {
                    ruleChangeContext.IncludeAddedChange(context.TargetFramework, model);
                }
            }
        }
            public LookupManager( IKernel kernel, IDependencyModel[] dependencies )
            {
                m_kernel = kernel;

                foreach(IDependencyModel dependency in dependencies )
                {
                    if (!kernel.HasService( dependency.Service ))
                    {
                        if (!dependency.Optional)
                        {
                            throw new LookupException( dependency.LookupKey, "Kernel can't supply specified service.");
                        }
                        else
                        {
                            continue;
                        }
                    }

                    m_key2handler[ dependency.LookupKey ] =
                        kernel.GetHandlerForService( dependency.Service );
                }
            }
 public void ExcludeRemovedChange(IDependencyModel model)
 {
     Removed.Remove(model);
 }
Example #19
0
 public static IDependencyViewModel ToViewModel(this IDependencyModel self, bool hasUnresolvedDependency)
 {
     return(new DependencyModelViewModel(self, hasUnresolvedDependency));
 }
Example #20
0
 public DependencyModelViewModel(IDependencyModel model, bool hasUnresolvedDependency)
 {
     _model = model;
     _hasUnresolvedDependency = hasUnresolvedDependency;
 }
 public void Added(ITargetFramework targetFramework, IDependencyModel model)
 {
     GetChanges(targetFramework).Added(model);
 }
 public bool Equals(IDependencyModel other)
 {
     return(other != null &&
            other.Id.Equals(Id, StringComparison.OrdinalIgnoreCase) &&
            StringComparers.DependencyProviderTypes.Equals(other.ProviderType, ProviderType));
 }
        /// <summary>
        /// When some other project's snapshot changed we need to check if our snapshot has a top level
        /// dependency on changed project. If it does we need to refresh those top level dependencies to
        /// reflect changes.
        /// </summary>
        /// <param name="thisProjectSnapshot"></param>
        /// <param name="otherProjectSnapshot"></param>
        /// <param name="shouldBeResolved">
        /// Specifies if top-level project dependencies resolved status. When other project just had its dependencies
        /// changed, it is resolved=true (we check target's support when we add project dependencies). However when
        /// other project is unloaded, we should mark top-level dependencies as unresolved.
        /// </param>
        /// <param name="token"></param>
        private void OnOtherProjectDependenciesChanged(
            DependenciesSnapshot thisProjectSnapshot,
            DependenciesSnapshot otherProjectSnapshot,
            bool shouldBeResolved,
            CancellationToken token)
        {
            if (token.IsCancellationRequested ||
                StringComparers.Paths.Equals(thisProjectSnapshot.ProjectPath, otherProjectSnapshot.ProjectPath))
            {
                // if any of the snapshots is not provided or this is the same project - skip
                return;
            }

            string otherProjectPath = otherProjectSnapshot.ProjectPath;

            foreach ((ITargetFramework _, TargetedDependenciesSnapshot targetedDependencies) in thisProjectSnapshot.DependenciesByTargetFramework)
            {
                foreach (IDependency dependency in targetedDependencies.TopLevelDependencies)
                {
                    if (token.IsCancellationRequested)
                    {
                        return;
                    }

                    // We're only interested in project dependencies
                    if (!StringComparers.DependencyProviderTypes.Equals(dependency.ProviderType, ProviderTypeString))
                    {
                        continue;
                    }

                    if (!StringComparers.Paths.Equals(otherProjectPath, dependency.FullPath))
                    {
                        continue;
                    }

                    RaiseChangeEvent(dependency);
                    break;
                }
            }

            return;

            void RaiseChangeEvent(IDependency dependency)
            {
                IDependencyModel model = CreateDependencyModel(
                    dependency.Path,
                    dependency.OriginalItemSpec,
                    shouldBeResolved,
                    dependency.Implicit,
                    dependency.BrowseObjectProperties);

                var changes = new DependenciesChangesBuilder();

                // avoid unnecessary removing since, add would upgrade dependency in snapshot anyway,
                // but remove would require removing item from the tree instead of in-place upgrade.
                if (!shouldBeResolved)
                {
                    changes.Removed(ProviderTypeString, model.Id);
                }

                changes.Added(model);

                FireDependenciesChanged(
                    new DependenciesChangedEventArgs(
                        this,
                        dependency.TargetFramework.FullName,
                        changes.TryBuildChanges() !,
                        token));
            }
        }
        public virtual void Handle(
            IImmutableDictionary <string, IProjectChangeDescription> changesByRuleName,
            ITargetFramework targetFramework,
            CrossTargetDependenciesChangesBuilder changesBuilder)
        {
            // We receive unresolved and resolved changes separately.

            // Process all unresolved changes.
            if (changesByRuleName.TryGetValue(UnresolvedRuleName, out IProjectChangeDescription unresolvedChanges))
            {
                HandleChangesForRule(
                    resolved: false,
                    projectChange: unresolvedChanges,
                    shouldProcess: dependencyId => true);
            }

            // Process only resolved changes that have a corresponding unresolved item.
            if (unresolvedChanges != null &&
                changesByRuleName.TryGetValue(ResolvedRuleName, out IProjectChangeDescription resolvedChanges))
            {
                HandleChangesForRule(
                    resolved: true,
                    projectChange: resolvedChanges,
                    shouldProcess: unresolvedChanges.After.Items.ContainsKey);
            }

            return;

            void HandleChangesForRule(bool resolved, IProjectChangeDescription projectChange, Func <string, bool> shouldProcess)
            {
                foreach (string removedItem in projectChange.Difference.RemovedItems)
                {
                    string dependencyId = resolved
                        ? projectChange.Before.GetProjectItemProperties(removedItem).GetStringProperty(ResolvedAssemblyReference.OriginalItemSpecProperty) ?? removedItem
                        : removedItem;

                    if (shouldProcess(dependencyId))
                    {
                        changesBuilder.Removed(targetFramework, ProviderType, removedItem);
                    }
                }

                foreach (string changedItem in projectChange.Difference.ChangedItems)
                {
                    IDependencyModel model = CreateDependencyModelForRule(changedItem, projectChange.After);
                    if (shouldProcess(model.Id))
                    {
                        // For changes we try to add new dependency. If it is a resolved dependency, it would just override
                        // old one with new properties. If it is unresolved dependency, it would be added only when there no
                        // resolved version in the snapshot.
                        changesBuilder.Added(targetFramework, model);
                    }
                }

                foreach (string addedItem in projectChange.Difference.AddedItems)
                {
                    IDependencyModel model = CreateDependencyModelForRule(addedItem, projectChange.After);
                    if (shouldProcess(model.Id))
                    {
                        changesBuilder.Added(targetFramework, model);
                    }
                }

                return;

                IDependencyModel CreateDependencyModelForRule(string itemSpec, IProjectRuleSnapshot projectRuleSnapshot)
                {
                    IImmutableDictionary <string, string> properties = projectRuleSnapshot.GetProjectItemProperties(itemSpec);

                    string originalItemSpec = resolved
                        ? properties.GetStringProperty(ResolvedAssemblyReference.OriginalItemSpecProperty)
                        : itemSpec;

                    bool isImplicit = properties.GetBoolProperty(ProjectItemMetadata.IsImplicitlyDefined) ?? false;

                    return(CreateDependencyModel(
                               itemSpec,
                               originalItemSpec,
                               resolved,
                               isImplicit,
                               properties));
                }
            }
        }
 public void IncludeAddedChange(IDependencyModel model)
 {
     Added.Add(model);
 }
Example #26
0
        public Dependency(IDependencyModel dependencyModel, ITargetFramework targetFramework, string containingProjectPath)
        {
            Requires.NotNull(dependencyModel, nameof(dependencyModel));
            Requires.NotNullOrEmpty(dependencyModel.ProviderType, nameof(dependencyModel.ProviderType));
            Requires.NotNullOrEmpty(dependencyModel.Id, nameof(dependencyModel.Id));
            Requires.NotNull(targetFramework, nameof(targetFramework));
            Requires.NotNullOrEmpty(containingProjectPath, nameof(containingProjectPath));

            TargetFramework = targetFramework;

            _modelId = dependencyModel.Id;
            _containingProjectPath = containingProjectPath;

            ProviderType     = dependencyModel.ProviderType;
            Name             = dependencyModel.Name ?? string.Empty;
            Version          = dependencyModel.Version ?? string.Empty;
            Caption          = dependencyModel.Caption ?? string.Empty;
            OriginalItemSpec = dependencyModel.OriginalItemSpec ?? string.Empty;
            Path             = dependencyModel.Path ?? string.Empty;
            SchemaName       = dependencyModel.SchemaName ?? Folder.SchemaName;
            _schemaItemType  = dependencyModel.SchemaItemType ?? Folder.PrimaryDataSourceItemType;
            Resolved         = dependencyModel.Resolved;
            TopLevel         = dependencyModel.TopLevel;
            Implicit         = dependencyModel.Implicit;
            Visible          = dependencyModel.Visible;
            Priority         = dependencyModel.Priority;
            Flags            = dependencyModel.Flags;

            // Just in case custom providers don't do it, add corresponding flags for Resolved state.
            // This is needed for tree update logic to track if tree node changing state from unresolved
            // to resolved or vice-versa (it helps to decide if we need to remove it or update in-place
            // in the tree to avoid flicks).
            if (Resolved)
            {
                Flags = Flags.Union(DependencyTreeFlags.ResolvedFlags);
            }
            else
            {
                Flags = Flags.Union(DependencyTreeFlags.UnresolvedFlags);
            }

            Icon                   = dependencyModel.Icon;
            ExpandedIcon           = dependencyModel.ExpandedIcon;
            UnresolvedIcon         = dependencyModel.UnresolvedIcon;
            UnresolvedExpandedIcon = dependencyModel.UnresolvedExpandedIcon;
            Properties             = dependencyModel.Properties ??
                                     ImmutableDictionary <string, string> .Empty
                                     .Add(Folder.IdentityProperty, Caption)
                                     .Add(Folder.FullPathProperty, Path);

            if (dependencyModel.DependencyIDs == null)
            {
                DependencyIDs = ImmutableList <string> .Empty;
            }
            else
            {
                var normalizedDependencyIDs = ImmutableList.CreateBuilder <string>();
                foreach (var id in dependencyModel.DependencyIDs)
                {
                    normalizedDependencyIDs.Add(GetID(TargetFramework, ProviderType, id));
                }

                DependencyIDs = normalizedDependencyIDs.ToImmutable();
            }
        }
        private IDependencyModel GetDependencyModel(
            string itemSpec,
            bool resolved,
            IImmutableDictionary <string, string> properties,
            IProjectChangeDescription projectChange,
            HashSet <string> unresolvedChanges,
            ITargetFramework targetFramework)
        {
            PackageDependencyMetadata metadata;
            bool isTopLevel = true;
            bool isTarget   = false;

            if (resolved)
            {
                metadata   = new PackageDependencyMetadata(itemSpec, properties);
                isTopLevel = metadata.IsImplicitlyDefined ||
                             (metadata.DependencyType == DependencyType.Package &&
                              unresolvedChanges != null &&
                              unresolvedChanges.Contains(metadata.Name));
                isTarget = metadata.IsTarget;
                ITargetFramework packageTargetFramework = TargetFrameworkProvider.GetTargetFramework(metadata.Target);
                if (!(packageTargetFramework?.Equals(targetFramework) == true))
                {
                    return(null);
                }
            }
            else
            {
                metadata = CreateUnresolvedMetadata(itemSpec, properties);
            }

            if (isTarget)
            {
                return(null);
            }

            string originalItemSpec = itemSpec;

            if (resolved && isTopLevel)
            {
                originalItemSpec = metadata.Name;
            }

            IDependencyModel dependencyModel = null;

            switch (metadata.DependencyType)
            {
            case DependencyType.Package:
                dependencyModel = new PackageDependencyModel(
                    ProviderType,
                    itemSpec,
                    originalItemSpec,
                    metadata.Name,
                    DependencyTreeFlags.NuGetSubTreeNodeFlags,
                    metadata.Version,
                    resolved,
                    metadata.IsImplicitlyDefined,
                    isTopLevel,
                    !metadata.IsImplicitlyDefined /*visible*/,
                    properties,
                    metadata.DependenciesItemSpecs);
                break;

            case DependencyType.Assembly:
            case DependencyType.FrameworkAssembly:
                dependencyModel = new PackageAssemblyDependencyModel(
                    ProviderType,
                    itemSpec,
                    originalItemSpec,
                    metadata.Name,
                    DependencyTreeFlags.NuGetSubTreeNodeFlags,
                    resolved,
                    properties,
                    metadata.DependenciesItemSpecs);
                break;

            case DependencyType.AnalyzerAssembly:
                dependencyModel = new PackageAnalyzerAssemblyDependencyModel(
                    ProviderType,
                    itemSpec,
                    originalItemSpec,
                    metadata.Name,
                    DependencyTreeFlags.NuGetSubTreeNodeFlags,
                    resolved,
                    properties,
                    metadata.DependenciesItemSpecs);
                break;

            case DependencyType.Diagnostic:
                dependencyModel = new DiagnosticDependencyModel(
                    ProviderType,
                    itemSpec,
                    metadata.Severity,
                    metadata.DiagnosticCode,
                    metadata.Name,
                    DependencyTreeFlags.NuGetSubTreeNodeFlags,
                    isVisible: true,
                    properties: properties);
                break;

            default:
                dependencyModel = new PackageUnknownDependencyModel(
                    ProviderType,
                    itemSpec,
                    originalItemSpec,
                    metadata.Name,
                    DependencyTreeFlags.NuGetSubTreeNodeFlags,
                    resolved,
                    properties,
                    metadata.DependenciesItemSpecs);
                break;
            }

            return(dependencyModel);
        }
        public Dependency(IDependencyModel dependencyModel, ITargetFramework targetFramework, string containingProjectPath)
        {
            Requires.NotNull(dependencyModel, nameof(dependencyModel));
            Requires.NotNullOrEmpty(dependencyModel.ProviderType, nameof(dependencyModel.ProviderType));
            Requires.NotNullOrEmpty(dependencyModel.Id, nameof(dependencyModel.Id));
            Requires.NotNull(targetFramework, nameof(targetFramework));
            Requires.NotNullOrEmpty(containingProjectPath, nameof(containingProjectPath));

            TargetFramework = targetFramework;

            _modelId = dependencyModel.Id;
            _containingProjectPath = containingProjectPath;

            ProviderType     = dependencyModel.ProviderType;
            Name             = dependencyModel.Name ?? string.Empty;
            Version          = dependencyModel.Version ?? string.Empty;
            Caption          = dependencyModel.Caption ?? string.Empty;
            OriginalItemSpec = dependencyModel.OriginalItemSpec ?? string.Empty;
            Path             = dependencyModel.Path ?? string.Empty;
            SchemaName       = dependencyModel.SchemaName ?? Folder.SchemaName;
            _schemaItemType  = dependencyModel.SchemaItemType ?? Folder.PrimaryDataSourceItemType;
            Resolved         = dependencyModel.Resolved;
            TopLevel         = dependencyModel.TopLevel;
            Implicit         = dependencyModel.Implicit;
            Visible          = dependencyModel.Visible;
            Priority         = dependencyModel.Priority;
            Flags            = dependencyModel.Flags;

            // Just in case custom providers don't do it, add corresponding flags for Resolved state.
            // This is needed for tree update logic to track if tree node changing state from unresolved
            // to resolved or vice-versa (it helps to decide if we need to remove it or update in-place
            // in the tree to avoid flicks).
            Flags += Resolved
                ? DependencyTreeFlags.ResolvedFlags
                : DependencyTreeFlags.UnresolvedFlags;

            // If this is one of our implementations of IDependencyModel then we can just reuse the icon
            // set rather than creating a new one.
            if (dependencyModel is Dependency dependency)
            {
                IconSet = dependency.IconSet;
            }
            else if (dependencyModel is DependencyModel model)
            {
                IconSet = model.IconSet;
            }
            else
            {
                IconSet = DependencyIconSetCache.Instance.GetOrAddIconSet(dependencyModel.Icon, dependencyModel.ExpandedIcon, dependencyModel.UnresolvedIcon, dependencyModel.UnresolvedExpandedIcon);
            }

            Properties = dependencyModel.Properties
                         ?? ImmutableStringDictionary <string> .EmptyOrdinal
                         .Add(Folder.IdentityProperty, Caption)
                         .Add(Folder.FullPathProperty, Path);

            if (dependencyModel.DependencyIDs == null || dependencyModel.DependencyIDs.Count == 0)
            {
                DependencyIDs = ImmutableList <string> .Empty;
            }
            else
            {
                int count = dependencyModel.DependencyIDs.Count;
                ImmutableArray <string> .Builder ids = ImmutableArray.CreateBuilder <string>(count);
                for (int i = 0; i < count; i++)
                {
                    ids.Add(GetID(TargetFramework, ProviderType, dependencyModel.DependencyIDs[i]));
                }
                DependencyIDs = ids.MoveToImmutable();
            }
        }
 public void IncludeRemovedChange(IDependencyModel model)
 {
     Removed.Add(model);
 }
 public static DependencyId GetDependencyId(this IDependencyModel self)
 {
     return(new DependencyId(self.ProviderType, self.Id));
 }
Example #31
0
        /// <summary>
        /// When some other project's snapshot changed we need to check if our snapshot has a top level
        /// dependency on changed project. If it does we need to refresh those top level dependencies to
        /// reflect changes.
        /// </summary>
        /// <param name="otherProjectSnapshot"></param>
        /// <param name="shouldBeResolved">
        /// Specifies if top-level project dependencies resolved status. When other project just had it's dependencies
        /// changed, it is resolved=true (we check target's support when we add project dependencies). However when
        /// other project is unloaded, we should mark top-level dependencies as unresolved.
        /// </param>
        private void OnOtherProjectDependenciesChanged(IDependenciesSnapshot otherProjectSnapshot, bool shouldBeResolved)
        {
            IDependenciesSnapshot projectSnapshot = SnapshotProvider.CurrentSnapshot;

            if (otherProjectSnapshot == null || projectSnapshot == null || projectSnapshot.Equals(otherProjectSnapshot))
            {
                // if any of the snapshots is not provided or this is the same project - skip
                return;
            }

            string otherProjectPath = otherProjectSnapshot.ProjectPath;

            var dependencyThatNeedChange = new List <IDependency>();

            foreach (KeyValuePair <ITargetFramework, ITargetedDependenciesSnapshot> target in projectSnapshot.Targets)
            {
                foreach (IDependency dependency in target.Value.TopLevelDependencies)
                {
                    // We're only interested in project dependencies
                    if (!StringComparers.DependencyProviderTypes.Equals(dependency.ProviderType, ProviderTypeString))
                    {
                        continue;
                    }

                    if (!StringComparers.Paths.Equals(otherProjectPath, dependency.FullPath))
                    {
                        continue;
                    }

                    dependencyThatNeedChange.Add(dependency);
                    break;
                }
            }

            if (dependencyThatNeedChange.Count == 0)
            {
                // we don't have dependency on updated project
                return;
            }

            foreach (IDependency dependency in dependencyThatNeedChange)
            {
                IDependencyModel model = CreateDependencyModel(
                    ProviderType,
                    dependency.Path,
                    dependency.OriginalItemSpec,
                    shouldBeResolved,
                    dependency.Implicit,
                    dependency.Properties);

                var changes = new DependenciesChanges();

                // avoid unnecessary removing since, add would upgrade dependency in snapshot anyway,
                // but remove would require removing item from the tree instead of in-place upgrade.
                if (!shouldBeResolved)
                {
                    changes.IncludeRemovedChange(model);
                }

                changes.IncludeAddedChange(model);

                FireDependenciesChanged(
                    new DependenciesChangedEventArgs(
                        this,
                        dependency.TargetFramework.FullName,
                        changes,
                        catalogs: null,
                        dataSourceVersions: null));
            }
        }