Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

List of missing properties #6720

Closed
10 of 32 tasks
tmeschter opened this issue Oct 29, 2020 · 1 comment
Closed
10 of 32 tasks

List of missing properties #6720

tmeschter opened this issue Oct 29, 2020 · 1 comment
Assignees
Labels
Feature-Project-Properties-Designer The new project property pages which replace the legacy AppDesigner Triage-Approved Reviewed and prioritized
Milestone

Comments

@tmeschter
Copy link
Contributor

tmeschter commented Oct 29, 2020

(For the list of properties requiring attention see #6907.)

We're missing the below property pages and/or properties from the new Project Properties Designer. Note that this is a list of everything we think is reasonable to consider, and so will contain both items that exist in the old property pages and new items.

@tmeschter tmeschter added the Feature-Project-Properties-Designer The new project property pages which replace the legacy AppDesigner label Oct 29, 2020
@jjmew jjmew added the Triage-Approved Reviewed and prioritized label Oct 29, 2020
@jjmew jjmew added this to the 16.9 milestone Oct 29, 2020
@drewnoakes drewnoakes modified the milestones: 16.9, 16.10 Feb 2, 2021
tmeschter added a commit to tmeschter/roslyn-project-system that referenced this issue Feb 18, 2021
Related to dotnet#6720.

### Background

The C# compiler provides a switch allowing the user to specify whether or not warnings _in general_ should be treated as errors. In addition to that, specific warnings can be treated as errors, or _blocked_ from being treated as errors. In the project file, these settings are stored in the `TreatWarningsAsErrors`, `WarningsAsErrors`, and `WarningsNotAsErrors` properties, respectively.

Currently, the project property pages only expose the first two of these. This change adds support for the third, `WarningsNotAsErrors`.

### Explanation

The first thing to note is that all we have to do to get the new control to show up in the UI *and* to get the property persisted to the right place in the project file is to add a new `StringProperty` element to BuildPropertyPage.xaml. The `Name` attribute uniquely identifies the property within the Build page, _and_ specifies the property name that is read and written in the project file.

Second, note the `VisibilityCondition` metadata on the new `WarningsNotAsErrors` and existing `WarningsAsErrors` property. We only want to show one or the other of these properties in the UI, not both. If warnings _in general_ are being treated as errors it makes sense to only show `WarningsNotAsErrors`; but if warnings are not being treated as errors then we should only show `WarningsAsErrors`. The `VisibilityCondition` contains an expression that controls whether or not the control should be displayed.

Before I get into specifics of the expressions implemented here, it is important to note that `TreatWarningsAsErrors`, `WarningsAsErrors`, and `WarningsNotAsErrors` are all configuration dependent properties. That is, their values could vary from one configuration to another, and so the property effectively has multiple values--one per configuration. There are also many configuration independent properties; these have at most one value.

We want the `WarningsAsErrors` control to show up if `TreatWarningsAsErrors` is false in _any_ configuration, and this is achieved with the following expression:

```
(has-evaluated-value "Build" "TreatWarningsAsErrors" "false")
```

This looks at all of the evaluated values of the `TreatWarningsAsErrors` property on the `Build` page and checks if any of them is "false"; if so, the overall expression evaluates to "true" and the control is displayed.

If the properties were configuration independent we could have gone with

```
(eq (evaluated "Build" "TreatWarningsAsErrors") "true")
```

to check if the evaluated value of TreatWarningsAsErrors is "true", or even just

```
(evaluated "Build" "TreatWarningsAsErrors")
```

Third, let's leave the .xaml file for the moment and look and the one piece of code, TreatWarningsAsErrorsValueProvider.cs. When the user toggles the value of `TreatWarningsAsErrors` we don't just want to hide or show `WarningsAsErrors` and/or `WarningsNotAsErrors`, we want to clear out the property values that no longer make sense. E.g., if we're setting `TreatWarningsAsErrors` to false, we can delete `WarningsNotAsErrors` entirely as it has no effect.

We accomplish this by implementing an `IInterceptingPropertyValueProvider` for `TreatWarningsAsErrors`. An intercepting value provider gets a chance to handle a property set before it is passed on for default handling; this allows it to manipulate the value or even other properties. It also has a chance to manipulate the values _read_ from the default handler before they are passed on to the property pages, but we don't need this ability here.

However, if the user toggles `TreatWarningsAsErrors` back and forth we don't want to permanently delete whatever values they had for the other two properties. Rather, we squirrel them away in `ITemporaryPropertyStorage` before deleting them, and restore the value from there when switching back.

Fourth, go back to the .xaml file and take a look at the `Rule.DataSource` entry at the top of the page. The `Persistence` attribute indicates that the property values will read from and written to the "ProjectFile" handler which, of course, reads and writes to the project file itself (as opposed to the .user file or some other .props or .targets file). However, as we want to intercept the `TreatWarningsAsErrors` property we update its `DataSource` entry to instead specify the "ProjectFileWithInterception" persistence handler. This handler runs the property through an applicable interceptors before handing it off to the "ProjectFile" handler. Without this, the TreatWarningsAsErrorsValueProvider would never be called.

Fifth and finally, note that the values of `WarningsAsErrors` and `WarningsNotAsErrors` now depend on the value of `TreatWarningsAsErrors`. We need to tell the UI that when `TreatWarningsAsErrors` is updated, it should re-query the values of the other two. This is done via the `DependsOn` metadata added to both of those properties' entries. Without this, the UI may become out of sync with the actual values in the project as the user makes changes.
@drewnoakes drewnoakes modified the milestones: 16.10, 16.11 May 11, 2021
@melytc melytc added the Must-Have Items that must be delivered by the end of the assigned milestone label May 17, 2021
@drewnoakes drewnoakes removed the Must-Have Items that must be delivered by the end of the assigned milestone label May 19, 2021
@drewnoakes
Copy link
Member

Remaining items have been split out into separate issues. Closing this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature-Project-Properties-Designer The new project property pages which replace the legacy AppDesigner Triage-Approved Reviewed and prioritized
Projects
None yet
Development

No branches or pull requests

4 participants