/// <summary>
        /// Gets the rule(s) that applies to a reference.
        /// </summary>
        /// <param name="itemType">The item type on the unresolved reference.</param>
        /// <param name="resolved">
        /// A value indicating whether to return rules for resolved or unresolved reference state.
        /// </param>
        /// <param name="namedCatalogs">The dictionary of catalogs.</param>
        /// <returns>The sequence of matching rules.  Hopefully having exactly one element.</returns>
        private IEnumerable <Rule> GetSchemaForReference(string itemType,
                                                         bool resolved,
                                                         IImmutableDictionary <string, IPropertyPagesCatalog> namedCatalogs)
        {
            Requires.NotNull(namedCatalogs, nameof(namedCatalogs));

            // Note: usually for default/generic dependencies we have sets of 2 rule schemas:
            //  - rule for unresolved dependency, they persist in ProjectFile
            //  - rule for resolved dependency, they persist in ResolvedReference
            // So to be able to find rule for resolved or unresolved reference we need to be consistent there
            // and make sure we do set ResolvedReference persistense for resolved dependnecies, since we rely
            // on that here when pick correct rule schema.
            // (old code used to check if rule datasource has SourceType=TargetResults, which was true for Resolved,
            // dependencies. However now we have custom logic for collecting unresolved dependencies too and use
            // DesignTime build results there too. Thats why we swicthed to check for persistence).
            IPropertyPagesCatalog        browseObjectCatalog = namedCatalogs[PropertyPageContexts.BrowseObject];
            IReadOnlyCollection <string> schemas             = browseObjectCatalog.GetPropertyPagesSchemas(itemType);

            return(from schemaName in browseObjectCatalog.GetPropertyPagesSchemas(itemType)
                   let schema = browseObjectCatalog.GetSchema(schemaName)
                                where schema.DataSource != null &&
                                string.Equals(itemType, schema.DataSource.ItemType, StringComparison.OrdinalIgnoreCase) &&
                                (resolved == string.Equals(schema.DataSource.Persistence,
                                                           RuleDataSourceTypes.PersistenceResolvedReference,
                                                           StringComparison.OrdinalIgnoreCase))
                                select schema);
        }
        public async Task <IRule> GetRuleAsync(IDependency dependency, IProjectCatalogSnapshot catalogs)
        {
            Requires.NotNull(dependency, nameof(dependency));

            ConfiguredProject project = null;

            if (dependency.TargetFramework.Equals(TargetFramework.Any))
            {
                project = ActiveConfiguredProject;
            }
            else
            {
                project = await DependenciesHost.GetConfiguredProject(dependency.TargetFramework)
                          .ConfigureAwait(false) ?? ActiveConfiguredProject;
            }

            ConfiguredProjectExports configuredProjectExports = GetActiveConfiguredProjectExports(project);
            IImmutableDictionary <string, IPropertyPagesCatalog> namedCatalogs = await GetNamedCatalogsAsync(catalogs).ConfigureAwait(false);

            Requires.NotNull(namedCatalogs, nameof(namedCatalogs));

            IPropertyPagesCatalog browseObjectsCatalog = namedCatalogs[PropertyPageContexts.BrowseObject];
            Rule   schema   = browseObjectsCatalog.GetSchema(dependency.SchemaName);
            string itemSpec = string.IsNullOrEmpty(dependency.OriginalItemSpec) ? dependency.Path : dependency.OriginalItemSpec;
            var    context  = ProjectPropertiesContext.GetContext(UnconfiguredProject,
                                                                  itemType: dependency.SchemaItemType,
                                                                  itemName: itemSpec);

            IRule rule = null;

            if (schema != null)
            {
                if (dependency.Resolved)
                {
                    rule = configuredProjectExports.RuleFactory.CreateResolvedReferencePageRule(
                        schema,
                        context,
                        dependency.Name,
                        dependency.Properties);
                }
                else
                {
                    rule = browseObjectsCatalog.BindToContext(schema.Name, context);
                }
            }
            else
            {
                // Since we have no browse object, we still need to create *something* so
                // that standard property pages can pop up.
                Rule emptyRule = RuleExtensions.SynthesizeEmptyRule(context.ItemType);
                return(configuredProjectExports.PropertyPagesDataModelProvider.GetRule(
                           emptyRule,
                           context.File,
                           context.ItemType,
                           context.ItemName));
            }

            return(rule);
        }
 public static IEnumerable <Rule> GetDebugChildRules(IPropertyPagesCatalog projectCatalog)
 {
     foreach (string schemaName in projectCatalog.GetPropertyPagesSchemas(itemType: "LaunchProfile"))
     {
         if (projectCatalog.GetSchema(schemaName) is { PropertyPagesHidden: false, PageTemplate: CommandNameBasedDebuggerPageTemplate } possibleChildRule)
         {
             yield return(possibleChildRule);
         }
     }
 }
 public static IEnumerable <Rule> GetDebugChildRules(IPropertyPagesCatalog projectCatalog)
 {
     foreach (string schemaName in projectCatalog.GetProjectLevelPropertyPagesSchemas())
     {
         if (projectCatalog.GetSchema(schemaName) is Rule possibleChildRule &&
             !possibleChildRule.PropertyPagesHidden &&
             possibleChildRule.PageTemplate == CommandNameBasedDebuggerPageTemplate)
         {
             yield return(possibleChildRule);
         }
     }
 }
        public override async Task <string?> OnSetPropertyValueAsync(string propertyName, string unevaluatedPropertyValue, IProjectProperties defaultProperties, IReadOnlyDictionary <string, string>?dimensionalConditions = null)
        {
            ConfiguredProject?configuredProject = await _project.GetSuggestedConfiguredProjectAsync();

            IPropertyPagesCatalogProvider?catalogProvider = configuredProject?.Services.PropertyPagesCatalog;

            if (catalogProvider == null)
            {
                return(null);
            }

            IPropertyPagesCatalog catalog = await catalogProvider.GetCatalogAsync(PropertyPageContexts.Project);

            Rule?rule = catalog.GetSchema(unevaluatedPropertyValue);

            if (rule == null)
            {
                return(null);
            }

            if (rule.Metadata.TryGetValue("CommandName", out object pageCommandNameObj) &&
                pageCommandNameObj is string pageCommandName)
            {
                _projectThreadingService.RunAndForget(async() =>
                {
                    // Infinite timeout means this will not actually be null.
                    ILaunchSettings?launchSettings = await _launchSettingsProvider.WaitForFirstSnapshot(Timeout.Infinite);
                    Assumes.NotNull(launchSettings);

                    IWritableLaunchSettings writableLaunchSettings = launchSettings.ToWritableLaunchSettings();
                    IWritableLaunchProfile?activeProfile           = writableLaunchSettings.ActiveProfile;
                    if (activeProfile != null)
                    {
                        activeProfile.CommandName = pageCommandName;

                        await _launchSettingsProvider.UpdateAndSaveSettingsAsync(writableLaunchSettings.ToLaunchSettings());
                    }
                },
                                                      options: ForkOptions.HideLocks,
                                                      unconfiguredProject: _project);
            }

            return(null);
        }
        private async Task <string> GetPropertyValueAsync()
        {
            // Infinite timeout means this will not actually be null.
            ILaunchSettings?launchSettings = await _launchSettingsProvider.WaitForFirstSnapshot(Timeout.Infinite);

            Assumes.NotNull(launchSettings);

            string?commandName = launchSettings.ActiveProfile?.CommandName;

            if (commandName == null)
            {
                return(string.Empty);
            }

            ConfiguredProject?configuredProject = await _project.GetSuggestedConfiguredProjectAsync();

            IPropertyPagesCatalogProvider?catalogProvider = configuredProject?.Services.PropertyPagesCatalog;

            if (catalogProvider == null)
            {
                return(string.Empty);
            }

            IPropertyPagesCatalog catalog = await catalogProvider.GetCatalogAsync(PropertyPageContexts.Project);

            foreach (string schemaName in catalog.GetPropertyPagesSchemas())
            {
                Rule?rule = catalog.GetSchema(schemaName);
                if (rule != null &&
                    string.Equals(rule.PageTemplate, "CommandNameBasedDebugger", StringComparison.OrdinalIgnoreCase) &&
                    rule.Metadata.TryGetValue("CommandName", out object pageCommandNameObj) &&
                    pageCommandNameObj is string pageCommandName &&
                    pageCommandName.Equals(commandName))
                {
                    return(schemaName);
                }
            }

            return(string.Empty);
        }
            public async Task <ICollection <IEnumValue> > GetListedValuesAsync()
            {
                var catalogProvider = _configuredProject.Services.PropertyPagesCatalog;

                if (catalogProvider == null)
                {
                    return(Array.Empty <IEnumValue>());
                }

                IPropertyPagesCatalog catalog = await catalogProvider.GetCatalogAsync(PropertyPageContexts.Project);

                return((ICollection <IEnumValue>)catalog.GetPropertyPagesSchemas()
                       .Select(name => catalog.GetSchema(name))
                       .WhereNotNull()
                       .Where(rule => string.Equals(rule.PageTemplate, "Debugger", StringComparison.OrdinalIgnoreCase) &&
                              rule.Metadata.TryGetValue("CommandName", out object pageCommandNameObj))
                       .Select(rule => new PageEnumValue(new EnumValue
                {
                    Name = rule.Name,
                    DisplayName = rule.DisplayName
                }))
                       .ToArray <IEnumValue>());
            }
        public async Task <IRule> GetRuleAsync(IDependency dependency, IProjectCatalogSnapshot catalogs)
        {
            Requires.NotNull(dependency, nameof(dependency));

            ConfiguredProject project = dependency.TargetFramework.Equals(TargetFramework.Any)
                ? ActiveConfiguredProject
                : _dependenciesHost.GetConfiguredProject(dependency.TargetFramework) ?? ActiveConfiguredProject;

            IImmutableDictionary <string, IPropertyPagesCatalog> namedCatalogs = await GetNamedCatalogsAsync();

            Requires.NotNull(namedCatalogs, nameof(namedCatalogs));

            IPropertyPagesCatalog browseObjectsCatalog = namedCatalogs[PropertyPageContexts.BrowseObject];
            Rule   schema   = browseObjectsCatalog.GetSchema(dependency.SchemaName);
            string itemSpec = string.IsNullOrEmpty(dependency.OriginalItemSpec) ? dependency.Path : dependency.OriginalItemSpec;
            var    context  = ProjectPropertiesContext.GetContext(UnconfiguredProject,
                                                                  itemType: dependency.SchemaItemType,
                                                                  itemName: itemSpec);

            if (schema == null)
            {
                // Since we have no browse object, we still need to create *something* so
                // that standard property pages can pop up.
                Rule emptyRule = RuleExtensions.SynthesizeEmptyRule(context.ItemType);
                return(GetActiveConfiguredProjectExports(project).PropertyPagesDataModelProvider.GetRule(
                           emptyRule,
                           context.File,
                           context.ItemType,
                           context.ItemName));
            }

            if (dependency.Resolved)
            {
                return(GetActiveConfiguredProjectExports(project).RuleFactory.CreateResolvedReferencePageRule(
                           schema,
                           context,
                           dependency.Name,
                           dependency.Properties));
            }

            return(browseObjectsCatalog.BindToContext(schema.Name, context));

            async Task <IImmutableDictionary <string, IPropertyPagesCatalog> > GetNamedCatalogsAsync()
            {
                if (catalogs != null)
                {
                    return(catalogs.NamedCatalogs);
                }

                if (_namedCatalogs == null)
                {
                    // Note: it is unlikely that we end up here, however for cases when node providers
                    // getting their node data not from Design time build events, we might have OnDependenciesChanged
                    // event coming before initial design time build event updates NamedCatalogs in this class.
                    // Thus, just in case, explicitly request it here (GetCatalogsAsync will acquire a project read lock)
                    _namedCatalogs = await ActiveConfiguredProject.Services
                                     .PropertyPagesCatalog
                                     .GetCatalogsAsync(CancellationToken.None);
                }

                return(_namedCatalogs);
            }
        }