KEMBAR78
Exclude platform-specific items using metadata by tmeschter · Pull Request #6681 · dotnet/maui · GitHub
Skip to content

Conversation

@tmeschter
Copy link
Contributor

Description of Change

Currently the platform-specific files are included for every platform in the MSBuild evaluation, and then at build the _MauiRemovePlatformCompileItems target removes all these items and then adds back the ones for the current platform.

This works for an actual build but screws up VS, as the Project System doesn't properly handle a Compile item that is present in evaluation but removed during a build. The end result is that the platform-specific files are not actually treated as platform-specific, leading to a number of user-visible issues:

  1. Platform-specific files incorrectly show all target frameworks in the Nav Bar
  2. Spurious errors in the Error List
  3. Squiggles in the editor, unless the user changes the Nav Bar to the "correct" target framework
  4. Possibly they will not see actual errors in their code (e.g. if you use a Windows-only API in an Android-specific file, but the Nav Bar is set to Windows, you won't get an squiggle about that)
  5. The spurious errors block Hot Reload as the Language Service thinks the project is very broken and will not attempt to apply changes

To work around this problem the Project System will now check items for special metadata indicating that they should be ignored. If an item is marked with ExcludeFromCurrentConfiguration=true the Project System will pretend it does not exist in the evaluation data for the current build configuration. And as the file no longer exists in the evaluation data, it no longer matters that the Project System does not properly handle the removal in the target.

Here we mark all items under the Platforms folder with ExcludeFromCurrentConfiguration=true, and then mark the items corresponding to the current platform with ExcludeFromCurrentConfiguration=false. The _MauiRemovePlatformCompileItems target is also updated to remove items based on the metadata rather than the folder structure.

Issues Fixed

Note that these issues also require a corresponding change in the dotnet/project-system repo.

Fixes #4726.
Fixes #5294.

Currently the platform-specific files are included for every platform in the MSBuild evaluation, and then at build the  _MauiRemovePlatformCompileItems target removes _all_ these items and then adds back the ones for the current platform.

This works for an actual build but screws up VS, as the Project System doesn't properly handle a `Compile` item that is present in evaluation but removed during a build. The end result is that the platform-specific files are not actually treated as platform specific, leading to a number of user-visible issues:

1. Platform-specific files incorrectly show all target frameworks in the Nav Bar.
2. Spurious errors in the Error List.
3. Squiggles in the editor, unless the user changes the Nav Bar to the "correct" target framework.
4. Possibly they will not see actual errors in their code (e.g. if you use a Windows-only API in an Android-specific file, but the Nav Bar is set to Windows, you won't get an squiggle about that).
5. The spurious errors block Hot Reload as the Language Service thinks the project is very broken and will not attempt to apply changes.

To work around this problem the Project System will now check items for special metadata indicating that they should be ignored. If an item is marked as a "LimitedConfigurationFile" but _not_ marked as "IncludeInThisConfiguration" the Project System will pretend it does not exist in the current build configuration. And as the file no longer exists in the evaluation data, it no longer matters that the Project System does not properly handle the removal in the target.

Here we mark all items under the Platforms folder with "LimitedConfigurationFile", and then mark the items corresponding to the current platform with "IncludeInThisConfiguration". The _MauiRemovePlatformCompileItems is updated to remove items based on the metadata rather than the folder structure.
Rather than two properties, we can use one. First all platform-specific files are tagged with `ExcludeFromCurrentConfiguration=true`. Then we update the platform-specific files for the current platform with `ExcludeFromCurrentConfiguration=false`, and the _MauiRemovePlatformCompileItems target can just check the one property.
@Eilon
Copy link
Contributor

Eilon commented Apr 29, 2022

@tmeschter - could this also solve #6642 ? Or does this seem different?

@Eilon Eilon added the area-tooling XAML & C# Hot Reload, XAML Editor, Live Visual Tree, Live Preview, Debugging label Apr 29, 2022
@mattleibow
Copy link
Member

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 2 pipeline(s).

tmeschter added a commit to tmeschter/roslyn-project-system that referenced this pull request Apr 29, 2022
Related to [dotnet/maui dotnet#6681](dotnet/maui#6681).
Related to AB#1525249.

Currently MAUI includes platform-specific files are for every platform in the MSBuild evaluation, and then at build a target removes _all_ these items and then adds back the ones for the current platform.

This works for an actual build but screws up VS, as the Project System doesn't properly handle a `Compile` item that is present in evaluation but removed during a build. The end result is that the platform-specific files are not actually treated as platform-specific, leading to a number of user-visible issues:

1. Platform-specific files incorrectly show all target frameworks in the Nav Bar
2. Spurious errors in the Error List
3. Squiggles in the editor, unless the user changes the Nav Bar to the "correct" target framework
4. Possibly they will not see actual errors in their code (e.g. if you use a Windows-only API in an Android-specific file, but the Nav Bar is set to Windows, you won't get an squiggle about that)
5. The spurious errors block Hot Reload as the Language Service thinks the project is very broken and will not attempt to apply changes

With this change the Project System will now check items for special metadata indicating that they should be ignored. If an item is marked with `ExcludeFromCurrentConfiguration=true` the Project System will pretend it does not exist in the evaluation data for the current build configuration. And as the file no longer exists in the evaluation data, it no longer matters that the Project System does not properly handle the removal in the target.

See [dotnet/maui dotnet#6681](dotnet/maui#6681) for the related MAUI SDK changes that add the metadata to the appropriate items.
@tmeschter
Copy link
Contributor Author

@tmeschter - could this also solve #6642 ? Or does this seem different?

@Eilon I haven't tried it out, but I think it will fix that bug as a side effect. Previously _MauiRemovePlatformCompileItems would remove all the files under "Platforms" and then add the platform-specific ones back, and that latter step pulled the Platforms\Android\test.cs file back in. Now the target only removes items.

1. Collapse the `ItemGroup`s into one, and move the conditions down to individual `Compile` items.
2. Since we're in an `ItemGroup` we can use `$(TargetPlatformIdentifier)` rather than `$([MSBuild]::GetTargetPlatformIdentifier($(TargetFramework)))`.
Copy link
Member

@jonathanpeppers jonathanpeppers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes look OK.

@mattleibow @Redth do we need to manually test what happens if you use this inside VS with & without Tom's fixes in the Project System?

@mattleibow
Copy link
Member

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 2 pipeline(s).

@tmeschter
Copy link
Contributor Author

Anything further I can do here?

@mattleibow mattleibow merged commit 3a1dcdc into dotnet:main May 3, 2022
@mattleibow
Copy link
Member

I tested this in an old IDE:

Microsoft Visual Studio Enterprise 2022 (64-bit) - Preview
Version 17.2.0 Preview 3.0

And it all appears to be working as it previously was (still has all the TFMs in the dropdown):

  • moving files from one platform folder to another does not adjust the csproj
  • adding files to the platform folders does not adjust the csproj
  • building works for the csproj
  • intellisense works when selecting the correct tfm from the dropdown

@ThatGuyMike7
Copy link

#4931 #4726 This is still broken (in a completely new project). Getting error squiggles in XAML. Changing target framework does nothing.

The type 'maui:MauiWinUIApplication' was not found. Verify that you are not missing an assembly reference and that all referenced assemblies have been built.

@Eilon
Copy link
Contributor

Eilon commented Oct 7, 2022

@ThatGuyMike7 can you please file a new issue with references to the previous similar issues/PRs?

@github-actions github-actions bot locked and limited conversation to collaborators Dec 21, 2023
@samhouts samhouts added the fixed-in-6.0.300-rc.3 Look for this fix in 6.0.300-rc.3! label Aug 2, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-tooling XAML & C# Hot Reload, XAML Editor, Live Visual Tree, Live Preview, Debugging fixed-in-6.0.300-rc.3 Look for this fix in 6.0.300-rc.3!

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Invoke Platform Code Works For One Platform Only, But Flagged As Wrong For The Two Others New Maui solution, AppDelegate intellisense issues

6 participants