Merge branch 'main' into net8.0-main

# Conflicts:
#	eng/Version.Details.xml
#	eng/Versions.props
This commit is contained in:
Rui Marinho 2023-01-09 16:15:55 +00:00
Родитель 1165fa04fb 91f76a6cd4
Коммит 6979dd1761
374 изменённых файлов: 6551 добавлений и 8785 удалений

279
.github/DEVELOPMENT.md поставляемый
Просмотреть файл

@ -4,130 +4,29 @@ This page contains steps to build and run the .NET MAUI repository from source.
## Requirements
### .NET 6 SDK
In most cases, when you have Visual Studio installed with the .NET workloads checked, these steps are not required.
1. Install the latest .NET 6:
<!--- [Win (x64)](https://aka.ms/dotnet/6.0.2xx/daily/dotnet-sdk-win-x64.exe) -->
- [Install the latest Public Preview of Visual Studio](https://docs.microsoft.com/en-us/dotnet/maui/get-started/installation/)
- [macOS](https://dotnet.microsoft.com/en-us/download/dotnet/6.0)
2. If you're on a Windows development machine, install [SDK 20348](https://go.microsoft.com/fwlink/?linkid=2164145)
3. If you're on a MacOS development machine, install [PowerShell](https://docs.microsoft.com/powershell/scripting/install/installing-powershell-on-macos)
### Visual Studio
Follow the instructions here to install .NET MAUI with Visual Studio Stable:
- [Windows](https://learn.microsoft.com/dotnet/maui/get-started/installation?tabs=vswin)
- Select the 20348 SDK option inside Individual Components or [install 20348 manually](https://go.microsoft.com/fwlink/?linkid=2164145)
- If you know you have 20348 installed but are still getting an error around this SDK missing, trying uninstalling and reinstalling the SDK.
- [macOS](https://learn.microsoft.com/dotnet/maui/get-started/installation?tabs=vsmac)
### iOS / MacCatalyst
iOS and MacCatalyst will require Xcode 13.3 Stable. You can get this [here](https://developer.apple.com/download/more/?name=Xcode).
iOS and MacCatalyst will require current stable Xcode. You can get this [here](https://developer.apple.com/download/more/?name=Xcode).
### Android
Android API-31 (Android 12) is now the default in .NET 6.
If you're missing any of the Android SDKs, Visual Studio should prompt you to install them. If it doesn't prompt you then use the [Android SDK Manager](https://learn.microsoft.com/xamarin/android/get-started/installation/android-sdk) to install the necessary SDKs.
## Running
### Compile using a local `bin\dotnet`
This method ensures that the workloads installed by Visual Studio won't get changed. This is usually the best method to use if you want to preserve the global state of your machine. This method will also use the versions that are specific to the branch you are on which is a good way to ensure compatibility.
#### Cake
You can run a `Cake` target to bootstrap .NET 6 in `bin\dotnet` and launch Visual Studio:
```dotnetcli
dotnet tool restore
dotnet cake --target=VS
```
#### Testing branch against your project
`--sln=<Path to SLN>`
- This will pack .NET and then open a VS instance using the local pack. This is useful if you want to check to see if the changes in a branch will address your particular issues. Pack only runs the first time so you will need to explicitly add the `--pack` flag if you make changes and need to repack.
```dotnetcli
dotnet tool restore
dotnet cake --sln="<download_directory>\MauiApp2\MauiApp2.sln" --target=VS
```
#### Pack
`--pack`
- This creates .NET MAUI packs inside the local dotnet install. This lets you use the CLI commands with the local dotnet to create/deploy with any changes that have been made on that branch (including template changes).
```dotnetcli
dotnet tool restore
dotnet cake --target=VS --pack --sln="<download_directory>\MauiApp2\MauiApp2.sln"
```
Create new .NET MAUI app using your new packs
```dotnetcli
dotnet tool restore
dotnet cake --pack
mkdir MyMauiApp
cd MyMauiApp
..\bin\dotnet\dotnet new maui
..\bin\dotnet\dotnet build -t:Run -f net6.0-android
```
You can also run commands individually:
```dotnetcli
# install local tools required to build (cake, pwsh, etc..)
dotnet tool restore
# Provision .NET 6 in bin\dotnet
dotnet build src\DotNet\DotNet.csproj
# Builds Maui MSBuild tasks
.\bin\dotnet\dotnet build Microsoft.Maui.BuildTasks.slnf
# Builds the rest of Maui
.\bin\dotnet\dotnet build Microsoft.Maui.sln
# Launch Visual Studio
dotnet cake --target=VS
```
### Compile with globally installed `dotnet`
- Try this first. This will build using the workloads installed by VS. If you receive a build failure related to workloads we recommend using a [local dotnet build](https://github.com/dotnet/maui/blob/main/.github/DEVELOPMENT.md#compile-using-a-local-bindotnet). If you want to keep on this path, proceed to the next step and then try to run these commands again.
### Opening the Repository
```dotnetcli
dotnet tool restore
dotnet cake --target=VS --workloads=global
```
- If you need/want to update your global workloads to the latest workloads.
> **Warning**
> This will replace what Visual Studio has installed for your workloads so now your entire machine will be using the workloads you have installed here.
#### main branch
> You'll probably need to run these commands with elevated privileges.
> **Warning**
> This is going to contain the "stable" versions of the packages, so you will have to clear the NuGet cache when this feed changes and when .NET ships. The various `darc-pub-dotnet-*` feeds are temporary and are generated on various builds. These feeds may disappear and be replaced with new ones as new builds come out. Make sure to verify that you are on the latest here and clear the nuget cache if it changes.
> ```
> dotnet nuget locals all --clear
> ```
Windows:
```bat
dotnet workload install maui `
--skip-sign-check `
--from-rollback-file https://aka.ms/dotnet/maui/net6.0.json `
--source https://pkgs.dev.azure.com/dnceng/public/_packaging/darc-pub-dotnet-runtime-531f715f/nuget/v3/index.json `
--source https://pkgs.dev.azure.com/dnceng/public/_packaging/darc-pub-dotnet-emsdk-3f6c45a2/nuget/v3/index.json `
--source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet6/nuget/v3/index.json `
--source https://api.nuget.org/v3/index.json
```
MacOS:
```bash
dotnet workload install maui \
--skip-sign-check \
--from-rollback-file https://aka.ms/dotnet/maui/net6.0.json \
--source https://pkgs.dev.azure.com/dnceng/public/_packaging/darc-pub-dotnet-runtime-531f715f/nuget/v3/index.json \
--source https://pkgs.dev.azure.com/dnceng/public/_packaging/darc-pub-dotnet-emsdk-3f6c45a2/nuget/v3/index.json \
--source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet6/nuget/v3/index.json \
--source https://api.nuget.org/v3/index.json
```
*NOTE*: Intellisense takes a decent amount of time to fully process your solution. It will eventually work through all the necessary tasks. If you are having intellisense issues, usually unloading/reloading the `maui.core` and `maui.controls` projects will resolve.
#### MacOS
@ -135,53 +34,10 @@ All of the above cake commands should work fine on `MacOS`.
If you aren't using the cake scripts and the `Microsoft.Maui-mac.slnf` isn't working for you try `_omnisharp.sln`
### Additional Cake Commands
#### Clean
`--clean`
- This will do a recursive delete of all your obj/bin folders. This is helpful if for some reason your repository is in a bad state and you don't want to go as scorched earth as `git clean -xdf`
### Blazor Desktop
To build and run Blazor Desktop samples, check out the [Blazor Desktop](https://github.com/dotnet/maui/wiki/Blazor-Desktop) wiki topic.
### Android
To workaround a performance issue, all `Resource.designer.cs`
generation is disabled for class libraries in this repo.
If you need to add a new `@(AndroidResource)` value to be used from C#
code in .NET MAUI:
1. Comment out the `<PropertyGroup>` in `Directory.Build.targets` that
sets `$(AndroidGenerateResourceDesigner)` and
`$(AndroidUseIntermediateDesignerFile)` to `false`.
2. Build .NET MAUI as you normally would. You will get compiler errors
about duplicate fields, but `obj\Debug\net6.0-android\Resource.designer.cs`
should now be generated.
3. Open `obj\Debug\net6.0-android\Resource.designer.cs`, and find the
field you need such as:
```csharp
// aapt resource value: 0x7F010000
public static int foo = 2130771968;
```
4. Copy this field to the `Resource.designer.cs` checked into source
control, such as: `src\Controls\src\Core\Platform\Android\Resource.designer.cs`
5. Restore the commented code in `Directory.Build.targets`.
## What branch should I use?
- main
- net7.0
- I want to use the net7.0 sdk and make changes that will be released with the .NET 7 release of MAUI
- net6.0
- This PR seems like it should go out with a net6.0 service release
- main (start here if you don't know what to use)
- I want to use the net6.0 sdk and make changes that will be released with the .NET 7 release of MAUI
Always use main no matter what you are working on or where you are hoping your change will get applied. We make sure that main always works against the current stable releases of Visual Studio and the .NET MAUI SDK. Even if you are working on features that will only be released with a future version of .NET. `main` is the only relevant branch for current development.
## Repository projects
@ -244,6 +100,117 @@ These are tests that will not run on a device. This is useful for testing device
│ │ ├── Essentials.UnitTests
```
### Additional Cake Commands
#### Clean
`--clean`
- This will do a recursive delete of all your obj/bin folders. This is helpful if for some reason your repository is in a bad state and you don't want to go as scorched earth as `git clean -xdf`
#### Target a specific platform
`--android`
`--ios`
`--windows`
`--catalyst`
```bash
dotnet cake --target=VS --workloads=global --android --ios
```
*Note* you will have to `git clean -xdf` your project if you change or add platforms.
### Blazor Desktop
To build and run Blazor Desktop samples, check out the [Blazor Desktop](https://github.com/dotnet/maui/wiki/Blazor-Desktop) wiki topic.
### Android
To workaround a performance issue, all `Resource.designer.cs`
generation is disabled for class libraries in this repo.
If you need to add a new `@(AndroidResource)` value to be used from C#
code in .NET MAUI:
1. Comment out the `<PropertyGroup>` in `Directory.Build.targets` that
sets `$(AndroidGenerateResourceDesigner)` and
`$(AndroidUseIntermediateDesignerFile)` to `false`.
2. Build .NET MAUI as you normally would. You will get compiler errors
about duplicate fields, but `obj\Debug\net[current_sdk_version]-android\Resource.designer.cs`
should now be generated.
3. Open `obj\Debug\net[current_sdk_version]-android\Resource.designer.cs`, and find the
field you need such as:
```csharp
// aapt resource value: 0x7F010000
public static int foo = 2130771968;
```
4. Copy this field to the `Resource.designer.cs` checked into source
control, such as: `src\Controls\src\Core\Platform\Android\Resource.designer.cs`
5. Restore the commented code in `Directory.Build.targets`.
# Advanced Scenarios
### Compile using a local `bin\dotnet`
This method ensures that the workloads installed by Visual Studio won't get changed. This is usually the best method to use if you want to preserve the global state of your machine. This method will also use the versions that are specific to the branch you are on which is a good way to ensure compatibility.
#### Cake
You can run a `Cake` target to bootstrap .NET SDK in `bin\dotnet` and launch Visual Studio:
```dotnetcli
dotnet tool restore
dotnet cake --target=VS
```
#### Testing branch against your project
`--sln=<Path to SLN>`
- This will pack .NET and then open a VS instance using the local pack. This is useful if you want to check to see if the changes in a branch will address your particular issues. Pack only runs the first time so you will need to explicitly add the `--pack` flag if you make changes and need to repack.
```dotnetcli
dotnet tool restore
dotnet cake --sln="<download_directory>\MauiApp2\MauiApp2.sln" --target=VS
```
#### Pack
`--pack`
- This creates .NET MAUI packs inside the local dotnet install. This lets you use the CLI commands with the local dotnet to create/deploy with any changes that have been made on that branch (including template changes).
```dotnetcli
dotnet tool restore
dotnet cake --target=VS --pack --sln="<download_directory>\MauiApp2\MauiApp2.sln"
```
Create new .NET MAUI app using your new packs
```dotnetcli
dotnet tool restore
dotnet cake --pack
mkdir MyMauiApp
cd MyMauiApp
..\bin\dotnet\dotnet new maui
..\bin\dotnet\dotnet build -t:Run -f net[current_sdk_version]-android
```
You can also run commands individually:
```dotnetcli
# install local tools required to build (cake, pwsh, etc..)
dotnet tool restore
# Provision .NET SDK in bin\dotnet
dotnet build src\DotNet\DotNet.csproj
# Builds Maui MSBuild tasks
.\bin\dotnet\dotnet build Microsoft.Maui.BuildTasks.slnf
# Builds the rest of Maui
.\bin\dotnet\dotnet build Microsoft.Maui.sln
# Launch Visual Studio
dotnet cake --target=VS
```
## Stats
<img src="https://repobeats.axiom.co/api/embed/f917a77cbbdeee19b87fa1f2f932895d1df18b71.svg" />

11
.github/ISSUE_TEMPLATE/bug-report.yml поставляемый
Просмотреть файл

@ -44,17 +44,14 @@ body:
label: Version with bug
description: In what version do you see this issue? Run `dotnet workload list` to find your version.
options:
- 6.0 Release Candidate 2 or older
- 6.0 Release Candidate 3
- 6.0.312
- 6.0.400
- 6.0.408
- 6.0.419
- 6.0.424
- 6.0.486
- 7.0 Release Candidate 1
- 7.0 Release Candidate 2
- 7.0 (current)
- 8.0 previews
- Unknown/Other (please specify)
validations:
required: true
@ -64,15 +61,13 @@ body:
label: Last version that worked well
description: Is there a version on which this _did_ work? If yes, which one? If no or unknown, please select `Unknown/Other`. Run `dotnet workload list` to find your version.
options:
- 6.0 Release Candidate 2 or older
- 6.0 Release Candidate 3
- 6.0.312
- 6.0.400
- 6.0.408
- 6.0.419
- 6.0.424
- 7.0 Release Candidate 1
- 7.0 Release Candidate 2
- 7.0 (current)
- 8.0 previews
- Unknown/Other
validations:
required: true

Просмотреть файл

@ -6,7 +6,7 @@
<WindowsAppSDKSelfContained Condition=" '$(WindowsAppSDKSelfContained)' == '' and '$(WindowsPackageType)' == 'None' and '$(OutputType)' == 'WinExe' ">true</WindowsAppSDKSelfContained>
<WindowsAppSdkBootstrapInitialize Condition=" '$(WindowsAppSdkBootstrapInitialize)' == '' and '$(EnableMsixTooling)' == 'true' and '$(OutputType)' != 'WinExe' ">false</WindowsAppSdkBootstrapInitialize>
<PublishAppXPackage Condition=" '$(PublishAppXPackage)' == '' and '$(EnableMsixTooling)' == 'true' and '$(WindowsPackageType)' == 'MSIX' ">true</PublishAppXPackage>
<PublishReadyToRun Condition=" '$(Configuration)' == 'Release' and '$(PublishReadyToRun)' == '' ">true</PublishReadyToRun>
<PublishReadyToRun Condition=" '$(PublishReadyToRun)' == '' and '$(Configuration)' == 'Release' and '$(OutputType)' != '' and '$(OutputType)' != 'Library' ">true</PublishReadyToRun>
<_SingleProjectRIDRequired Condition="'$(OutputType)' == 'WinExe'">true</_SingleProjectRIDRequired>
<_SingleProjectRIDSpecified Condition="'$(RuntimeIdentifier)' != '' or '$(RuntimeIdentifiers)' != ''">true</_SingleProjectRIDSpecified>
</PropertyGroup>

Просмотреть файл

@ -143,6 +143,8 @@
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
<PackageVersion>$(DotNetVersionBand)-dev</PackageVersion>
<PackageOutputPath>$(MSBuildThisFileDirectory)artifacts</PackageOutputPath>
<LicenseFile>$(MSBuildThisFileDirectory)LICENSE.TXT</LicenseFile>
<PackageThirdPartyNoticesFile>$(MSBuildThisFileDirectory)THIRD-PARTY-NOTICES.TXT</PackageThirdPartyNoticesFile>
</PropertyGroup>
<!-- This target is replaced by GitInfo when restored. Allows Versions.targets to rely on it before restore. -->
<Target Name="GitVersion" />

Просмотреть файл

@ -78,4 +78,13 @@
-->
<Import Project="src\Workload\Microsoft.Maui.Sdk\Sdk\WinUI.Unpackaged.targets" Condition=" '$(WindowsPackageType)' == 'None' and '$(_MauiTargetPlatformIsWindows)' == 'True' " />
<!-- Packaging -->
<ItemGroup Condition="'$(IsPackable)' == 'true'">
<None Include="$(LicenseFile)"
PackagePath="$([System.IO.Path]::GetFileName('$(LicenseFile)'))"
Pack="true" />
<None Include="$(PackageThirdPartyNoticesFile)"
PackagePath="$([System.IO.Path]::GetFileName('$(PackageThirdPartyNoticesFile)'))"
Pack="true" />
</ItemGroup>
</Project>

Просмотреть файл

@ -47,6 +47,7 @@
"src\\Essentials\\test\\UnitTests\\Essentials.UnitTests.csproj",
"src\\Graphics\\src\\Graphics.Skia\\Graphics.Skia.csproj",
"src\\Graphics\\src\\Graphics\\Graphics.csproj",
"src\\Graphics\\tests\\DeviceTests\\Graphics.DeviceTests.csproj",
"src\\Graphics\\src\\Text.Markdig\\Graphics.Text.Markdig.csproj",
"src\\SingleProject\\Resizetizer\\src\\Resizetizer.csproj",
"src\\SingleProject\\Resizetizer\\test\\UnitTests\\Resizetizer.UnitTests.csproj",

Просмотреть файл

@ -255,6 +255,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Controls.Core.Design.UnitTe
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Core.DeviceTests.Shared", "src\Core\tests\DeviceTests.Shared\Core.DeviceTests.Shared.csproj", "{66CC98E3-6A1A-4C44-A23C-B575E82106EC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Graphics.DeviceTests", "src\Graphics\tests\DeviceTests\Graphics.DeviceTests.csproj", "{34969E49-FA6E-41BB-9813-5689BB14021E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -637,6 +639,12 @@ Global
{66CC98E3-6A1A-4C44-A23C-B575E82106EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{66CC98E3-6A1A-4C44-A23C-B575E82106EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{66CC98E3-6A1A-4C44-A23C-B575E82106EC}.Release|Any CPU.Build.0 = Release|Any CPU
{34969E49-FA6E-41BB-9813-5689BB14021E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{34969E49-FA6E-41BB-9813-5689BB14021E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{34969E49-FA6E-41BB-9813-5689BB14021E}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{34969E49-FA6E-41BB-9813-5689BB14021E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{34969E49-FA6E-41BB-9813-5689BB14021E}.Release|Any CPU.Build.0 = Release|Any CPU
{34969E49-FA6E-41BB-9813-5689BB14021E}.Release|Any CPU.Deploy.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -755,6 +763,7 @@ Global
{F351A992-18E4-473C-8ADD-2BA0BAA7B5A2} = {1BA0121E-0B83-4C8F-81BE-C293E7E35DCE}
{F68932B0-81A2-4CC3-A4F7-28091EE91B23} = {25D0D27A-C5FE-443D-8B65-D6C987F4A80E}
{66CC98E3-6A1A-4C44-A23C-B575E82106EC} = {C564DDD6-DE79-45CD-88EA-3F690481572A}
{34969E49-FA6E-41BB-9813-5689BB14021E} = {936C47A9-A7EA-4FBD-8733-CED1D4100E69}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {0B8ABEAD-D2B5-4370-A187-62B5ABE4EE50}

467
THIRD-PARTY-NOTICES.TXT Normal file
Просмотреть файл

@ -0,0 +1,467 @@
.NET MAUI uses third-party libraries or other resources that may be
distributed under licenses different than the .NET MAUI software.
Attributions and license notices for test cases originally authored by
third parties can be found in the respective test directories.
In the event that we accidentally failed to list a required notice, please
bring it to our attention. Post an issue or email us:
dotnet@microsoft.com
The attached notices are provided for information only.
License notice for Bootstrap
=========================================
The MIT License (MIT)
Copyright (c) 2011-2018 Twitter, Inc.
Copyright (c) 2011-2018 The Bootstrap Authors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
=========================================
License notice for Mono
=========================================
http://www.mono-project.com/docs/about-mono/
Copyright (c) .NET Foundation Contributors
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the Software), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
=========================================
License notice for Open Sans fonts
=========================================
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
Copyright 2020 The Open Sans Project Authors (https://github.com/googlefonts/opensans)
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font
creation efforts of academic and linguistic communities, and to
provide a free and open framework in which fonts may be shared and
improved in partnership with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply to
any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software
components as distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to,
deleting, or substituting -- in part or in whole -- any of the
components of the Original Version, by changing formats or by porting
the Font Software to a new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed,
modify, redistribute, and sell modified and unmodified copies of the
Font Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components, in
Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the
corresponding Copyright Holder. This restriction only applies to the
primary font name as presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created using
the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.
=========================================
License notice for Glide
=========================================
Copyright 2014 Google, Inc. All rights reserved. https://github.com/bumptech/glide
Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list
of conditions and the following disclaimer in the documentation and/or other materials
provided with the distribution.
THIS SOFTWARE IS PROVIDED BY GOOGLE, INC. ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE, INC. OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those of the
authors and should not be interpreted as representing official policies, either expressed
or implied, of Google, Inc.
=========================================
License notice for Open Iconic fonts
=========================================
SIL OPEN FONT LICENSE Version 1.1
Copyright (c) 2014 Waybury
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.
=========================================
License notice for Gradle (https://github.com/gradle/gradle)
=========================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
==============================================================================

Просмотреть файл

@ -9,8 +9,8 @@
Version="1.4.0.3"
/>
<PackageReference
Update="Xamarin.AndroidX.Legacy.Support.V4"
Version="1.0.0.15"
Update="Xamarin.AndroidX.SwipeRefreshLayout"
Version="1.1.0.10"
/>
<PackageReference
Update="Xamarin.AndroidX.Lifecycle.LiveData"

Просмотреть файл

@ -23,21 +23,21 @@
<MicrosoftNETWorkloadEmscriptennet7Manifest80100PackageVersion>8.0.0-alpha.1.22510.1</MicrosoftNETWorkloadEmscriptennet7Manifest80100PackageVersion>
<MicrosoftNETWorkloadEmscriptenPackageVersion>$(MicrosoftNETWorkloadEmscriptennet7Manifest80100PackageVersion)</MicrosoftNETWorkloadEmscriptenPackageVersion>
<!-- wasdk -->
<MicrosoftWindowsAppSDKPackageVersion>1.2.221116.1</MicrosoftWindowsAppSDKPackageVersion>
<MicrosoftWindowsAppSDKPackageVersion>1.2.221209.1</MicrosoftWindowsAppSDKPackageVersion>
<MicrosoftWindowsSDKBuildToolsPackageVersion>10.0.22621.755</MicrosoftWindowsSDKBuildToolsPackageVersion>
<MicrosoftGraphicsWin2DPackageVersion>1.0.4</MicrosoftGraphicsWin2DPackageVersion>
<!-- Everything else -->
<MicrosoftAspNetCoreAuthorizationPackageVersion>7.0.0</MicrosoftAspNetCoreAuthorizationPackageVersion>
<MicrosoftAspNetCoreAuthenticationFacebookPackageVersion>7.0.0</MicrosoftAspNetCoreAuthenticationFacebookPackageVersion>
<MicrosoftAspNetCoreAuthenticationGooglePackageVersion>7.0.0</MicrosoftAspNetCoreAuthenticationGooglePackageVersion>
<MicrosoftAspNetCoreAuthenticationMicrosoftAccountPackageVersion>7.0.0</MicrosoftAspNetCoreAuthenticationMicrosoftAccountPackageVersion>
<MicrosoftAspNetCoreComponentsAnalyzersPackageVersion>7.0.0</MicrosoftAspNetCoreComponentsAnalyzersPackageVersion>
<MicrosoftAspNetCoreComponentsFormsPackageVersion>7.0.0</MicrosoftAspNetCoreComponentsFormsPackageVersion>
<MicrosoftAspNetCoreComponentsPackageVersion>7.0.0</MicrosoftAspNetCoreComponentsPackageVersion>
<MicrosoftAspNetCoreComponentsWebPackageVersion>7.0.0</MicrosoftAspNetCoreComponentsWebPackageVersion>
<MicrosoftAspNetCoreComponentsWebViewPackageVersion>7.0.0</MicrosoftAspNetCoreComponentsWebViewPackageVersion>
<MicrosoftAspNetCoreMetadataPackageVersion>7.0.0</MicrosoftAspNetCoreMetadataPackageVersion>
<MicrosoftJSInteropPackageVersion>7.0.0</MicrosoftJSInteropPackageVersion>
<MicrosoftAspNetCoreAuthorizationPackageVersion>7.0.1</MicrosoftAspNetCoreAuthorizationPackageVersion>
<MicrosoftAspNetCoreAuthenticationFacebookPackageVersion>7.0.1</MicrosoftAspNetCoreAuthenticationFacebookPackageVersion>
<MicrosoftAspNetCoreAuthenticationGooglePackageVersion>7.0.1</MicrosoftAspNetCoreAuthenticationGooglePackageVersion>
<MicrosoftAspNetCoreAuthenticationMicrosoftAccountPackageVersion>7.0.1</MicrosoftAspNetCoreAuthenticationMicrosoftAccountPackageVersion>
<MicrosoftAspNetCoreComponentsAnalyzersPackageVersion>7.0.1</MicrosoftAspNetCoreComponentsAnalyzersPackageVersion>
<MicrosoftAspNetCoreComponentsFormsPackageVersion>7.0.1</MicrosoftAspNetCoreComponentsFormsPackageVersion>
<MicrosoftAspNetCoreComponentsPackageVersion>7.0.1</MicrosoftAspNetCoreComponentsPackageVersion>
<MicrosoftAspNetCoreComponentsWebPackageVersion>7.0.1</MicrosoftAspNetCoreComponentsWebPackageVersion>
<MicrosoftAspNetCoreComponentsWebViewPackageVersion>7.0.1</MicrosoftAspNetCoreComponentsWebViewPackageVersion>
<MicrosoftAspNetCoreMetadataPackageVersion>7.0.1</MicrosoftAspNetCoreMetadataPackageVersion>
<MicrosoftJSInteropPackageVersion>7.0.1</MicrosoftJSInteropPackageVersion>
<!-- Other packages -->
<MicrosoftCodeAnalysisNetAnalyzersVersion>7.0.0</MicrosoftCodeAnalysisNetAnalyzersVersion>
<MicrosoftCodeAnalysisPublicApiAnalyzersVersion>3.3.3</MicrosoftCodeAnalysisPublicApiAnalyzersVersion>

Просмотреть файл

@ -17,6 +17,7 @@ var NuGetOnlyPackages = new string[] {
"Microsoft.Maui.Graphics.*.nupkg",
"Microsoft.Maui.Controls.Maps.*.nupkg",
"Microsoft.Maui.Maps.*.nupkg",
"Microsoft.AspNetCore.Components.WebView.*.nupkg",
};
ProcessTFMSwitches();
@ -341,11 +342,22 @@ Task("dotnet-pack-docs")
{
foreach (var nupkg in GetFiles($"./artifacts/{pattern}"))
{
var d = $"{tempDir}/{nupkg.GetFilename()}";
var filename = nupkg.GetFilename().ToString();
var d = $"{tempDir}/{filename}";
Unzip(nupkg, d);
DeleteFiles($"{d}/**/*.pri");
DeleteFiles($"{d}/**/*.aar");
DeleteFiles($"{d}/**/*.pdb");
if (filename.StartsWith("Microsoft.AspNetCore.Components.WebView.Wpf")
|| filename.StartsWith("Microsoft.AspNetCore.Components.WebView.WindowsForms"))
{
CopyFiles($"{d}/lib/**/net?.?-windows?.?/**/*.dll", $"{destDir}");
CopyFiles($"{d}/lib/**/net?.?-windows?.?/**/*.xml", $"{destDir}");
continue;
}
CopyFiles($"{d}/lib/**/{{net,netstandard}}?.?/**/*.dll", $"{destDir}");
CopyFiles($"{d}/lib/**/{{net,netstandard}}?.?/**/*.xml", $"{destDir}");
}

Просмотреть файл

@ -8,9 +8,9 @@ variables:
- name: DOTNET_VERSION
value: 6.0.403
- name: REQUIRED_XCODE
value: 14.1.0
value: 14.2.0
- name: DEVICETESTS_REQUIRED_XCODE
value: 14.1.0
value: 14.2.0
- name: LocBranchPrefix
value: 'loc-hb'
- name: isMainBranch

Просмотреть файл

@ -101,6 +101,11 @@ stages:
androidApiLevelsExclude: [25] # Ignore for now API25 since the runs's are not stable
android: $(System.DefaultWorkingDirectory)/src/Essentials/test/DeviceTests/Essentials.DeviceTests.csproj
ios: $(System.DefaultWorkingDirectory)/src/Essentials/test/DeviceTests/Essentials.DeviceTests.csproj
- name: graphics
desc: Graphics
androidApiLevelsExclude: [25] # Ignore for now API25 since the runs's are not stable
android: $(System.DefaultWorkingDirectory)/src/Graphics/tests/DeviceTests/Graphics.DeviceTests.csproj
ios: $(System.DefaultWorkingDirectory)/src/Graphics/tests/DeviceTests/Graphics.DeviceTests.csproj
- name: core
desc: Core
androidApiLevelsExclude: [25] # Ignore for now API25 since the runs's are not stable

Просмотреть файл

@ -120,7 +120,7 @@ namespace Microsoft.AspNetCore.Components.WebView.Maui
}
}
_webviewManager.Navigate("/");
_webviewManager.Navigate(VirtualView.StartPath);
}
internal IFileProvider CreateFileProvider(string contentRootDir)

Просмотреть файл

@ -30,7 +30,21 @@ namespace Microsoft.AspNetCore.Components.WebView.Maui
/// </summary>
public string? HostPage { get; set; }
/// <inheritdoc />
/// <summary>
/// Bindable property for <see cref="StartPath"/>.
/// </summary>
public static readonly BindableProperty StartPathProperty = BindableProperty.Create(nameof(StartPath), typeof(string), typeof(BlazorWebView), "/");
/// <summary>
/// Gets or sets the path for initial navigation within the Blazor navigation context when the Blazor component is finished loading.
/// </summary>
public string StartPath
{
get { return (string)GetValue(StartPathProperty); }
set { SetValue(StartPathProperty, value); }
}
/// <inheritdoc cref="IBlazorWebView.RootComponents" />
public RootComponentsCollection RootComponents { get; }
/// <summary>

Просмотреть файл

@ -15,6 +15,15 @@ namespace Microsoft.AspNetCore.Components.WebView.Maui
/// </summary>
string? HostPage { get; }
/// <summary>
/// Gets or sets the path for initial navigation within the Blazor navigation context when the Blazor component is finished loading.
/// </summary>
public string StartPath
{
get => "/";
set => throw new NotImplementedException();
}
/// <summary>
/// Gets a collection of <see cref="RootComponent"/> items.
/// </summary>

Просмотреть файл

@ -1 +1,6 @@
#nullable enable
Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebView.StartPath.get -> string!
Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebView.StartPath.set -> void
Microsoft.AspNetCore.Components.WebView.Maui.IBlazorWebView.StartPath.get -> string!
Microsoft.AspNetCore.Components.WebView.Maui.IBlazorWebView.StartPath.set -> void
static readonly Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebView.StartPathProperty -> Microsoft.Maui.Controls.BindableProperty!

Просмотреть файл

@ -1 +1,6 @@
#nullable enable
Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebView.StartPath.get -> string!
Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebView.StartPath.set -> void
Microsoft.AspNetCore.Components.WebView.Maui.IBlazorWebView.StartPath.get -> string!
Microsoft.AspNetCore.Components.WebView.Maui.IBlazorWebView.StartPath.set -> void
static readonly Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebView.StartPathProperty -> Microsoft.Maui.Controls.BindableProperty!

Просмотреть файл

@ -1 +1,6 @@
#nullable enable
Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebView.StartPath.get -> string!
Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebView.StartPath.set -> void
Microsoft.AspNetCore.Components.WebView.Maui.IBlazorWebView.StartPath.get -> string!
Microsoft.AspNetCore.Components.WebView.Maui.IBlazorWebView.StartPath.set -> void
static readonly Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebView.StartPathProperty -> Microsoft.Maui.Controls.BindableProperty!

Просмотреть файл

@ -1 +1,6 @@
#nullable enable
Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebView.StartPath.get -> string!
Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebView.StartPath.set -> void
Microsoft.AspNetCore.Components.WebView.Maui.IBlazorWebView.StartPath.get -> string!
Microsoft.AspNetCore.Components.WebView.Maui.IBlazorWebView.StartPath.set -> void
static readonly Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebView.StartPathProperty -> Microsoft.Maui.Controls.BindableProperty!

Просмотреть файл

@ -1 +1,6 @@
#nullable enable
Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebView.StartPath.get -> string!
Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebView.StartPath.set -> void
Microsoft.AspNetCore.Components.WebView.Maui.IBlazorWebView.StartPath.get -> string!
Microsoft.AspNetCore.Components.WebView.Maui.IBlazorWebView.StartPath.set -> void
static readonly Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebView.StartPathProperty -> Microsoft.Maui.Controls.BindableProperty!

Просмотреть файл

@ -1 +1,6 @@
#nullable enable
Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebView.StartPath.get -> string!
Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebView.StartPath.set -> void
Microsoft.AspNetCore.Components.WebView.Maui.IBlazorWebView.StartPath.get -> string!
Microsoft.AspNetCore.Components.WebView.Maui.IBlazorWebView.StartPath.set -> void
static readonly Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebView.StartPathProperty -> Microsoft.Maui.Controls.BindableProperty!

Просмотреть файл

@ -9,10 +9,10 @@ namespace Microsoft.AspNetCore.Components.WebView.Maui
/// </summary>
public partial class BlazorWebViewHandler : ViewHandler<IBlazorWebView, object>
{
/// <inheritdoc />
/// <inheritdoc cref="Microsoft.Maui.Handlers.ViewHandler{TVirtualView, TPlatformView}.CreatePlatformView" />
protected override object CreatePlatformView() => throw new NotSupportedException();
/// <inheritdoc />
/// <inheritdoc cref="IBlazorWebView.CreateFileProvider" />
public virtual IFileProvider CreateFileProvider(string contentRootDir) => throw new NotSupportedException();
}
}

Просмотреть файл

@ -184,7 +184,7 @@ namespace Microsoft.AspNetCore.Components.WebView.Maui
_ = rootComponent.AddToWebViewManagerAsync(_webviewManager);
}
}
_webviewManager.Navigate("/");
_webviewManager.Navigate(VirtualView.StartPath);
}
internal IFileProvider CreateFileProvider(string contentRootDir)

Просмотреть файл

@ -83,7 +83,7 @@ namespace Microsoft.AspNetCore.Components.WebView.Maui
_ = rootComponent.AddToWebViewManagerAsync(_webviewManager);
}
}
_webviewManager.Navigate("/");
_webviewManager.Navigate(VirtualView.StartPath);
}
internal IFileProvider CreateFileProvider(string contentRootDir)

Просмотреть файл

@ -150,7 +150,7 @@ namespace Microsoft.AspNetCore.Components.WebView.Maui
}
}
_webviewManager.Navigate("/");
_webviewManager.Navigate(VirtualView.StartPath);
}
internal IFileProvider CreateFileProvider(string contentRootDir)

Просмотреть файл

@ -55,7 +55,7 @@ namespace Microsoft.AspNetCore.Components.WebView.WindowsForms
private WindowsFormsDispatcher ComponentsDispatcher { get; }
/// <inheritdoc />
/// <inheritdoc cref="Control.OnCreateControl" />
protected override void OnCreateControl()
{
base.OnCreateControl();
@ -79,6 +79,13 @@ namespace Microsoft.AspNetCore.Components.WebView.WindowsForms
}
}
/// <summary>
/// Path for initial Blazor navigation when the Blazor component is finished loading.
/// </summary>
[Category("Behavior")]
[Description(@"Path for initial Blazor navigation when the Blazor component is finished loading.")]
public string StartPath { get; set; } = "/";
// Learn more about these methods here: https://docs.microsoft.com/en-us/dotnet/desktop/winforms/controls/defining-default-values-with-the-shouldserialize-and-reset-methods?view=netframeworkdesktop-4.8
private void ResetHostPage() => HostPage = null;
private bool ShouldSerializeHostPage() => !string.IsNullOrEmpty(HostPage);
@ -193,7 +200,7 @@ namespace Microsoft.AspNetCore.Components.WebView.WindowsForms
// Since the page isn't loaded yet, this will always complete synchronously
_ = rootComponent.AddToWebViewManagerAsync(_webviewManager);
}
_webviewManager.Navigate("/");
_webviewManager.Navigate(StartPath);
}
private void HandleRootComponentsCollectionChanged(object? sender, NotifyCollectionChangedEventArgs eventArgs)
@ -243,7 +250,7 @@ namespace Microsoft.AspNetCore.Components.WebView.WindowsForms
}
}
/// <inheritdoc />
/// <inheritdoc cref="Control.Dispose(bool)" />
protected override void Dispose(bool disposing)
{
if (disposing)
@ -261,7 +268,7 @@ namespace Microsoft.AspNetCore.Components.WebView.WindowsForms
base.Dispose(disposing);
}
/// <inheritdoc />
/// <inheritdoc cref="Control.CreateControlsInstance" />
protected override ControlCollection CreateControlsInstance()
{
return new BlazorWebViewControlCollection(this);

Просмотреть файл

@ -1 +1,3 @@
#nullable enable
Microsoft.AspNetCore.Components.WebView.WindowsForms.BlazorWebView.StartPath.get -> string!
Microsoft.AspNetCore.Components.WebView.WindowsForms.BlazorWebView.StartPath.set -> void

Просмотреть файл

@ -32,6 +32,15 @@ namespace Microsoft.AspNetCore.Components.WebView.Wpf
ownerType: typeof(BlazorWebView),
typeMetadata: new PropertyMetadata(OnHostPagePropertyChanged));
/// <summary>
/// The backing store for the <see cref="StartPath"/> property.
/// </summary>
public static readonly DependencyProperty StartPathProperty = DependencyProperty.Register(
name: nameof(StartPath),
propertyType: typeof(string),
ownerType: typeof(BlazorWebView),
typeMetadata: new PropertyMetadata("/"));
/// <summary>
/// The backing store for the <see cref="RootComponent"/> property.
/// </summary>
@ -129,6 +138,15 @@ namespace Microsoft.AspNetCore.Components.WebView.Wpf
set => SetValue(HostPageProperty, value);
}
/// <summary>
/// Path for initial Blazor navigation when the Blazor component is finished loading.
/// </summary>
public string StartPath
{
get => (string)GetValue(StartPathProperty);
set => SetValue(StartPathProperty, value);
}
/// <summary>
/// A collection of <see cref="RootComponent"/> instances that specify the Blazor <see cref="IComponent"/> types
/// to be used directly in the specified <see cref="HostPage"/>.
@ -197,7 +215,7 @@ namespace Microsoft.AspNetCore.Components.WebView.Wpf
HostPage != null &&
Services != null;
/// <inheritdoc />
/// <inheritdoc cref="FrameworkElement.OnApplyTemplate" />
public override void OnApplyTemplate()
{
CheckDisposed();
@ -212,7 +230,7 @@ namespace Microsoft.AspNetCore.Components.WebView.Wpf
}
}
/// <inheritdoc />
/// <inheritdoc cref="FrameworkElement.OnInitialized(EventArgs)" />
protected override void OnInitialized(EventArgs e)
{
// Called when BeginInit/EndInit are used, such as when creating the control from XAML
@ -267,7 +285,7 @@ namespace Microsoft.AspNetCore.Components.WebView.Wpf
// Since the page isn't loaded yet, this will always complete synchronously
_ = rootComponent.AddToWebViewManagerAsync(_webviewManager);
}
_webviewManager.Navigate("/");
_webviewManager.Navigate(StartPath);
}
private WpfDispatcher ComponentsDispatcher { get; }

Просмотреть файл

@ -1 +1,4 @@
#nullable enable
Microsoft.AspNetCore.Components.WebView.Wpf.BlazorWebView.StartPath.get -> string!
Microsoft.AspNetCore.Components.WebView.Wpf.BlazorWebView.StartPath.set -> void
static readonly Microsoft.AspNetCore.Components.WebView.Wpf.BlazorWebView.StartPathProperty -> System.Windows.DependencyProperty!

Просмотреть файл

@ -12,7 +12,6 @@
<ItemGroup>
<PackageReference Include="Xamarin.Firebase.AppIndexing" Version="120.0.0.10" />
<PackageReference Include="Xamarin.AndroidX.Lifecycle.LiveData" />
<PackageReference Include="Xamarin.AndroidX.Legacy.Support.V4" />
</ItemGroup>
<ItemGroup>

Просмотреть файл

@ -40,7 +40,6 @@
<PackageReference Include="Xamarin.Build.Download" />
<PackageReference Include="Xamarin.AndroidX.Lifecycle.LiveData" />
<PackageReference Include="Xamarin.AndroidX.Browser" />
<PackageReference Include="Xamarin.AndroidX.Legacy.Support.V4" />
<PackageReference Include="Xamarin.AndroidX.Palette" />
<PackageReference Include="Xamarin.Google.Android.Material" />
</ItemGroup>

Просмотреть файл

@ -3,7 +3,6 @@
<PackageReference Include="Xamarin.AndroidX.Browser" />
<PackageReference Include="Xamarin.AndroidX.Palette" />
<PackageReference Include="Xamarin.AndroidX.Lifecycle.LiveData" />
<PackageReference Include="Xamarin.AndroidX.Legacy.Support.V4" />
<PackageReference Include="Xamarin.Google.Android.Material" />
</ItemGroup>
<Import Project="..\..\..\..\..\eng\AndroidX.targets" />

Просмотреть файл

@ -1,15 +1,9 @@
using System;
using Android.App;
using Android.OS;
#if __ANDROID_29__
using AndroidX.Fragment.App;
using Fragment = AndroidX.Fragment.App.Fragment;
using FragmentTransaction = AndroidX.Fragment.App.FragmentTransaction;
#else
using Android.Support.V4.App;
using Fragment = Android.Support.V4.App.Fragment;
using FragmentTransaction = Android.Support.V4.App.FragmentTransaction;
#endif
using Android.Views;
using Embedding.XF;
using Xamarin.Forms;

Просмотреть файл

@ -1,15 +1,9 @@
using System;
using Android.App;
using Android.OS;
#if __ANDROID_29__
using AndroidX.Fragment.App;
using Fragment = AndroidX.Fragment.App.Fragment;
using FragmentTransaction = AndroidX.Fragment.App.FragmentTransaction;
#else
using Android.Support.V4.App;
using Fragment = Android.Support.V4.App.Fragment;
using FragmentTransaction = Android.Support.V4.App.FragmentTransaction;
#endif
using Android.Views;
using Embedding.XF;
using Xamarin.Forms.Platform.Android;

Просмотреть файл

@ -16,7 +16,7 @@
<ItemGroup>
<PackageReference Include="Appium.WebDriver" Version="4.3.1" />
<PackageReference Include="Castle.Core" Version="5.1.0" />
<PackageReference Include="Castle.Core" Version="5.1.1" />
<PackageReference Include="DotNetSeleniumExtras.PageObjects" Version="3.11.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="NUnit" Version="3.13.3" />

Просмотреть файл

@ -11,7 +11,6 @@
<ItemGroup>
<PackageReference Include="Xamarin.AndroidX.Lifecycle.LiveData" />
<PackageReference Include="Xamarin.Google.Android.Material" />
<PackageReference Include="Xamarin.AndroidX.Legacy.Support.V4" />
<PackageReference Include="Xamarin.GooglePlayServices.Maps" Version="118.1.0" />
</ItemGroup>

Просмотреть файл

@ -32,7 +32,6 @@
<ItemGroup Condition=" '$(UseMaui)' != 'true' and '$(TargetPlatformIdentifier)' == 'android' ">
<PackageReference Include="Xamarin.AndroidX.Lifecycle.LiveData" />
<PackageReference Include="Xamarin.Google.Android.Material" />
<PackageReference Include="Xamarin.AndroidX.Legacy.Support.V4" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetPlatformIdentifier)' == 'android' ">
<PackageReference Include="Xamarin.AndroidX.Window.WindowJava" />

Просмотреть файл

@ -5,79 +5,92 @@
xmlns:views="clr-namespace:Maui.Controls.Sample.Pages.Base"
Title="Frame">
<views:BasePage.Content>
<VerticalStackLayout
Margin="12">
<Label
Text="Default"
Style="{StaticResource Headline}"/>
<Frame
BackgroundColor="LightGray"
HasShadow="False">
<Label
Text="Only with BackgroundColor" />
</Frame>
<Label
Text="Background"
Style="{StaticResource Headline}"/>
<Frame>
<Frame.Background>
<LinearGradientBrush EndPoint="1,0">
<GradientStop Color="Yellow"
Offset="0.1" />
<GradientStop Color="Green"
Offset="1.0" />
</LinearGradientBrush>
</Frame.Background>
<Label
Text="Background" />
</Frame>
<Label
Text="BorderColor"
Style="{StaticResource Headline}"/>
<Frame
BackgroundColor="LightGray"
BorderColor="Red"
HasShadow="False">
<Label
Text="Using BorderColor" />
</Frame>
<Label
Text="Shadow"
Style="{StaticResource Headline}"/>
<Frame
x:Name="HasShadowFrame"
BackgroundColor="LightGray"
BorderColor="Red"
HasShadow="True">
<Label
Text="Has Shadow" />
</Frame>
<Label
Text="IsClippedToBounds (False)"
Style="{StaticResource Headline}"/>
<Frame
IsClippedToBounds="False"
Padding="0"
BackgroundColor="LightGray"
BorderColor="Red"
CornerRadius="24">
<Image
Aspect="AspectFill"
Source="cover1.jpg" />
</Frame>
<Label
Text="IsClippedToBounds (True)"
Style="{StaticResource Headline}"/>
<Frame
IsClippedToBounds="True"
Padding="0"
BackgroundColor="LightGray"
BorderColor="Red"
CornerRadius="24">
<Image
Aspect="AspectFill"
Source="cover1.jpg" />
</Frame>
</VerticalStackLayout>
<ScrollView>
<VerticalStackLayout
Margin="12">
<Label
Text="Default"
Style="{StaticResource Headline}"/>
<Frame
BackgroundColor="LightGray"
HasShadow="False">
<Label
Text="Only with BackgroundColor" />
</Frame>
<Label
Text="Background"
Style="{StaticResource Headline}"/>
<Frame>
<Frame.Background>
<LinearGradientBrush EndPoint="1,0">
<GradientStop Color="Yellow"
Offset="0.1" />
<GradientStop Color="Green"
Offset="1.0" />
</LinearGradientBrush>
</Frame.Background>
<Label
Text="Background" />
</Frame>
<Label
Text="BorderColor"
Style="{StaticResource Headline}"/>
<Frame
BackgroundColor="LightGray"
BorderColor="Red"
HasShadow="False">
<Label
Text="Using BorderColor" />
</Frame>
<Label
Text="Shadow"
Style="{StaticResource Headline}"/>
<Frame
x:Name="HasShadowFrame"
BackgroundColor="LightGray"
BorderColor="Red"
HasShadow="True">
<Label
Text="Has Shadow" />
</Frame>
<Label
Text="Opacity"
Style="{StaticResource Headline}"/>
<Frame
BackgroundColor="LightGray"
BorderColor="Red"
Opacity="0.5"
HasShadow="True">
<Label
Text="Opacity 0.5" />
</Frame>
<Label
Text="IsClippedToBounds (False)"
Style="{StaticResource Headline}"/>
<Frame
IsClippedToBounds="False"
Padding="0"
BackgroundColor="LightGray"
BorderColor="Red"
CornerRadius="24">
<Image
Aspect="AspectFill"
Source="cover1.jpg" />
</Frame>
<Label
Text="IsClippedToBounds (True)"
Style="{StaticResource Headline}"/>
<Frame
IsClippedToBounds="True"
Padding="0"
BackgroundColor="LightGray"
BorderColor="Red"
CornerRadius="24">
<Image
Aspect="AspectFill"
Source="cover1.jpg" />
</Frame>
</VerticalStackLayout>
</ScrollView>
</views:BasePage.Content>
</views:BasePage>

Просмотреть файл

@ -67,6 +67,17 @@
VerticalOptions="Center"
HorizontalOptions="Center" />
<Label
Text="Using Opacity"
Style="{StaticResource Headline}"/>
<BoxView
Color="Orange"
Opacity="0.5"
WidthRequest="160"
HeightRequest="160"
VerticalOptions="Center"
HorizontalOptions="Center" />
</VerticalStackLayout>
</ScrollView>
</views:BasePage>

Просмотреть файл

@ -9,48 +9,48 @@ namespace Microsoft.Maui.Controls.Build.Tasks
{
static class BindablePropertyReferenceExtensions
{
public static TypeReference GetBindablePropertyType(this FieldReference bpRef, IXmlLineInfo iXmlLineInfo, ModuleDefinition module)
public static TypeReference GetBindablePropertyType(this FieldReference bpRef, XamlCache cache, IXmlLineInfo iXmlLineInfo, ModuleDefinition module)
{
if (!bpRef.Name.EndsWith("Property", StringComparison.InvariantCulture))
throw new BuildException(BuildExceptionCode.BPName, iXmlLineInfo, null, bpRef.Name);
var bpName = bpRef.Name.Substring(0, bpRef.Name.Length - 8);
var owner = bpRef.DeclaringType;
var getter = owner.GetProperty(pd => pd.Name == bpName, out TypeReference declaringTypeRef)?.GetMethod;
var getter = owner.GetProperty(cache, pd => pd.Name == bpName, out TypeReference declaringTypeRef)?.GetMethod;
if (getter == null || getter.IsStatic || !getter.IsPublic)
getter = null;
getter = getter ?? owner.GetMethods(md => md.Name == $"Get{bpName}" &&
getter = getter ?? owner.GetMethods(cache, md => md.Name == $"Get{bpName}" &&
md.IsStatic &&
md.IsPublic &&
md.Parameters.Count == 1 &&
md.Parameters[0].ParameterType.InheritsFromOrImplements(module.ImportReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "BindableObject"))), module).FirstOrDefault()?.Item1;
md.Parameters[0].ParameterType.InheritsFromOrImplements(cache, module.ImportReference(cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "BindableObject"))), module).FirstOrDefault()?.Item1;
if (getter == null)
throw new BuildException(BuildExceptionCode.BPName, iXmlLineInfo, null, bpName, bpRef.DeclaringType);
return getter.ResolveGenericReturnType(declaringTypeRef, module);
}
public static TypeReference GetBindablePropertyTypeConverter(this FieldReference bpRef, ModuleDefinition module)
public static TypeReference GetBindablePropertyTypeConverter(this FieldReference bpRef, XamlCache cache, ModuleDefinition module)
{
var owner = bpRef.DeclaringType;
var bpName = bpRef.Name.EndsWith("Property", StringComparison.Ordinal) ? bpRef.Name.Substring(0, bpRef.Name.Length - 8) : bpRef.Name;
var property = owner.GetProperty(pd => pd.Name == bpName, out TypeReference propertyDeclaringType);
var property = owner.GetProperty(cache, pd => pd.Name == bpName, out TypeReference propertyDeclaringType);
var propertyType = property?.PropertyType?.ResolveGenericParameters(propertyDeclaringType);
var staticGetter = owner.GetMethods(md => md.Name == $"Get{bpName}" &&
var staticGetter = owner.GetMethods(cache, md => md.Name == $"Get{bpName}" &&
md.IsStatic &&
md.IsPublic &&
md.Parameters.Count == 1 &&
md.Parameters[0].ParameterType.InheritsFromOrImplements(module.ImportReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "BindableObject"))), module).FirstOrDefault()?.Item1;
md.Parameters[0].ParameterType.InheritsFromOrImplements(cache, module.ImportReference(cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "BindableObject"))), module).FirstOrDefault()?.Item1;
var attributes = new List<CustomAttribute>();
if (property != null && property.HasCustomAttributes)
attributes.AddRange(property.CustomAttributes);
if (propertyType != null && propertyType.ResolveCached().HasCustomAttributes)
attributes.AddRange(propertyType.ResolveCached().CustomAttributes);
if (propertyType != null && propertyType.ResolveCached(cache).HasCustomAttributes)
attributes.AddRange(propertyType.ResolveCached(cache).CustomAttributes);
if (staticGetter != null && staticGetter.HasCustomAttributes)
attributes.AddRange(staticGetter.CustomAttributes);
if (staticGetter != null && staticGetter.ReturnType.ResolveGenericParameters(bpRef.DeclaringType).ResolveCached().HasCustomAttributes)
attributes.AddRange(staticGetter.ReturnType.ResolveGenericParameters(bpRef.DeclaringType).ResolveCached().CustomAttributes);
if (staticGetter != null && staticGetter.ReturnType.ResolveGenericParameters(bpRef.DeclaringType).ResolveCached(cache).HasCustomAttributes)
attributes.AddRange(staticGetter.ReturnType.ResolveGenericParameters(bpRef.DeclaringType).ResolveCached(cache).CustomAttributes);
if (attributes.FirstOrDefault(cad => cad.AttributeType.FullName == "System.ComponentModel.TypeConverterAttribute")?.ConstructorArguments[0].Value is TypeReference typeConverter)
return typeConverter;

Просмотреть файл

@ -21,11 +21,11 @@ namespace Microsoft.Maui.Controls.XamlC
yield return Instruction.Create(OpCodes.Ldnull);
yield break;
}
var bpRef = GetBindablePropertyFieldReference(value, module, node);
var bpRef = GetBindablePropertyFieldReference(value, context, module, node);
yield return Instruction.Create(OpCodes.Ldsfld, bpRef);
}
public FieldReference GetBindablePropertyFieldReference(string value, ModuleDefinition module, BaseNode node)
public FieldReference GetBindablePropertyFieldReference(string value, ILContext context, ModuleDefinition module, BaseNode node)
{
FieldReference bpRef = null;
string typeName = null, propertyName = null;
@ -70,11 +70,11 @@ namespace Microsoft.Maui.Controls.XamlC
if (typeName == null || propertyName == null)
throw new BuildException(Conversion, node, null, value, typeof(BindableProperty));
var typeRef = XmlTypeExtensions.GetTypeReference(typeName, module, node);
var typeRef = XmlTypeExtensions.GetTypeReference(context.Cache, typeName, module, node);
if (typeRef == null)
throw new BuildException(TypeResolution, node, null, typeName);
bpRef = GetBindablePropertyFieldReference(typeRef, propertyName, module);
bpRef = GetBindablePropertyFieldReference(context.Cache, typeRef, propertyName, module);
if (bpRef == null)
throw new BuildException(PropertyResolution, node, null, propertyName, typeRef.Name);
return bpRef;
@ -103,10 +103,10 @@ namespace Microsoft.Maui.Controls.XamlC
return target.XmlType.Name;
}
public static FieldReference GetBindablePropertyFieldReference(TypeReference typeRef, string propertyName, ModuleDefinition module)
public static FieldReference GetBindablePropertyFieldReference(XamlCache cache, TypeReference typeRef, string propertyName, ModuleDefinition module)
{
TypeReference declaringTypeReference;
FieldReference bpRef = typeRef.GetField(fd => fd.Name == $"{propertyName}Property" && fd.IsStatic && fd.IsPublic, out declaringTypeReference);
FieldReference bpRef = typeRef.GetField(cache, fd => fd.Name == $"{propertyName}Property" && fd.IsStatic && fd.IsPublic, out declaringTypeReference);
if (bpRef != null)
{
bpRef = module.ImportReference(bpRef.ResolveGenericParameters(declaringTypeReference));

Просмотреть файл

@ -53,10 +53,10 @@ namespace Microsoft.Maui.Controls.XamlC
if (!hasX || !hasY || !hasW || !hasH)
throw new BuildException(BuildExceptionCode.Conversion, node, null, value, typeof(Rect));
return GenerateIL(x, y, w, h, module);
return GenerateIL(context, x, y, w, h, module);
}
IEnumerable<Instruction> GenerateIL(double x, double y, double w, double h, ModuleDefinition module)
IEnumerable<Instruction> GenerateIL(ILContext context, double x, double y, double w, double h, ModuleDefinition module)
{
// IL_0000: ldc.r8 3.1000000000000001
// IL_0009: ldc.r8 4.2000000000000002
@ -68,7 +68,7 @@ namespace Microsoft.Maui.Controls.XamlC
yield return Instruction.Create(OpCodes.Ldc_R8, y);
yield return Instruction.Create(OpCodes.Ldc_R8, w);
yield return Instruction.Create(OpCodes.Ldc_R8, h);
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("Microsoft.Maui.Graphics", "Microsoft.Maui.Graphics", "Rect"), parameterTypes: new[] {
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(context.Cache, ("Microsoft.Maui.Graphics", "Microsoft.Maui.Graphics", "Rect"), parameterTypes: new[] {
("mscorlib", "System", "Double"),
("mscorlib", "System", "Double"),
("mscorlib", "System", "Double"),

Просмотреть файл

@ -22,13 +22,14 @@ class BrushTypeConverter : ICompiledTypeConverter
foreach (var instruction in colorConverter.ConvertFromString(value, context, node))
yield return instruction;
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "SolidColorBrush"), parameterTypes: new[] {
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "SolidColorBrush"), parameterTypes: new[] {
("Microsoft.Maui.Graphics", "Microsoft.Maui.Graphics", "Color")}));
yield break;
}
var propertyGetterReference = module.ImportPropertyGetterReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "Brush"),
var propertyGetterReference = module.ImportPropertyGetterReference(context.Cache,
("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "Brush"),
value,
isStatic: true,
caseSensitive: false);

Просмотреть файл

@ -29,7 +29,7 @@ namespace Microsoft.Maui.Controls.XamlC
yield return Instruction.Create(OpCodes.Ldc_R4, color.Blue);
yield return Instruction.Create(OpCodes.Ldc_R4, color.Alpha);
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("Microsoft.Maui.Graphics", "Microsoft.Maui.Graphics", "Color"), parameterTypes: new[] {
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(context.Cache, ("Microsoft.Maui.Graphics", "Microsoft.Maui.Graphics", "Color"), parameterTypes: new[] {
("mscorlib", "System", "Single"),
("mscorlib", "System", "Single"),
("mscorlib", "System", "Single"),
@ -49,7 +49,7 @@ namespace Microsoft.Maui.Controls.XamlC
yield break;
}
var fieldReference = module.ImportFieldReference(("Microsoft.Maui.Graphics", "Microsoft.Maui.Graphics", "Colors"),
var fieldReference = module.ImportFieldReference(context.Cache, ("Microsoft.Maui.Graphics", "Microsoft.Maui.Graphics", "Colors"),
color,
isStatic: true,
caseSensitive: false);
@ -60,7 +60,7 @@ namespace Microsoft.Maui.Controls.XamlC
yield break;
}
var propertyGetterReference = module.ImportPropertyGetterReference(("Microsoft.Maui.Graphics", "Microsoft.Maui.Graphics", "Colors"),
var propertyGetterReference = module.ImportPropertyGetterReference(context.Cache, ("Microsoft.Maui.Graphics", "Microsoft.Maui.Graphics", "Colors"),
color,
isStatic: true,
caseSensitive: false);

Просмотреть файл

@ -20,19 +20,19 @@ namespace Microsoft.Maui.Controls.XamlC
var parts = value.Split(',');
yield return Create(Ldc_I4, parts.Length);
yield return Create(Newarr, module.ImportReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "ColumnDefinition")));
yield return Create(Newarr, module.ImportReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "ColumnDefinition")));
for (var i = 0; i < parts.Length; i++)
{
yield return Create(Dup);
yield return Create(Ldc_I4, i);
foreach (var instruction in gridlengthconverter.ConvertFromString(parts[i], context, node))
yield return instruction;
yield return Create(Newobj, module.ImportCtorReference(
yield return Create(Newobj, module.ImportCtorReference(context.Cache,
type: ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "ColumnDefinition"),
parameterTypes: new[] { ("Microsoft.Maui", "Microsoft.Maui", "GridLength") }));
yield return Create(Stelem_Ref);
}
yield return Create(Newobj, module.ImportCtorReference(
yield return Create(Newobj, module.ImportCtorReference(context.Cache,
type: ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "ColumnDefinitionCollection"),
paramCount: 1));
yield break;

Просмотреть файл

@ -20,7 +20,7 @@ namespace Microsoft.Maui.Controls.XamlC
throw new BuildException(BuildExceptionCode.Conversion, node, null, value, typeof(Compatibility.Constraint));
yield return Create(Ldc_R8, size);
yield return Create(Call, module.ImportMethodReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Compatibility", "Constraint"),
yield return Create(Call, module.ImportMethodReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Compatibility", "Constraint"),
methodName: "Constant",
parameterTypes: new[] { ("mscorlib", "System", "Double") },
isStatic: true));

Просмотреть файл

@ -22,25 +22,25 @@ namespace Microsoft.Maui.Controls.XamlC
{
case 1:
if (double.TryParse(cornerradius[0], NumberStyles.Number, CultureInfo.InvariantCulture, out l))
return GenerateIL(module, l);
return GenerateIL(context, module, l);
break;
case 4:
if (double.TryParse(cornerradius[0], NumberStyles.Number, CultureInfo.InvariantCulture, out tl)
&& double.TryParse(cornerradius[1], NumberStyles.Number, CultureInfo.InvariantCulture, out tr)
&& double.TryParse(cornerradius[2], NumberStyles.Number, CultureInfo.InvariantCulture, out bl)
&& double.TryParse(cornerradius[3], NumberStyles.Number, CultureInfo.InvariantCulture, out br))
return GenerateIL(module, tl, tr, bl, br);
return GenerateIL(context, module, tl, tr, bl, br);
break;
}
}
throw new BuildException(BuildExceptionCode.Conversion, node, null, value, typeof(CornerRadius));
}
IEnumerable<Instruction> GenerateIL(ModuleDefinition module, params double[] args)
IEnumerable<Instruction> GenerateIL(ILContext context, ModuleDefinition module, params double[] args)
{
foreach (var d in args)
yield return Instruction.Create(OpCodes.Ldc_R8, d);
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("Microsoft.Maui", "Microsoft.Maui", "CornerRadius"), parameterTypes: args.Select(a => ("mscorlib", "System", "Double")).ToArray()));
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(context.Cache, ("Microsoft.Maui", "Microsoft.Maui", "CornerRadius"), parameterTypes: args.Select(a => ("mscorlib", "System", "Double")).ToArray()));
}
}

Просмотреть файл

@ -25,7 +25,7 @@ namespace Microsoft.Maui.Controls.XamlC
var assemblyTypeInfo = ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", nameof(Easing));
var module = context.Body.Method.Module;
var fieldReference = module.ImportFieldReference(assemblyTypeInfo, value, isStatic: true, caseSensitive: false);
var fieldReference = module.ImportFieldReference(context.Cache, assemblyTypeInfo, value, isStatic: true, caseSensitive: false);
if (fieldReference != null)
{

Просмотреть файл

@ -19,7 +19,7 @@ namespace Microsoft.Maui.Controls.XamlC
if (value == "Auto")
{
yield return Instruction.Create(OpCodes.Ldsfld,
module.ImportFieldReference(("Microsoft.Maui", "Microsoft.Maui.Layouts", "FlexBasis"),
module.ImportFieldReference(context.Cache, ("Microsoft.Maui", "Microsoft.Maui.Layouts", "FlexBasis"),
"Auto",
isStatic: true));
yield break;
@ -29,7 +29,7 @@ namespace Microsoft.Maui.Controls.XamlC
{
yield return Instruction.Create(OpCodes.Ldc_R4, (float)(relflex / 100));
yield return Instruction.Create(OpCodes.Ldc_I4_1); //isRelative: true
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("Microsoft.Maui", "Microsoft.Maui.Layouts", "FlexBasis"), parameterTypes: new[] {
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(context.Cache, ("Microsoft.Maui", "Microsoft.Maui.Layouts", "FlexBasis"), parameterTypes: new[] {
("mscorlib", "System", "Single"),
("mscorlib", "System", "Boolean")}));
yield break;
@ -38,7 +38,7 @@ namespace Microsoft.Maui.Controls.XamlC
{
yield return Instruction.Create(OpCodes.Ldc_R4, flex);
yield return Instruction.Create(OpCodes.Ldc_I4_0); //isRelative: false
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("Microsoft.Maui", "Microsoft.Maui.Layouts", "FlexBasis"), parameterTypes: new[] {
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(context.Cache, ("Microsoft.Maui", "Microsoft.Maui.Layouts", "FlexBasis"), parameterTypes: new[] {
("mscorlib", "System", "Single"),
("mscorlib", "System", "Boolean")}));
yield break;

Просмотреть файл

@ -32,19 +32,22 @@ namespace Microsoft.Maui.Controls.XamlC
{
yield return Instruction.Create(OpCodes.Ldloc, context.Variables[parent]);
yield return Instruction.Create(OpCodes.Callvirt, module.ImportMethodReference(
context.Cache,
module.TypeSystem.Object,
methodName: "GetType"));
}
else
{
yield return Instruction.Create(OpCodes.Ldtoken, module.ImportReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "Label")));
yield return Instruction.Create(OpCodes.Ldtoken, module.ImportReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "Label")));
yield return Instruction.Create(OpCodes.Call, module.ImportMethodReference(
context.Cache,
("mscorlib", "System", "Type"),
methodName: "GetTypeFromHandle",
parameterTypes: new[] { ("mscorlib", "System", "RuntimeTypeHandle") },
isStatic: true));
}
yield return Instruction.Create(OpCodes.Call, module.ImportMethodReference(
context.Cache,
("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "Device"),
methodName: "GetNamedSize",
parameterTypes: new[] { ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "NamedSize"), ("System.Runtime", "System", "Type") },

Просмотреть файл

@ -21,28 +21,28 @@ namespace Microsoft.Maui.Controls.XamlC
if (value.Equals("auto", StringComparison.OrdinalIgnoreCase))
{
yield return Create(Ldsfld, module.ImportFieldReference(("Microsoft.Maui", "Microsoft.Maui", "GridLength"), nameof(GridLength.Auto), isStatic: true));
yield return Create(Ldsfld, module.ImportFieldReference(context.Cache, ("Microsoft.Maui", "Microsoft.Maui", "GridLength"), nameof(GridLength.Auto), isStatic: true));
yield break;
}
if (value.Equals("*", StringComparison.OrdinalIgnoreCase))
{
yield return Create(Ldsfld, module.ImportFieldReference(("Microsoft.Maui", "Microsoft.Maui", "GridLength"), nameof(GridLength.Star), isStatic: true));
yield return Create(Ldsfld, module.ImportFieldReference(context.Cache, ("Microsoft.Maui", "Microsoft.Maui", "GridLength"), nameof(GridLength.Star), isStatic: true));
yield break;
}
if (value.EndsWith("*", StringComparison.OrdinalIgnoreCase) && double.TryParse(value.Substring(0, value.Length - 1), NumberStyles.Number, CultureInfo.InvariantCulture, out var length))
{
yield return Create(Ldc_R8, length);
yield return Create(Ldc_I4, (int)GridUnitType.Star);
yield return Create(Newobj, module.ImportCtorReference(
type: module.GetTypeDefinition(("Microsoft.Maui", "Microsoft.Maui", "GridLength")),
parameterTypes: new[] { module.TypeSystem.Double, module.GetTypeDefinition(("Microsoft.Maui", "Microsoft.Maui", "GridUnitType")) }));
yield return Create(Newobj, module.ImportCtorReference(context.Cache,
type: module.GetTypeDefinition(context.Cache, ("Microsoft.Maui", "Microsoft.Maui", "GridLength")),
parameterTypes: new[] { module.TypeSystem.Double, module.GetTypeDefinition(context.Cache, ("Microsoft.Maui", "Microsoft.Maui", "GridUnitType")) }));
yield break;
}
if (double.TryParse(value, NumberStyles.Number, CultureInfo.InvariantCulture, out length))
{
yield return Create(Ldc_R8, length);
yield return Create(Newobj, module.ImportCtorReference(
type: module.GetTypeDefinition(("Microsoft.Maui", "Microsoft.Maui", "GridLength")),
yield return Create(Newobj, module.ImportCtorReference(context.Cache,
type: module.GetTypeDefinition(context.Cache, ("Microsoft.Maui", "Microsoft.Maui", "GridLength")),
parameterTypes: new[] { module.TypeSystem.Double }));
yield break;
}

Просмотреть файл

@ -19,16 +19,16 @@ class ImageSourceTypeConverter : ICompiledTypeConverter
{
yield return Instruction.Create(OpCodes.Ldstr, value);
yield return Instruction.Create(OpCodes.Ldc_I4_1); // (int)UriKind.Absolute is 1
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("System", "System", "Uri"), parameterTypes: new[] {
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(context.Cache, ("System", "System", "Uri"), parameterTypes: new[] {
("mscorlib", "System", "String"),
("System", "System", "UriKind")}));
yield return Instruction.Create(OpCodes.Call, module.ImportMethodReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "ImageSource"), "FromUri", parameterTypes: new[] {
yield return Instruction.Create(OpCodes.Call, module.ImportMethodReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "ImageSource"), "FromUri", parameterTypes: new[] {
("System", "System", "Uri")}, isStatic: true));
}
else
{
yield return Instruction.Create(OpCodes.Ldstr, value);
yield return Instruction.Create(OpCodes.Call, module.ImportMethodReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "ImageSource"), "FromFile", parameterTypes: new[] {
yield return Instruction.Create(OpCodes.Call, module.ImportMethodReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "ImageSource"), "FromFile", parameterTypes: new[] {
("mscorlib", "System", "String")}, isStatic: true));
}
yield break;

Просмотреть файл

@ -26,7 +26,7 @@ namespace Microsoft.Maui.Controls.XamlC
{
var options = parts[parts.Length - 1];
var fieldReference = module.ImportFieldReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "LayoutOptions"),
var fieldReference = module.ImportFieldReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "LayoutOptions"),
fieldName: options,
isStatic: true);
if (fieldReference != null)

Просмотреть файл

@ -23,14 +23,14 @@ namespace Microsoft.Maui.Controls.XamlC
var parts = value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(s => s.Trim()).ToList();
yield return Create(Ldc_I4, parts.Count);
yield return Create(Newobj, module.ImportCtorReference(("System.Collections", "System.Collections.Generic", "List`1"),
yield return Create(Newobj, module.ImportCtorReference(context.Cache, ("System.Collections", "System.Collections.Generic", "List`1"),
parameterTypes: new[] { ("mscorlib", "System", "Int32") },
classArguments: new[] { ("mscorlib", "System", "String") }));
foreach (var part in parts)
{
yield return Create(Dup);
yield return Create(Ldstr, part);
yield return Create(Callvirt, module.ImportMethodReference(("mscorlib", "System.Collections.Generic", "ICollection`1"),
yield return Create(Callvirt, module.ImportMethodReference(context.Cache, ("mscorlib", "System.Collections.Generic", "ICollection`1"),
methodName: "Add",
paramCount: 1,
classArguments: new[] { ("mscorlib", "System", "String") }));

Просмотреть файл

@ -14,7 +14,7 @@ class PointTypeConverter : ICompiledTypeConverter
var module = context.Body.Method.Module;
if (!string.IsNullOrEmpty(value) && Point.TryParse(value.Trim(), out var point))
{
foreach (var instruction in CreatePoint(module, point))
foreach (var instruction in CreatePoint(context, module, point))
{
yield return instruction;
}
@ -23,11 +23,11 @@ class PointTypeConverter : ICompiledTypeConverter
throw new BuildException(BuildExceptionCode.Conversion, node, null, value, typeof(Point));
}
public IEnumerable<Instruction> CreatePoint(ModuleDefinition module, Point point)
public IEnumerable<Instruction> CreatePoint(ILContext context, ModuleDefinition module, Point point)
{
yield return Instruction.Create(OpCodes.Ldc_R8, point.X);
yield return Instruction.Create(OpCodes.Ldc_R8, point.Y);
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("Microsoft.Maui.Graphics", "Microsoft.Maui.Graphics", "Point"), parameterTypes: new[] {
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(context.Cache, ("Microsoft.Maui.Graphics", "Microsoft.Maui.Graphics", "Point"), parameterTypes: new[] {
("mscorlib", "System", "Double"),
("mscorlib", "System", "Double")}));
}

Просмотреть файл

@ -23,7 +23,7 @@ namespace Microsoft.Maui.Controls.XamlC
var rdNode = node.Parent as IElementNode;
var rootTargetPath = XamlCTask.GetPathForType(currentModule, ((ILRootNode)rootNode).TypeReference);
var rootTargetPath = XamlCTask.GetPathForType(context.Cache, currentModule, ((ILRootNode)rootNode).TypeReference);
var module = currentModule;
string asmName = null;
@ -45,7 +45,7 @@ namespace Microsoft.Maui.Controls.XamlC
var resourcePath = ResourceDictionary.RDSourceTypeConverter.GetResourcePath(uri, rootTargetPath);
//fail early
var resourceId = XamlCTask.GetResourceIdForPath(module, resourcePath);
var resourceId = XamlCTask.GetResourceIdForPath(context.Cache, module, resourcePath);
if (resourceId == null)
throw new BuildException(BuildExceptionCode.ResourceMissing, node, null, value);
@ -53,7 +53,7 @@ namespace Microsoft.Maui.Controls.XamlC
//abuse the converter, produce some side effect, but leave the stack untouched
//public void SetAndLoadSource(Uri value, string resourceID, Assembly assembly, System.Xml.IXmlLineInfo lineInfo)
foreach (var instruction in context.Variables[rdNode].LoadAs(currentModule.GetTypeDefinition(resourceDictionaryType), currentModule))
foreach (var instruction in context.Variables[rdNode].LoadAs(context.Cache, currentModule.GetTypeDefinition(context.Cache, resourceDictionaryType), currentModule))
yield return instruction;
//reappend assembly= in all cases, see other RD converter
if (!string.IsNullOrEmpty(asmName))
@ -65,7 +65,7 @@ namespace Microsoft.Maui.Controls.XamlC
//keep the Uri for later
yield return Create(Dup);
var uriVarDef = new VariableDefinition(currentModule.ImportReference(("System", "System", "Uri")));
var uriVarDef = new VariableDefinition(currentModule.ImportReference(context.Cache, ("System", "System", "Uri")));
body.Variables.Add(uriVarDef);
yield return Create(Stloc, uriVarDef);
yield return Create(Ldstr, resourcePath); //resourcePath
@ -73,28 +73,29 @@ namespace Microsoft.Maui.Controls.XamlC
if (!string.IsNullOrEmpty(asmName))
{
yield return Create(Ldstr, asmName);
yield return Create(Call, currentModule.ImportMethodReference(("mscorlib", "System.Reflection", "Assembly"), methodName: "Load", parameterTypes: new[] { ("mscorlib", "System", "String") }, isStatic: true));
yield return Create(Call, currentModule.ImportMethodReference(context.Cache, ("mscorlib", "System.Reflection", "Assembly"), methodName: "Load", parameterTypes: new[] { ("mscorlib", "System", "String") }, isStatic: true));
}
else //we could use assembly.Load in the 'else' part too, but I don't want to change working code right now
{
yield return Create(Ldtoken, currentModule.ImportReference(((ILRootNode)rootNode).TypeReference));
yield return Create(Call, currentModule.ImportMethodReference(("mscorlib", "System", "Type"), methodName: "GetTypeFromHandle", parameterTypes: new[] { ("mscorlib", "System", "RuntimeTypeHandle") }, isStatic: true));
yield return Create(Callvirt, currentModule.ImportPropertyGetterReference(("mscorlib", "System", "Type"), propertyName: "Assembly", flatten: true));
yield return Create(Call, currentModule.ImportMethodReference(context.Cache, ("mscorlib", "System", "Type"), methodName: "GetTypeFromHandle", parameterTypes: new[] { ("mscorlib", "System", "RuntimeTypeHandle") }, isStatic: true));
yield return Create(Callvirt, currentModule.ImportPropertyGetterReference(context.Cache, ("mscorlib", "System", "Type"), propertyName: "Assembly", flatten: true));
}
foreach (var instruction in node.PushXmlLineInfo(context))
yield return instruction; //lineinfo
yield return Create(Callvirt, currentModule.ImportMethodReference(resourceDictionaryType,
yield return Create(Callvirt, currentModule.ImportMethodReference(context.Cache,
resourceDictionaryType,
methodName: "SetAndLoadSource",
parameterTypes: new[] { ("System", "System", "Uri"), ("mscorlib", "System", "String"), ("mscorlib", "System.Reflection", "Assembly"), ("System.Xml.ReaderWriter", "System.Xml", "IXmlLineInfo") }));
//ldloc the stored uri as return value
yield return Create(Ldloc, uriVarDef);
}
internal static string GetPathForType(ModuleDefinition module, TypeReference type)
internal static string GetPathForType(ILContext context, ModuleDefinition module, TypeReference type)
{
foreach (var ca in type.Module.GetCustomAttributes())
{
if (!TypeRefComparer.Default.Equals(ca.AttributeType, module.ImportReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "XamlResourceIdAttribute"))))
if (!TypeRefComparer.Default.Equals(ca.AttributeType, module.ImportReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "XamlResourceIdAttribute"))))
continue;
if (!TypeRefComparer.Default.Equals(ca.ConstructorArguments[2].Value as TypeReference, type))
continue;

Просмотреть файл

@ -26,10 +26,10 @@ namespace Microsoft.Maui.Controls.XamlC
!double.TryParse(xywh[3], NumberStyles.Number, CultureInfo.InvariantCulture, out h))
throw new BuildException(BuildExceptionCode.Conversion, node, null, value, typeof(Rect));
return GenerateIL(x, y, w, h, module);
return GenerateIL(context, x, y, w, h, module);
}
IEnumerable<Instruction> GenerateIL(double x, double y, double w, double h, ModuleDefinition module)
IEnumerable<Instruction> GenerateIL(ILContext context, double x, double y, double w, double h, ModuleDefinition module)
{
// IL_0000: ldc.r8 3.1000000000000001
// IL_0009: ldc.r8 4.2000000000000002
@ -41,7 +41,7 @@ namespace Microsoft.Maui.Controls.XamlC
yield return Instruction.Create(OpCodes.Ldc_R8, y);
yield return Instruction.Create(OpCodes.Ldc_R8, w);
yield return Instruction.Create(OpCodes.Ldc_R8, h);
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("Microsoft.Maui.Graphics", "Microsoft.Maui.Graphics", "Rect"), parameterTypes: new[] {
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(context.Cache, ("Microsoft.Maui.Graphics", "Microsoft.Maui.Graphics", "Rect"), parameterTypes: new[] {
("mscorlib", "System", "Double"),
("mscorlib", "System", "Double"),
("mscorlib", "System", "Double"),

Просмотреть файл

@ -20,7 +20,7 @@ namespace Microsoft.Maui.Controls.XamlC
var parts = value.Split(',');
yield return Create(Ldc_I4, parts.Length);
yield return Create(Newarr, module.ImportReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "RowDefinition")));
yield return Create(Newarr, module.ImportReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "RowDefinition")));
for (var i = 0; i < parts.Length; i++)
{
yield return Create(Dup);
@ -28,11 +28,13 @@ namespace Microsoft.Maui.Controls.XamlC
foreach (var instruction in gridlengthconverter.ConvertFromString(parts[i], context, node))
yield return instruction;
yield return Create(Newobj, module.ImportCtorReference(
context.Cache,
type: ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "RowDefinition"),
parameterTypes: new[] { ("Microsoft.Maui", "Microsoft.Maui", "GridLength") }));
yield return Create(Stelem_Ref);
}
yield return Create(Newobj, module.ImportCtorReference(
context.Cache,
type: ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "RowDefinitionCollection"),
paramCount: 1));
yield break;

Просмотреть файл

@ -23,7 +23,7 @@ class StrokeShapeTypeConverter : ICompiledTypeConverter
if (value.StartsWith(ShapeConverter.Ellipse, StringComparison.Ordinal))
{
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "Ellipse"), parameterTypes: null));
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "Ellipse"), parameterTypes: null));
yield break;
}
@ -33,7 +33,7 @@ class StrokeShapeTypeConverter : ICompiledTypeConverter
var parts = value.Split(ShapeConverter.Delimiter, 2);
if (parts.Length != 2)
{
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "Line"), parameterTypes: null));
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "Line"), parameterTypes: null));
yield break;
}
@ -42,7 +42,7 @@ class StrokeShapeTypeConverter : ICompiledTypeConverter
if (points == null || points.Count == 0)
{
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "Line"), parameterTypes: null));
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "Line"), parameterTypes: null));
yield break;
}
@ -53,7 +53,7 @@ class StrokeShapeTypeConverter : ICompiledTypeConverter
yield return Instruction.Create(OpCodes.Ldc_R8, p1.Y);
yield return Instruction.Create(OpCodes.Ldc_R8, 0d);
yield return Instruction.Create(OpCodes.Ldc_R8, 0d);
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "Line"), parameterTypes: new[] {
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "Line"), parameterTypes: new[] {
("mscorlib", "System", "Double"),
("mscorlib", "System", "Double"),
("mscorlib", "System", "Double"),
@ -68,7 +68,7 @@ class StrokeShapeTypeConverter : ICompiledTypeConverter
yield return Instruction.Create(OpCodes.Ldc_R8, p2.X);
yield return Instruction.Create(OpCodes.Ldc_R8, p2.Y);
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "Line"), parameterTypes: new[] {
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "Line"), parameterTypes: new[] {
("mscorlib", "System", "Double"),
("mscorlib", "System", "Double"),
("mscorlib", "System", "Double"),
@ -85,17 +85,17 @@ class StrokeShapeTypeConverter : ICompiledTypeConverter
var parts = value.Split(ShapeConverter.Delimiter, 2);
if (parts.Length != 2)
{
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "Path"), parameterTypes: null));
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "Path"), parameterTypes: null));
yield break;
}
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "Path"), parameterTypes: null));
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "Path"), parameterTypes: null));
yield return Instruction.Create(OpCodes.Dup);
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "PathGeometryConverter"), parameterTypes: null));
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "PathGeometryConverter"), parameterTypes: null));
yield return Instruction.Create(OpCodes.Ldstr, parts[1]);
yield return Instruction.Create(OpCodes.Call, module.ImportMethodReference(("System", "System.ComponentModel", "TypeConverter"), "ConvertFromInvariantString", parameterTypes: new[] {
yield return Instruction.Create(OpCodes.Call, module.ImportMethodReference(context.Cache, ("System", "System.ComponentModel", "TypeConverter"), "ConvertFromInvariantString", parameterTypes: new[] {
("mscorlib", "System", "String")}));
yield return Instruction.Create(OpCodes.Call, module.ImportPropertySetterReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "Path"), "Data"));
yield return Instruction.Create(OpCodes.Call, module.ImportPropertySetterReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "Path"), "Data"));
yield break;
}
@ -104,7 +104,7 @@ class StrokeShapeTypeConverter : ICompiledTypeConverter
var parts = value.Split(ShapeConverter.Delimiter, 2);
if (parts.Length != 2)
{
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "Polygon"), parameterTypes: null));
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "Polygon"), parameterTypes: null));
yield break;
}
@ -113,16 +113,16 @@ class StrokeShapeTypeConverter : ICompiledTypeConverter
if (points == null || points.Count == 0)
{
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "Polygon"), parameterTypes: null));
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "Polygon"), parameterTypes: null));
yield break;
}
foreach (var instruction in CreatePointCollection(module, points))
foreach (var instruction in CreatePointCollection(context, module, points))
{
yield return instruction;
}
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "Polygon"), parameterTypes: new[] {
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "Polygon"), parameterTypes: new[] {
("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "PointCollection")}));
yield break;
}
@ -132,7 +132,7 @@ class StrokeShapeTypeConverter : ICompiledTypeConverter
var parts = value.Split(ShapeConverter.Delimiter, 2);
if (parts.Length != 2)
{
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "Polyline"), parameterTypes: null));
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "Polyline"), parameterTypes: null));
yield break;
}
@ -141,23 +141,23 @@ class StrokeShapeTypeConverter : ICompiledTypeConverter
if (points == null || points.Count == 0)
{
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "Polyline"), parameterTypes: null));
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "Polyline"), parameterTypes: null));
yield break;
}
foreach (var instruction in CreatePointCollection(module, points))
foreach (var instruction in CreatePointCollection(context, module, points))
{
yield return instruction;
}
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "Polyline"), parameterTypes: new[] {
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "Polyline"), parameterTypes: new[] {
("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "PointCollection")}));
yield break;
}
if (value.StartsWith(ShapeConverter.Rectangle, StringComparison.Ordinal))
{
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "Rectangle"), parameterTypes: null));
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "Rectangle"), parameterTypes: null));
yield break;
}
@ -166,11 +166,11 @@ class StrokeShapeTypeConverter : ICompiledTypeConverter
var parts = value.Split(ShapeConverter.Delimiter, 2);
if (parts.Length != 2)
{
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "RoundRectangle"), parameterTypes: null));
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "RoundRectangle"), parameterTypes: null));
yield break;
}
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "RoundRectangle"), parameterTypes: null));
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "RoundRectangle"), parameterTypes: null));
yield return Instruction.Create(OpCodes.Dup);
var cornerRadiusTypeConverter = new Converters.CornerRadiusTypeConverter();
@ -181,22 +181,22 @@ class StrokeShapeTypeConverter : ICompiledTypeConverter
yield return Instruction.Create(OpCodes.Ldc_R8, cornerRadius.BottomLeft);
yield return Instruction.Create(OpCodes.Ldc_R8, cornerRadius.BottomRight);
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("Microsoft.Maui", "Microsoft.Maui", "CornerRadius"), parameterTypes: new[] {
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(context.Cache, ("Microsoft.Maui", "Microsoft.Maui", "CornerRadius"), parameterTypes: new[] {
("mscorlib", "System", "Double"),
("mscorlib", "System", "Double"),
("mscorlib", "System", "Double"),
("mscorlib", "System", "Double")}));
yield return Instruction.Create(OpCodes.Call, module.ImportPropertySetterReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "RoundRectangle"), "CornerRadius"));
yield return Instruction.Create(OpCodes.Call, module.ImportPropertySetterReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "RoundRectangle"), "CornerRadius"));
yield break;
}
}
throw new BuildException(BuildExceptionCode.Conversion, node, null, value, typeof(IShape));
}
IEnumerable<Instruction> CreatePointCollection(ModuleDefinition module, PointCollection points)
IEnumerable<Instruction> CreatePointCollection(ILContext context, ModuleDefinition module, PointCollection points)
{
var pointType = module.ImportReference(("Microsoft.Maui.Graphics", "Microsoft.Maui.Graphics", "Point"));
var pointType = module.ImportReference(context.Cache, ("Microsoft.Maui.Graphics", "Microsoft.Maui.Graphics", "Point"));
yield return Instruction.Create(OpCodes.Ldc_I4, points.Count);
yield return Instruction.Create(OpCodes.Newarr, pointType);
@ -206,7 +206,7 @@ class StrokeShapeTypeConverter : ICompiledTypeConverter
yield return Instruction.Create(OpCodes.Dup);
yield return Instruction.Create(OpCodes.Ldc_I4, i);
foreach (var instruction in pointTypeConverter.CreatePoint(module, points[i]))
foreach (var instruction in pointTypeConverter.CreatePoint(context, module, points[i]))
{
yield return instruction;
}
@ -215,6 +215,6 @@ class StrokeShapeTypeConverter : ICompiledTypeConverter
yield return Instruction.Create(OpCodes.Stelem_Any, pointType);
}
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(type: ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "PointCollection"), paramCount: 1));
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(context.Cache, type: ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "PointCollection"), paramCount: 1));
}
}

Просмотреть файл

@ -22,30 +22,30 @@ namespace Microsoft.Maui.Controls.XamlC
{
case 1:
if (double.TryParse(thickness[0], NumberStyles.Number, CultureInfo.InvariantCulture, out l))
return GenerateIL(module, l);
return GenerateIL(context, module, l);
break;
case 2:
if (double.TryParse(thickness[0], NumberStyles.Number, CultureInfo.InvariantCulture, out l) &&
double.TryParse(thickness[1], NumberStyles.Number, CultureInfo.InvariantCulture, out t))
return GenerateIL(module, l, t);
return GenerateIL(context, module, l, t);
break;
case 4:
if (double.TryParse(thickness[0], NumberStyles.Number, CultureInfo.InvariantCulture, out l) &&
double.TryParse(thickness[1], NumberStyles.Number, CultureInfo.InvariantCulture, out t) &&
double.TryParse(thickness[2], NumberStyles.Number, CultureInfo.InvariantCulture, out r) &&
double.TryParse(thickness[3], NumberStyles.Number, CultureInfo.InvariantCulture, out b))
return GenerateIL(module, l, t, r, b);
return GenerateIL(context, module, l, t, r, b);
break;
}
}
throw new BuildException(BuildExceptionCode.Conversion, node, null, value, typeof(Thickness));
}
IEnumerable<Instruction> GenerateIL(ModuleDefinition module, params double[] args)
IEnumerable<Instruction> GenerateIL(ILContext context, ModuleDefinition module, params double[] args)
{
foreach (var d in args)
yield return Instruction.Create(OpCodes.Ldc_R8, d);
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("Microsoft.Maui", "Microsoft.Maui", "Thickness"), parameterTypes: args.Select(a => ("mscorlib", "System", "Double")).ToArray()));
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(context.Cache, ("Microsoft.Maui", "Microsoft.Maui", "Thickness"), parameterTypes: args.Select(a => ("mscorlib", "System", "Double")).ToArray()));
}
}

Просмотреть файл

@ -28,12 +28,12 @@ namespace Microsoft.Maui.Controls.XamlC
else
xmlType = new XmlType(node.NamespaceResolver.LookupNamespace(""), split[0], null);
var typeRef = xmlType.GetTypeReference(module, (IXmlLineInfo)node);
var typeRef = xmlType.GetTypeReference(context.Cache, module, (IXmlLineInfo)node);
if (typeRef == null)
goto error;
yield return Create(Ldtoken, module.ImportReference(typeRef));
yield return Create(Call, module.ImportMethodReference(("mscorlib", "System", "Type"),
yield return Create(Call, module.ImportMethodReference(context.Cache, ("mscorlib", "System", "Type"),
methodName: "GetTypeFromHandle",
parameterTypes: new[] { ("mscorlib", "System", "RuntimeTypeHandle") },
isStatic: true));

Просмотреть файл

@ -21,7 +21,7 @@ namespace Microsoft.Maui.Controls.XamlC
yield return Create(Ldstr, value);
yield return Create(Ldc_I4_0); //UriKind.RelativeOrAbsolute
yield return Create(Newobj, module.ImportCtorReference(("System", "System", "Uri"), parameterTypes: new[] {
yield return Create(Newobj, module.ImportCtorReference(context.Cache, ("System", "System", "Uri"), parameterTypes: new[] {
("mscorlib", "System", "String"),
("System", "System", "UriKind")}));
}

Просмотреть файл

@ -32,7 +32,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
yield return Instruction.Create(OpCodes.Dup);
yield return Instruction.Create(OpCodes.Ldc_I4, i);
yield return Instruction.Create(OpCodes.Ldelema, typeTypeRef);
foreach (var instruction in vardef.LoadAs(typeTypeRef, module))
foreach (var instruction in vardef.LoadAs(context.Cache, typeTypeRef, module))
yield return instruction;
yield return Instruction.Create(OpCodes.Stobj, typeTypeRef);
}
@ -40,7 +40,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
{
yield return Instruction.Create(OpCodes.Dup);
yield return Instruction.Create(OpCodes.Ldc_I4, i);
foreach (var instruction in vardef.LoadAs(typeTypeRef, module))
foreach (var instruction in vardef.LoadAs(context.Cache, typeTypeRef, module))
yield return instruction;
yield return Instruction.Create(OpCodes.Stelem_Ref);
}

Просмотреть файл

@ -13,7 +13,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
{
public IEnumerable<Instruction> ProvideValue(IElementNode node, ModuleDefinition module, ILContext context, out TypeReference typeRef)
{
typeRef = module.ImportReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "DataTemplate"));
typeRef = module.ImportReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "DataTemplate"));
var name = new XmlName("", "TypeName");
if (!node.Properties.TryGetValue(name, out INode typeNameNode) && node.CollectionItems.Any())
@ -22,13 +22,13 @@ namespace Microsoft.Maui.Controls.Build.Tasks
if (!(typeNameNode is ValueNode valueNode))
throw new BuildException(BuildExceptionCode.PropertyMissing, node as IXmlLineInfo, null, "TypeName", typeof(Microsoft.Maui.Controls.Xaml.DataTemplateExtension));
var contentTypeRef = module.ImportReference(XmlTypeExtensions.GetTypeReference(valueNode.Value as string, module, node as BaseNode))
var contentTypeRef = module.ImportReference(XmlTypeExtensions.GetTypeReference(context.Cache, valueNode.Value as string, module, node as BaseNode))
?? throw new BuildException(BuildExceptionCode.TypeResolution, node as IXmlLineInfo, null, valueNode.Value);
var dataTemplateCtor = module.ImportCtorReference(typeRef, new[] { module.ImportReference(("mscorlib", "System", "Type")) });
var dataTemplateCtor = module.ImportCtorReference(context.Cache, typeRef, new[] { module.ImportReference(context.Cache, ("mscorlib", "System", "Type")) });
return new List<Instruction> {
Create(Ldtoken, module.ImportReference(contentTypeRef)),
Create(Call, module.ImportMethodReference(("mscorlib", "System", "Type"), methodName: "GetTypeFromHandle", parameterTypes: new[] { ("mscorlib", "System", "RuntimeTypeHandle") }, isStatic: true)),
Create(Call, module.ImportMethodReference(context.Cache, ("mscorlib", "System", "Type"), methodName: "GetTypeFromHandle", parameterTypes: new[] { ("mscorlib", "System", "RuntimeTypeHandle") }, isStatic: true)),
Create(Newobj, dataTemplateCtor),
};
}

Просмотреть файл

@ -24,9 +24,9 @@ namespace Microsoft.Maui.Controls.Build.Tasks
var typename = member.Substring(0, dotIdx);
var membername = member.Substring(dotIdx + 1);
var typeRef = module.ImportReference(XmlTypeExtensions.GetTypeReference(typename, module, node as BaseNode));
var fieldRef = GetFieldReference(typeRef, membername, module);
var propertyDef = GetPropertyDefinition(typeRef, membername, module);
var typeRef = module.ImportReference(XmlTypeExtensions.GetTypeReference(context.Cache, typename, module, node as BaseNode));
var fieldRef = GetFieldReference(context.Cache, typeRef, membername, module);
var propertyDef = GetPropertyDefinition(context.Cache, typeRef, membername, module);
if (fieldRef == null && propertyDef == null)
throw new BuildException(BuildExceptionCode.XStaticResolution, node as IXmlLineInfo, null, membername, typename);
@ -61,7 +61,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
return new[] { Instruction.Create(OpCodes.Ldc_I8, (ulong)fieldDef.Constant) };
//enum values
if (memberRef.ResolveCached().IsEnum)
if (memberRef.ResolveCached(context.Cache).IsEnum)
{
if (fieldDef.Constant is long)
return new[] { Instruction.Create(OpCodes.Ldc_I8, (long)fieldDef.Constant) };
@ -79,9 +79,9 @@ namespace Microsoft.Maui.Controls.Build.Tasks
return new[] { Instruction.Create(OpCodes.Call, getterDef) };
}
public static FieldReference GetFieldReference(TypeReference typeRef, string fieldName, ModuleDefinition module)
public static FieldReference GetFieldReference(XamlCache cache, TypeReference typeRef, string fieldName, ModuleDefinition module)
{
FieldReference fRef = typeRef.GetField(fd => fd.Name == fieldName
FieldReference fRef = typeRef.GetField(cache, fd => fd.Name == fieldName
&& fd.IsStatic
&& IsPublicOrVisibleInternal(fd, module), out TypeReference declaringTypeReference);
if (fRef != null)
@ -109,9 +109,9 @@ namespace Microsoft.Maui.Controls.Build.Tasks
return false;
}
public static PropertyDefinition GetPropertyDefinition(TypeReference typeRef, string propertyName, ModuleDefinition module)
public static PropertyDefinition GetPropertyDefinition(XamlCache cache, TypeReference typeRef, string propertyName, ModuleDefinition module)
{
PropertyDefinition pDef = typeRef.GetProperty(pd => pd.Name == propertyName
PropertyDefinition pDef = typeRef.GetProperty(cache, pd => pd.Name == propertyName
&& IsPublicOrVisibleInternal(pd.GetMethod, module)
&& pd.GetMethod.IsStatic, out TypeReference declaringTypeReference);
return pDef;

Просмотреть файл

@ -13,7 +13,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
{
public IEnumerable<Instruction> ProvideValue(IElementNode node, ModuleDefinition module, ILContext context, out TypeReference memberRef)
{
memberRef = module.ImportReference(("mscorlib", "System", "Type"));
memberRef = module.ImportReference(context.Cache, ("mscorlib", "System", "Type"));
var name = new XmlName("", "TypeName");
if (!node.Properties.TryGetValue(name, out INode typeNameNode) && node.CollectionItems.Any())
@ -28,13 +28,13 @@ namespace Microsoft.Maui.Controls.Build.Tasks
node.CollectionItems.Clear();
}
var typeref = module.ImportReference(XmlTypeExtensions.GetTypeReference(valueNode.Value as string, module, node as BaseNode));
var typeref = module.ImportReference(XmlTypeExtensions.GetTypeReference(context.Cache, valueNode.Value as string, module, node as BaseNode));
context.TypeExtensions[node] = typeref ?? throw new BuildException(BuildExceptionCode.TypeResolution, node as IXmlLineInfo, null, valueNode.Value);
return new List<Instruction> {
Create(Ldtoken, module.ImportReference(typeref)),
Create(Call, module.ImportMethodReference(("mscorlib", "System", "Type"),
Create(Call, module.ImportMethodReference(context.Cache, ("mscorlib", "System", "Type"),
methodName: "GetTypeFromHandle",
parameterTypes: new[] { ("mscorlib", "System", "RuntimeTypeHandle") },
isStatic: true)),

Просмотреть файл

@ -18,7 +18,7 @@ namespace Microsoft.Maui.Controls.XamlC
valueNode = ((IElementNode)node).CollectionItems[0];
var bpNode = ((ValueNode)((IElementNode)node).Properties[new XmlName("", "Property")]);
var bpRef = (new BindablePropertyConverter()).GetBindablePropertyFieldReference((string)bpNode.Value, module, bpNode);
var bpRef = (new BindablePropertyConverter()).GetBindablePropertyFieldReference((string)bpNode.Value, context, module, bpNode);
if (SetterValueIsCollection(bpRef, module, node, context))
yield break;
@ -34,7 +34,7 @@ namespace Microsoft.Maui.Controls.XamlC
var setterType = ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "Setter");
//push the setter
foreach (var instruction in vardefref.VariableDefinition.LoadAs(module.GetTypeDefinition(setterType), module))
foreach (var instruction in vardefref.VariableDefinition.LoadAs(context.Cache, module.GetTypeDefinition(context.Cache, setterType), module))
yield return instruction;
//push the value
@ -42,7 +42,7 @@ namespace Microsoft.Maui.Controls.XamlC
yield return instruction;
//set the value
yield return Instruction.Create(OpCodes.Callvirt, module.ImportPropertySetterReference(setterType, propertyName: "Value"));
yield return Instruction.Create(OpCodes.Callvirt, module.ImportPropertySetterReference(context.Cache, setterType, propertyName: "Value"));
}
static bool SetterValueIsCollection(FieldReference bindablePropertyReference, ModuleDefinition module, BaseNode node, ILContext context)
@ -53,7 +53,7 @@ namespace Microsoft.Maui.Controls.XamlC
return false;
// Is this a generic type ?
var generic = bindablePropertyReference.GetBindablePropertyType(node, module) as GenericInstanceType;
var generic = bindablePropertyReference.GetBindablePropertyType(context.Cache, node, module) as GenericInstanceType;
// With a single generic argument?
if (generic?.GenericArguments.Count != 1)
@ -65,7 +65,7 @@ namespace Microsoft.Maui.Controls.XamlC
if (!(items[0] is IElementNode firstItem))
return false;
return context.Variables[firstItem].VariableType.InheritsFromOrImplements(genericType);
return context.Variables[firstItem].VariableType.InheritsFromOrImplements(context.Cache, genericType);
}
}
}

Просмотреть файл

@ -40,7 +40,7 @@ namespace Microsoft.Maui.Controls.XamlC
{
var style = (styleNode as ValueNode).Value as string;
yield return Create(Ldstr, style);
yield return Create(Call, module.ImportMethodReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.StyleSheets", "StyleSheet"),
yield return Create(Call, module.ImportMethodReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.StyleSheets", "StyleSheet"),
methodName: "FromString",
parameterTypes: new[] { ("mscorlib", "System", "String") },
isStatic: true));
@ -52,31 +52,31 @@ namespace Microsoft.Maui.Controls.XamlC
while (!(rootNode is ILRootNode))
rootNode = rootNode.Parent;
var rootTargetPath = RDSourceTypeConverter.GetPathForType(module, ((ILRootNode)rootNode).TypeReference);
var rootTargetPath = RDSourceTypeConverter.GetPathForType(context, module, ((ILRootNode)rootNode).TypeReference);
var uri = new Uri(source, UriKind.Relative);
var resourcePath = ResourceDictionary.RDSourceTypeConverter.GetResourcePath(uri, rootTargetPath);
//fail early
if (XamlCTask.GetResourceIdForPath(module, resourcePath) == null)
if (XamlCTask.GetResourceIdForPath(context.Cache, module, resourcePath) == null)
throw new XamlParseException($"Resource '{source}' not found.", node);
yield return Create(Ldstr, resourcePath); //resourcePath
yield return Create(Ldtoken, module.ImportReference(((ILRootNode)rootNode).TypeReference));
yield return Create(Call, module.ImportMethodReference(("mscorlib", "System", "Type"), methodName: "GetTypeFromHandle", parameterTypes: new[] { ("mscorlib", "System", "RuntimeTypeHandle") }, isStatic: true));
yield return Create(Callvirt, module.ImportPropertyGetterReference(("mscorlib", "System", "Type"), propertyName: "Assembly", flatten: true)); //assembly
yield return Create(Call, module.ImportMethodReference(context.Cache, ("mscorlib", "System", "Type"), methodName: "GetTypeFromHandle", parameterTypes: new[] { ("mscorlib", "System", "RuntimeTypeHandle") }, isStatic: true));
yield return Create(Callvirt, module.ImportPropertyGetterReference(context.Cache, ("mscorlib", "System", "Type"), propertyName: "Assembly", flatten: true)); //assembly
foreach (var instruction in node.PushXmlLineInfo(context))
yield return instruction; //lineinfo
yield return Create(Call, module.ImportMethodReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.StyleSheets", "StyleSheet"),
yield return Create(Call, module.ImportMethodReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.StyleSheets", "StyleSheet"),
methodName: "FromResource",
parameterTypes: new[] { ("mscorlib", "System", "String"), ("mscorlib", "System.Reflection", "Assembly"), ("System.Xml.ReaderWriter", "System.Xml", "IXmlLineInfo") },
isStatic: true));
}
//the variable is of type `object`. fix that
var vardef = new VariableDefinition(module.ImportReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.StyleSheets", "StyleSheet")));
var vardef = new VariableDefinition(module.ImportReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.StyleSheets", "StyleSheet")));
yield return Create(Stloc, vardef);
vardefref.VariableDefinition = vardef;
}

Просмотреть файл

@ -48,8 +48,8 @@ namespace Microsoft.Maui.Controls.Build.Tasks
public void Visit(ElementNode node, INode parentNode)
{
var typeref = Module.ImportReference(node.XmlType.GetTypeReference(Module, node));
TypeDefinition typedef = typeref.ResolveCached();
var typeref = Module.ImportReference(node.XmlType.GetTypeReference(Context.Cache, Module, node));
TypeDefinition typedef = typeref.ResolveCached(Context.Cache);
if (IsXaml2009LanguagePrimitive(node))
{
@ -64,7 +64,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
//if this is a MarkupExtension that can be compiled directly, compile and returns the value
var compiledMarkupExtensionName = typeref
.GetCustomAttribute(Module, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "ProvideCompiledAttribute"))
.GetCustomAttribute(Context.Cache, Module, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "ProvideCompiledAttribute"))
?.ConstructorArguments?[0].Value as string;
Type compiledMarkupExtensionType;
ICompiledMarkupExtension markupProvider;
@ -99,7 +99,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
if (node.Properties.ContainsKey(XmlName.xArguments) && !node.Properties.ContainsKey(XmlName.xFactoryMethod))
{
factoryCtorInfo = typedef.AllMethods().FirstOrDefault(md => md.methodDef.IsConstructor &&
factoryCtorInfo = typedef.AllMethods(Context.Cache).FirstOrDefault(md => md.methodDef.IsConstructor &&
!md.methodDef.IsStatic &&
md.methodDef.HasParameters &&
md.methodDef.MatchXArguments(node, typeref, Module, Context)).methodDef;
@ -110,7 +110,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
else if (node.Properties.ContainsKey(XmlName.xFactoryMethod))
{
var factoryMethod = (string)(node.Properties[XmlName.xFactoryMethod] as ValueNode).Value;
factoryMethodInfo = typedef.AllMethods().FirstOrDefault(md => !md.methodDef.IsConstructor &&
factoryMethodInfo = typedef.AllMethods(Context.Cache).FirstOrDefault(md => !md.methodDef.IsConstructor &&
md.methodDef.Name == factoryMethod &&
md.methodDef.IsStatic &&
md.methodDef.MatchXArguments(node, typeref, Module, Context)).methodDef;
@ -302,13 +302,13 @@ namespace Microsoft.Maui.Controls.Build.Tasks
ValueNode vnode = null;
if (node is IElementNode && (vardef = Context.Variables[node as IElementNode]) != null)
foreach (var instruction in vardef.LoadAs(parameter.ParameterType.ResolveGenericParameters(ctorinfo), Module))
foreach (var instruction in vardef.LoadAs(Context.Cache, parameter.ParameterType.ResolveGenericParameters(ctorinfo), Module))
yield return instruction;
else if ((vnode = node as ValueNode) != null)
{
foreach (var instruction in vnode.PushConvertedValue(Context,
parameter.ParameterType,
new ICustomAttributeProvider[] { parameter, parameter.ParameterType.ResolveCached() },
new ICustomAttributeProvider[] { parameter, parameter.ParameterType.ResolveCached(Context.Cache) },
enode.PushServiceProvider(Context), false, true))
yield return instruction;
}
@ -339,13 +339,13 @@ namespace Microsoft.Maui.Controls.Build.Tasks
ValueNode vnode = null;
if (arg is IElementNode && (vardef = Context.Variables[arg as IElementNode]) != null)
foreach (var instruction in vardef.LoadAs(parameter.ParameterType.ResolveGenericParameters(factoryCtorInfo), Module))
foreach (var instruction in vardef.LoadAs(Context.Cache, parameter.ParameterType.ResolveGenericParameters(factoryCtorInfo), Module))
yield return instruction;
else if ((vnode = arg as ValueNode) != null)
{
foreach (var instruction in vnode.PushConvertedValue(Context,
parameter.ParameterType,
new ICustomAttributeProvider[] { parameter, parameter.ParameterType.ResolveCached() },
new ICustomAttributeProvider[] { parameter, parameter.ParameterType.ResolveCached(Context.Cache) },
enode.PushServiceProvider(Context), false, true))
yield return instruction;
}
@ -449,7 +449,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
break;
case "System.Object":
var ctorinfo =
module.TypeSystem.Object.ResolveCached()
module.TypeSystem.Object.ResolveCached(Context.Cache)
.Methods.FirstOrDefault(md => md.IsConstructor && !md.HasParameters);
var ctor = module.ImportReference(ctorinfo);
yield return Create(Newobj, ctor);
@ -464,7 +464,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
decimal outdecimal;
if (hasValue && decimal.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out outdecimal))
{
var vardef = new VariableDefinition(module.ImportReference(("mscorlib", "System", "Decimal")));
var vardef = new VariableDefinition(module.ImportReference(Context.Cache, ("mscorlib", "System", "Decimal")));
Context.Body.Variables.Add(vardef);
//Use an extra temp var so we can push the value to the stack, just like other cases
// IL_0003: ldstr "adecimal"
@ -475,11 +475,11 @@ namespace Microsoft.Maui.Controls.Build.Tasks
// IL_0016: pop
yield return Create(Ldstr, valueString);
yield return Create(Ldc_I4, 0x6f); //NumberStyles.Number
yield return Create(Call, module.ImportPropertyGetterReference(("mscorlib", "System.Globalization", "CultureInfo"),
yield return Create(Call, module.ImportPropertyGetterReference(Context.Cache, ("mscorlib", "System.Globalization", "CultureInfo"),
propertyName: "InvariantCulture",
isStatic: true));
yield return Create(Ldloca, vardef);
yield return Create(Call, module.ImportMethodReference(("mscorlib", "System", "Decimal"),
yield return Create(Call, module.ImportMethodReference(Context.Cache, ("mscorlib", "System", "Decimal"),
methodName: "TryParse",
parameterTypes: new[] {
("mscorlib", "System", "String"),
@ -494,7 +494,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
else
{
yield return Create(Ldc_I4_0);
yield return Create(Newobj, module.ImportCtorReference(("mscorlib", "System", "Decimal"), parameterTypes: new[] { ("mscorlib", "System", "Int32") }));
yield return Create(Newobj, module.ImportCtorReference(Context.Cache, ("mscorlib", "System", "Decimal"), parameterTypes: new[] { ("mscorlib", "System", "Int32") }));
}
break;
case "System.Single":
@ -512,14 +512,14 @@ namespace Microsoft.Maui.Controls.Build.Tasks
case "System.TimeSpan":
if (hasValue && TimeSpan.TryParse(valueString, CultureInfo.InvariantCulture, out TimeSpan outspan))
{
var vardef = new VariableDefinition(module.ImportReference(("mscorlib", "System", "TimeSpan")));
var vardef = new VariableDefinition(module.ImportReference(Context.Cache, ("mscorlib", "System", "TimeSpan")));
Context.Body.Variables.Add(vardef);
//Use an extra temp var so we can push the value to the stack, just like other cases
yield return Create(Ldstr, valueString);
yield return Create(Call, module.ImportPropertyGetterReference(("mscorlib", "System.Globalization", "CultureInfo"),
yield return Create(Call, module.ImportPropertyGetterReference(Context.Cache, ("mscorlib", "System.Globalization", "CultureInfo"),
propertyName: "InvariantCulture", isStatic: true));
yield return Create(Ldloca, vardef);
yield return Create(Call, module.ImportMethodReference(("mscorlib", "System", "TimeSpan"),
yield return Create(Call, module.ImportMethodReference(Context.Cache, ("mscorlib", "System", "TimeSpan"),
methodName: "TryParse",
parameterTypes: new[] {
("mscorlib", "System", "String"),
@ -533,19 +533,19 @@ namespace Microsoft.Maui.Controls.Build.Tasks
else
{
yield return Create(Ldc_I8, 0L);
yield return Create(Newobj, module.ImportCtorReference(("mscorlib", "System", "TimeSpan"), parameterTypes: new[] { ("mscorlib", "System", "Int64") }));
yield return Create(Newobj, module.ImportCtorReference(Context.Cache, ("mscorlib", "System", "TimeSpan"), parameterTypes: new[] { ("mscorlib", "System", "Int64") }));
}
break;
case "System.Uri":
if (hasValue && Uri.TryCreate(valueString, UriKind.RelativeOrAbsolute, out _))
{
var vardef = new VariableDefinition(module.ImportReference(("System", "System", "Uri")));
var vardef = new VariableDefinition(module.ImportReference(Context.Cache, ("System", "System", "Uri")));
Context.Body.Variables.Add(vardef);
//Use an extra temp var so we can push the value to the stack, just like other cases
yield return Create(Ldstr, valueString);
yield return Create(Ldc_I4, (int)UriKind.RelativeOrAbsolute);
yield return Create(Ldloca, vardef);
yield return Create(Call, module.ImportMethodReference(("System", "System", "Uri"),
yield return Create(Call, module.ImportMethodReference(Context.Cache, ("System", "System", "Uri"),
methodName: "TryCreate",
parameterTypes: new[] {
("mscorlib", "System", "String"),
@ -560,7 +560,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
yield return Create(Ldnull);
break;
default:
var defaultCtor = module.ImportCtorReference(typedef, parameterTypes: null);
var defaultCtor = module.ImportCtorReference(Context.Cache, typedef, parameterTypes: null);
if (defaultCtor != null)
yield return Create(Newobj, defaultCtor);
else

Просмотреть файл

@ -11,6 +11,8 @@ namespace Microsoft.Maui.Controls.Build.Tasks
{
public class DebugXamlCTask : XamlTask
{
readonly XamlCache cache = new();
public override bool Execute(out IList<Exception> thrownExceptions)
{
thrownExceptions = null;
@ -42,7 +44,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
foreach (var resource in module.Resources.OfType<EmbeddedResource>())
{
LoggingHelper.LogMessage(Low, $"{new string(' ', 4)}Resource: {resource.Name}");
if (!resource.IsXaml(module, out var classname))
if (!resource.IsXaml(cache, module, out var classname))
{
LoggingHelper.LogMessage(Low, $"{new string(' ', 6)}skipped.");
continue;

Просмотреть файл

@ -190,7 +190,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
//The order of lookup is to look for the Extension-suffixed class name first and then look for the class name without the Extension suffix.
XmlType type = new XmlType(namespaceuri, name + "Extension", typeArguments);
if (!type.TryGetTypeReference(contextProvider.Context.Module, null, out _))
if (!type.TryGetTypeReference(contextProvider.Context.Cache, contextProvider.Context.Module, null, out _))
type = new XmlType(namespaceuri, name, typeArguments);
if (type == null)

Просмотреть файл

@ -9,7 +9,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
{
class ILContext
{
public ILContext(ILProcessor il, MethodBody body, ModuleDefinition module, FieldDefinition parentContextValues = null)
public ILContext(ILProcessor il, MethodBody body, ModuleDefinition module, XamlCache cache, FieldDefinition parentContextValues = null)
{
IL = il;
Body = body;
@ -19,8 +19,11 @@ namespace Microsoft.Maui.Controls.Build.Tasks
TypeExtensions = new Dictionary<INode, TypeReference>();
ParentContextValues = parentContextValues;
Module = module;
Cache = cache;
}
public XamlCache Cache { get; private set; }
public Dictionary<IValueNode, object> Values { get; private set; }
public Dictionary<IElementNode, VariableDefinition> Variables { get; private set; }

Просмотреть файл

@ -34,7 +34,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
paramType = (declaringTypeRef as GenericInstanceType).GenericArguments[index];
}
var argType = context.Variables[arguments[i] as IElementNode].VariableType;
if (!argType.InheritsFromOrImplements(paramType))
if (!argType.InheritsFromOrImplements(context.Cache, paramType))
return false;
}
return true;

Просмотреть файл

@ -8,35 +8,23 @@ namespace Microsoft.Maui.Controls.Build.Tasks
{
static class ModuleDefinitionExtensions
{
static Dictionary<(ModuleDefinition module, string typeKey), TypeReference> TypeRefCache = new Dictionary<(ModuleDefinition module, string typeKey), TypeReference>();
public static TypeReference ImportReference(this ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName) type)
{
var typeKey = type.ToString();
if (!TypeRefCache.TryGetValue((module, typeKey), out var typeRef))
TypeRefCache.Add((module, typeKey), typeRef = module.ImportReference(module.GetTypeDefinition(type)));
return typeRef;
}
public static TypeReference ImportReference(this ModuleDefinition module, XamlCache cache, (string assemblyName, string clrNamespace, string typeName) type) => cache.GetOrAddTypeReference(module, type);
public static TypeReference ImportReference(this ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName) type, (string assemblyName, string clrNamespace, string typeName)[] classArguments)
public static TypeReference ImportReference(this ModuleDefinition module, XamlCache cache, (string assemblyName, string clrNamespace, string typeName) type, (string assemblyName, string clrNamespace, string typeName)[] classArguments)
{
var typeKey = $"{type}<{string.Join(",", classArguments)}>";
if (!TypeRefCache.TryGetValue((module, typeKey), out var typeRef))
TypeRefCache.Add((module, typeKey), typeRef = module.ImportReference(module.ImportReference(type).MakeGenericInstanceType(classArguments.Select(gp => module.GetTypeDefinition((gp.assemblyName, gp.clrNamespace, gp.typeName))).ToArray())));
return typeRef;
return cache.GetOrAddTypeReference(module, typeKey, x => module.ImportReference(module.ImportReference(cache, type).MakeGenericInstanceType(classArguments.Select(gp => module.GetTypeDefinition(cache, (gp.assemblyName, gp.clrNamespace, gp.typeName))).ToArray())));
}
public static TypeReference ImportArrayReference(this ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName) type)
public static TypeReference ImportArrayReference(this ModuleDefinition module, XamlCache cache, (string assemblyName, string clrNamespace, string typeName) type)
{
var typeKey = "${type}[]";
if (!TypeRefCache.TryGetValue((module, typeKey), out var typeRef))
TypeRefCache.Add((module, typeKey), typeRef = module.ImportReference(module.ImportReference(type).MakeArrayType()));
return typeRef;
var typeKey = $"{type}[]";
return cache.GetOrAddTypeReference(module, typeKey, x => module.ImportReference(module.ImportReference(cache, type).MakeArrayType()));
}
static Dictionary<(ModuleDefinition module, string methodRefKey), MethodReference> MethodRefCache = new Dictionary<(ModuleDefinition module, string methodRefKey), MethodReference>();
static MethodReference ImportCtorReference(this ModuleDefinition module, TypeReference type, TypeReference[] classArguments, Func<MethodDefinition, bool> predicate)
static MethodReference ImportCtorReference(this ModuleDefinition module, XamlCache cache, TypeReference type, TypeReference[] classArguments, Func<MethodDefinition, bool> predicate)
{
var ctor = module.ImportReference(type).ResolveCached().Methods.FirstOrDefault(md => !md.IsPrivate && !md.IsStatic && md.IsConstructor && (predicate?.Invoke(md) ?? true));
var ctor = module.ImportReference(type).ResolveCached(cache).Methods.FirstOrDefault(md => !md.IsPrivate && !md.IsStatic && md.IsConstructor && (predicate?.Invoke(md) ?? true));
if (ctor is null)
return null;
var ctorRef = module.ImportReference(ctor);
@ -45,99 +33,79 @@ namespace Microsoft.Maui.Controls.Build.Tasks
return module.ImportReference(ctorRef.ResolveGenericParameters(type.MakeGenericInstanceType(classArguments), module));
}
public static MethodReference ImportCtorReference(this ModuleDefinition module, TypeReference type, TypeReference[] parameterTypes)
public static MethodReference ImportCtorReference(this ModuleDefinition module, XamlCache cache, TypeReference type, TypeReference[] parameterTypes)
{
var ctorKey = $"{type}.ctor({(parameterTypes == null ? "" : string.Join(",", parameterTypes.Select(SerializeTypeReference)))})";
if (MethodRefCache.TryGetValue((module, ctorKey), out var ctorRef))
return ctorRef;
ctorRef = module.ImportCtorReference(type, classArguments: null, predicate: md =>
return cache.GetOrAddMethodReference(module, ctorKey, x => x.module.ImportCtorReference(cache, type, classArguments: null, predicate: md =>
{
if (md.Parameters.Count != (parameterTypes?.Length ?? 0))
return false;
for (var i = 0; i < md.Parameters.Count; i++)
if (!TypeRefComparer.Default.Equals(md.Parameters[i].ParameterType, module.ImportReference(parameterTypes[i])))
if (!TypeRefComparer.Default.Equals(md.Parameters[i].ParameterType, x.module.ImportReference(parameterTypes[i])))
return false;
return true;
});
MethodRefCache.Add((module, ctorKey), ctorRef);
return ctorRef;
}));
}
public static MethodReference ImportCtorReference(this ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName) type, int paramCount)
public static MethodReference ImportCtorReference(this ModuleDefinition module, XamlCache cache, (string assemblyName, string clrNamespace, string typeName) type, int paramCount)
{
var ctorKey = $"{type}.ctor({(string.Join(",", Enumerable.Repeat("_", paramCount)))})";
if (!MethodRefCache.TryGetValue((module, ctorKey), out var ctorRef))
MethodRefCache.Add((module, ctorKey), ctorRef = module.ImportCtorReference(module.GetTypeDefinition(type), null, md => md.Parameters.Count == paramCount));
return ctorRef;
return cache.GetOrAddMethodReference(module, ctorKey, x => x.module.ImportCtorReference(cache, x.module.GetTypeDefinition(cache, type), null, md => md.Parameters.Count == paramCount));
}
public static MethodReference ImportCtorReference(this ModuleDefinition module, TypeReference type, int paramCount)
public static MethodReference ImportCtorReference(this ModuleDefinition module, XamlCache cache, TypeReference type, int paramCount)
{
var ctorKey = $"{type}.ctor({(string.Join(",", Enumerable.Repeat("_", paramCount)))})";
if (!MethodRefCache.TryGetValue((module, ctorKey), out var ctorRef))
MethodRefCache.Add((module, ctorKey), ctorRef = module.ImportCtorReference(type, null, md => md.Parameters.Count == paramCount));
return ctorRef;
return cache.GetOrAddMethodReference(module, ctorKey, x => x.module.ImportCtorReference(cache, type, null, md => md.Parameters.Count == paramCount));
}
public static MethodReference ImportCtorReference(this ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName) type, int paramCount, (string assemblyName, string clrNamespace, string typeName)[] classArguments)
public static MethodReference ImportCtorReference(this ModuleDefinition module, XamlCache cache, (string assemblyName, string clrNamespace, string typeName) type, int paramCount, (string assemblyName, string clrNamespace, string typeName)[] classArguments)
{
var ctorKey = $"{type}<{(string.Join(",", classArguments))}>.ctor({(string.Join(",", Enumerable.Repeat("_", paramCount)))})";
if (!MethodRefCache.TryGetValue((module, ctorKey), out var ctorRef))
MethodRefCache.Add((module, ctorKey), ctorRef = module.ImportCtorReference(module.GetTypeDefinition(type), classArguments.Select(module.GetTypeDefinition).ToArray(), md => md.Parameters.Count == paramCount));
return ctorRef;
return cache.GetOrAddMethodReference(module, ctorKey, x => x.module.ImportCtorReference(cache, x.module.GetTypeDefinition(cache, type), classArguments.Select(args => x.module.GetTypeDefinition(cache, args)).ToArray(), md => md.Parameters.Count == paramCount));
}
public static MethodReference ImportCtorReference(this ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName) type, int paramCount, TypeReference[] classArguments)
public static MethodReference ImportCtorReference(this ModuleDefinition module, XamlCache cache, (string assemblyName, string clrNamespace, string typeName) type, int paramCount, TypeReference[] classArguments)
{
var ctorKey = $"{type}<{string.Join(",", classArguments.Select(SerializeTypeReference))}>.ctor({(string.Join(",", Enumerable.Repeat("_", paramCount)))})";
if (!MethodRefCache.TryGetValue((module, ctorKey), out var ctorRef))
MethodRefCache.Add((module, ctorKey), ctorRef = module.ImportCtorReference(module.GetTypeDefinition(type), classArguments, predicate: md => md.Parameters.Count == paramCount));
return ctorRef;
return cache.GetOrAddMethodReference(module, ctorKey, x => x.module.ImportCtorReference(cache, x.module.GetTypeDefinition(cache, type), classArguments, predicate: md => md.Parameters.Count == paramCount));
}
public static MethodReference ImportCtorReference(this ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName) type, (string assemblyName, string clrNamespace, string typeName)[] parameterTypes, (string assemblyName, string clrNamespace, string typeName)[] classArguments)
public static MethodReference ImportCtorReference(this ModuleDefinition module, XamlCache cache, (string assemblyName, string clrNamespace, string typeName) type, (string assemblyName, string clrNamespace, string typeName)[] parameterTypes, (string assemblyName, string clrNamespace, string typeName)[] classArguments)
{
var ctorKey = $"{type}<{(string.Join(",", classArguments))}>.ctor({(parameterTypes == null ? "" : string.Join(",", parameterTypes))})";
if (MethodRefCache.TryGetValue((module, ctorKey), out var ctorRef))
return ctorRef;
ctorRef = module.ImportCtorReference(module.GetTypeDefinition(type), classArguments.Select(module.GetTypeDefinition).ToArray(), md =>
return cache.GetOrAddMethodReference(module, ctorKey, x => x.module.ImportCtorReference(cache, x.module.GetTypeDefinition(cache, type), classArguments.Select(args => x.module.GetTypeDefinition(cache, args)).ToArray(), md =>
{
if (md.Parameters.Count != (parameterTypes?.Length ?? 0))
return false;
for (var i = 0; i < md.Parameters.Count; i++)
if (!TypeRefComparer.Default.Equals(md.Parameters[i].ParameterType, module.ImportReference(parameterTypes[i])))
if (!TypeRefComparer.Default.Equals(md.Parameters[i].ParameterType, x.module.ImportReference(cache, parameterTypes[i])))
return false;
return true;
});
MethodRefCache.Add((module, ctorKey), ctorRef);
return ctorRef;
}));
}
public static MethodReference ImportCtorReference(this ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName) type, (string assemblyName, string clrNamespace, string typeName)[] parameterTypes)
public static MethodReference ImportCtorReference(this ModuleDefinition module, XamlCache cache, (string assemblyName, string clrNamespace, string typeName) type, (string assemblyName, string clrNamespace, string typeName)[] parameterTypes)
{
var ctorKey = $"{type}.ctor({(parameterTypes == null ? "" : string.Join(",", parameterTypes))})";
if (MethodRefCache.TryGetValue((module, ctorKey), out var ctorRef))
return ctorRef;
ctorRef = module.ImportCtorReference(module.GetTypeDefinition(type), classArguments: null, predicate: md =>
return cache.GetOrAddMethodReference(module, ctorKey, x => x.module.ImportCtorReference(cache, x.module.GetTypeDefinition(cache, type), classArguments: null, predicate: md =>
{
if (md.Parameters.Count != (parameterTypes?.Length ?? 0))
return false;
for (var i = 0; i < md.Parameters.Count; i++)
if (!TypeRefComparer.Default.Equals(md.Parameters[i].ParameterType, module.ImportReference(parameterTypes[i])))
if (!TypeRefComparer.Default.Equals(md.Parameters[i].ParameterType, x.module.ImportReference(cache, parameterTypes[i])))
return false;
return true;
});
MethodRefCache.Add((module, ctorKey), ctorRef);
return ctorRef;
}));
}
static MethodReference ImportPropertyGetterReference(this ModuleDefinition module, TypeReference type, string propertyName, Func<PropertyDefinition, bool> predicate = null, bool flatten = false, bool caseSensitive = true)
static MethodReference ImportPropertyGetterReference(this ModuleDefinition module, XamlCache cache, TypeReference type, string propertyName, Func<PropertyDefinition, bool> predicate = null, bool flatten = false, bool caseSensitive = true)
{
var properties = module.ImportReference(type).Resolve().Properties;
var getter = module
.ImportReference(type)
.ResolveCached()
.Properties(flatten)
.ResolveCached(cache)
.Properties(cache, flatten)
.FirstOrDefault(pd =>
string.Equals(pd.Name, propertyName, caseSensitive ? StringComparison.InvariantCulture : StringComparison.InvariantCultureIgnoreCase)
&& !pd.GetMethod.IsPrivate
@ -146,19 +114,17 @@ namespace Microsoft.Maui.Controls.Build.Tasks
return getter == null ? null : module.ImportReference(getter);
}
public static MethodReference ImportPropertyGetterReference(this ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName) type, string propertyName, bool isStatic = false, bool flatten = false, bool caseSensitive = true)
public static MethodReference ImportPropertyGetterReference(this ModuleDefinition module, XamlCache cache, (string assemblyName, string clrNamespace, string typeName) type, string propertyName, bool isStatic = false, bool flatten = false, bool caseSensitive = true)
{
var getterKey = $"{(isStatic ? "static " : "")}{type}.get_{propertyName}{(flatten ? "*" : "")}";
if (!MethodRefCache.TryGetValue((module, getterKey), out var methodReference))
MethodRefCache.Add((module, getterKey), methodReference = module.ImportPropertyGetterReference(module.GetTypeDefinition(type), propertyName, pd => pd.GetMethod.IsStatic == isStatic, flatten, caseSensitive: caseSensitive));
return methodReference;
return cache.GetOrAddMethodReference(module, getterKey, x => x.module.ImportPropertyGetterReference(cache, x.module.GetTypeDefinition(cache, type), propertyName, pd => pd.GetMethod.IsStatic == isStatic, flatten, caseSensitive: caseSensitive));
}
static MethodReference ImportPropertySetterReference(this ModuleDefinition module, TypeReference type, string propertyName, Func<PropertyDefinition, bool> predicate = null)
static MethodReference ImportPropertySetterReference(this ModuleDefinition module, XamlCache cache, TypeReference type, string propertyName, Func<PropertyDefinition, bool> predicate = null)
{
var setter = module
.ImportReference(type)
.ResolveCached()
.ResolveCached(cache)
.Properties
.FirstOrDefault(pd =>
pd.Name == propertyName
@ -168,19 +134,17 @@ namespace Microsoft.Maui.Controls.Build.Tasks
return setter == null ? null : module.ImportReference(setter);
}
public static MethodReference ImportPropertySetterReference(this ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName) type, string propertyName, bool isStatic = false)
public static MethodReference ImportPropertySetterReference(this ModuleDefinition module, XamlCache cache, (string assemblyName, string clrNamespace, string typeName) type, string propertyName, bool isStatic = false)
{
var setterKey = $"{(isStatic ? "static " : "")}{type}.set{propertyName}";
if (!MethodRefCache.TryGetValue((module, setterKey), out var methodReference))
MethodRefCache.Add((module, setterKey), methodReference = module.ImportPropertySetterReference(module.GetTypeDefinition(type), propertyName, pd => pd.SetMethod.IsStatic == isStatic));
return methodReference;
return cache.GetOrAddMethodReference(module, setterKey, x => x.module.ImportPropertySetterReference(cache, x.module.GetTypeDefinition(cache, type), propertyName, pd => pd.SetMethod.IsStatic == isStatic));
}
static MethodReference ImportMethodReference(this ModuleDefinition module, TypeReference type, string methodName, Func<MethodDefinition, bool> predicate = null, TypeReference[] classArguments = null)
static MethodReference ImportMethodReference(this ModuleDefinition module, XamlCache cache, TypeReference type, string methodName, Func<MethodDefinition, bool> predicate = null, TypeReference[] classArguments = null)
{
var method = module
.ImportReference(type)
.ResolveCached()
.ResolveCached(cache)
.Methods
.FirstOrDefault(md =>
!md.IsConstructor
@ -196,13 +160,14 @@ namespace Microsoft.Maui.Controls.Build.Tasks
}
public static MethodReference ImportMethodReference(this ModuleDefinition module,
XamlCache cache,
TypeReference type,
string methodName,
TypeReference[] parameterTypes = null,
TypeReference[] classArguments = null,
bool isStatic = false)
{
return module.ImportMethodReference(type,
return module.ImportMethodReference(cache, type,
methodName: methodName,
predicate: md =>
{
@ -219,6 +184,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
}
public static MethodReference ImportMethodReference(this ModuleDefinition module,
XamlCache cache,
(string assemblyName, string clrNamespace, string typeName) type,
string methodName,
(string assemblyName, string clrNamespace, string typeName)[] parameterTypes,
@ -226,9 +192,8 @@ namespace Microsoft.Maui.Controls.Build.Tasks
bool isStatic = false)
{
var methodKey = $"{(isStatic ? "static " : "")}{type}<{(classArguments == null ? "" : string.Join(",", classArguments))}>.({(parameterTypes == null ? "" : string.Join(",", parameterTypes))})";
if (MethodRefCache.TryGetValue((module, methodKey), out var methodReference))
return methodReference;
methodReference = module.ImportMethodReference(module.GetTypeDefinition(type),
return cache.GetOrAddMethodReference(module, methodKey, x => x.module.ImportMethodReference(cache,
x.module.GetTypeDefinition(cache, type),
methodName: methodName,
predicate: md =>
{
@ -237,16 +202,15 @@ namespace Microsoft.Maui.Controls.Build.Tasks
if (md.Parameters.Count != (parameterTypes?.Length ?? 0))
return false;
for (var i = 0; i < md.Parameters.Count; i++)
if (!TypeRefComparer.Default.Equals(md.Parameters[i].ParameterType, module.ImportReference(parameterTypes[i])))
if (!TypeRefComparer.Default.Equals(md.Parameters[i].ParameterType, x.module.ImportReference(cache, parameterTypes[i])))
return false;
return true;
},
classArguments: classArguments?.Select(gp => module.GetTypeDefinition((gp.assemblyName, gp.clrNamespace, gp.typeName))).ToArray());
MethodRefCache.Add((module, methodKey), methodReference);
return methodReference;
classArguments: classArguments?.Select(gp => x.module.GetTypeDefinition(cache, (gp.assemblyName, gp.clrNamespace, gp.typeName))).ToArray()));
}
public static MethodReference ImportMethodReference(this ModuleDefinition module,
XamlCache cache,
(string assemblyName, string clrNamespace, string typeName) type,
string methodName,
int paramCount,
@ -254,9 +218,8 @@ namespace Microsoft.Maui.Controls.Build.Tasks
bool isStatic = false)
{
var methodKey = $"{(isStatic ? "static " : "")}{type}<{(classArguments == null ? "" : string.Join(",", classArguments))}>.({(string.Join(",", Enumerable.Repeat("_", paramCount)))})";
if (MethodRefCache.TryGetValue((module, methodKey), out var methodReference))
return methodReference;
methodReference = module.ImportMethodReference(module.GetTypeDefinition(type),
return cache.GetOrAddMethodReference(module, methodKey, x => x.module.ImportMethodReference(cache,
x.module.GetTypeDefinition(cache, type),
methodName: methodName,
predicate: md =>
{
@ -266,17 +229,14 @@ namespace Microsoft.Maui.Controls.Build.Tasks
return false;
return true;
},
classArguments: classArguments?.Select(gp => module.GetTypeDefinition((gp.assemblyName, gp.clrNamespace, gp.typeName))).ToArray());
MethodRefCache.Add((module, methodKey), methodReference);
return methodReference;
classArguments: classArguments?.Select(gp => x.module.GetTypeDefinition(cache, (gp.assemblyName, gp.clrNamespace, gp.typeName))).ToArray()));
}
static Dictionary<(ModuleDefinition module, string fieldRefKey), FieldReference> FieldRefCache = new Dictionary<(ModuleDefinition module, string fieldRefKey), FieldReference>();
static FieldReference ImportFieldReference(this ModuleDefinition module, TypeReference type, string fieldName, Func<FieldDefinition, bool> predicate = null, bool caseSensitive = true)
static FieldReference ImportFieldReference(this ModuleDefinition module, XamlCache cache, TypeReference type, string fieldName, Func<FieldDefinition, bool> predicate = null, bool caseSensitive = true)
{
var field = module
.ImportReference(type)
.ResolveCached()
.ResolveCached(cache)
.Fields
.FirstOrDefault(fd =>
string.Equals(fd.Name, fieldName, caseSensitive ? StringComparison.InvariantCulture : StringComparison.InvariantCultureIgnoreCase)
@ -284,53 +244,47 @@ namespace Microsoft.Maui.Controls.Build.Tasks
return field == null ? null : module.ImportReference(field);
}
public static FieldReference ImportFieldReference(this ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName) type, string fieldName, bool isStatic = false, bool caseSensitive = true)
public static FieldReference ImportFieldReference(this ModuleDefinition module, XamlCache cache, (string assemblyName, string clrNamespace, string typeName) type, string fieldName, bool isStatic = false, bool caseSensitive = true)
{
var fieldKey = $"{(isStatic ? "static " : "")}{type}.{(caseSensitive ? fieldName : fieldName.ToLowerInvariant())}";
if (!FieldRefCache.TryGetValue((module, fieldKey), out var fieldReference))
FieldRefCache.Add((module, fieldKey), fieldReference = module.ImportFieldReference(module.GetTypeDefinition(type), fieldName: fieldName, predicate: fd => fd.IsStatic == isStatic, caseSensitive: caseSensitive));
return fieldReference;
return cache.GetOrAddFieldReference((module, fieldKey), _ => module.ImportFieldReference(cache, module.GetTypeDefinition(cache, type), fieldName: fieldName, predicate: fd => fd.IsStatic == isStatic, caseSensitive: caseSensitive));
}
static Dictionary<(ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName)), TypeDefinition> typeDefCache
= new Dictionary<(ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName)), TypeDefinition>();
public static TypeDefinition GetTypeDefinition(this ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName) type)
public static TypeDefinition GetTypeDefinition(this ModuleDefinition module, XamlCache cache, (string assemblyName, string clrNamespace, string typeName) type)
{
if (typeDefCache.TryGetValue((module, type), out TypeDefinition cachedTypeDefinition))
return cachedTypeDefinition;
var asm = module.Assembly.Name.Name == type.assemblyName
? module.Assembly
: module.AssemblyResolver.Resolve(AssemblyNameReference.Parse(type.assemblyName));
var typeDef = asm.MainModule.GetType($"{type.clrNamespace}.{type.typeName}");
if (typeDef != null)
return cache.GetOrAddTypeDefinition(module, type, x =>
{
typeDefCache.Add((module, type), typeDef);
return typeDef;
}
var exportedType = asm.MainModule.ExportedTypes.FirstOrDefault(
arg => arg.IsForwarder && arg.Namespace == type.clrNamespace && arg.Name == type.typeName);
if (exportedType != null)
{
typeDef = exportedType.Resolve();
typeDefCache.Add((module, type), typeDef);
return typeDef;
}
var asm = module.Assembly.Name.Name == type.assemblyName
? module.Assembly
: module.AssemblyResolver.Resolve(AssemblyNameReference.Parse(type.assemblyName));
var typeDef = asm.MainModule.GetType($"{type.clrNamespace}.{type.typeName}");
if (typeDef != null)
{
return typeDef;
}
var exportedType = asm.MainModule.ExportedTypes.FirstOrDefault(
arg => arg.IsForwarder && arg.Namespace == type.clrNamespace && arg.Name == type.typeName);
if (exportedType != null)
{
typeDef = exportedType.Resolve();
return typeDef;
}
//I hate you, netstandard
if (type.assemblyName == "mscorlib" && type.clrNamespace == "System.Reflection")
return module.GetTypeDefinition(("System.Reflection", type.clrNamespace, type.typeName));
return null;
//I hate you, netstandard
if (type.assemblyName == "mscorlib" && type.clrNamespace == "System.Reflection")
return module.GetTypeDefinition(cache, ("System.Reflection", type.clrNamespace, type.typeName));
return null;
});
}
static IEnumerable<PropertyDefinition> Properties(this TypeDefinition typedef, bool flatten)
static IEnumerable<PropertyDefinition> Properties(this TypeDefinition typedef, XamlCache cache, bool flatten)
{
foreach (var property in typedef.Properties)
yield return property;
if (!flatten || typedef.BaseType == null)
yield break;
foreach (var property in typedef.BaseType.ResolveCached().Properties(true))
foreach (var property in typedef.BaseType.ResolveCached(cache).Properties(cache, flatten: true))
yield return property;
}

Просмотреть файл

@ -37,8 +37,8 @@ namespace Microsoft.Maui.Controls.Build.Tasks
public static bool CanConvertValue(this ValueNode node, ILContext context, FieldReference bpRef)
{
var module = context.Body.Method.Module;
var targetTypeRef = bpRef.GetBindablePropertyType(node, module);
var typeConverter = bpRef.GetBindablePropertyTypeConverter(module);
var targetTypeRef = bpRef.GetBindablePropertyType(context.Cache, node, module);
var typeConverter = bpRef.GetBindablePropertyTypeConverter(context.Cache, module);
return node.CanConvertValue(context, targetTypeRef, typeConverter);
}
@ -52,9 +52,9 @@ namespace Microsoft.Maui.Controls.Build.Tasks
return true;
//check if it's assignable from a string
if (targetTypeRef.ResolveCached().FullName == "System.Nullable`1")
if (targetTypeRef.ResolveCached(context.Cache).FullName == "System.Nullable`1")
targetTypeRef = ((GenericInstanceType)targetTypeRef).GenericArguments[0];
if (targetTypeRef.ResolveCached().BaseType != null && targetTypeRef.ResolveCached().BaseType.FullName == "System.Enum")
if (targetTypeRef.ResolveCached(context.Cache).BaseType != null && targetTypeRef.ResolveCached(context.Cache).BaseType.FullName == "System.Enum")
return true;
if (targetTypeRef.FullName == "System.Char")
return true;
@ -90,7 +90,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
return true;
if (targetTypeRef.FullName == "System.Decimal")
return true;
var implicitOperator = module.TypeSystem.String.GetImplicitOperatorTo(targetTypeRef, module);
var implicitOperator = module.TypeSystem.String.GetImplicitOperatorTo(context.Cache, targetTypeRef, module);
if (implicitOperator != null)
return true;
return false;
@ -122,8 +122,8 @@ namespace Microsoft.Maui.Controls.Build.Tasks
IEnumerable<Instruction> pushServiceProvider, bool boxValueTypes, bool unboxValueTypes)
{
var module = context.Body.Method.Module;
var targetTypeRef = bpRef.GetBindablePropertyType(node, module);
var typeConverter = bpRef.GetBindablePropertyTypeConverter(module);
var targetTypeRef = bpRef.GetBindablePropertyType(context.Cache, node, module);
var typeConverter = bpRef.GetBindablePropertyTypeConverter(context.Cache, module);
return node.PushConvertedValue(context, targetTypeRef, typeConverter, pushServiceProvider, boxValueTypes,
unboxValueTypes);
@ -141,40 +141,19 @@ namespace Microsoft.Maui.Controls.Build.Tasks
}
}
static Dictionary<TypeReference, Type> KnownCompiledTypeConverters;
public static IEnumerable<Instruction> PushConvertedValue(this ValueNode node, ILContext context,
TypeReference targetTypeRef, TypeReference typeConverter, IEnumerable<Instruction> pushServiceProvider,
bool boxValueTypes, bool unboxValueTypes)
{
var module = context.Body.Method.Module;
if (KnownCompiledTypeConverters == null)
{
KnownCompiledTypeConverters = new Dictionary<TypeReference, Type>(TypeRefComparer.Default)
{
{ module.ImportReference(("Microsoft.Maui", "Microsoft.Maui.Converters", "ThicknessTypeConverter")), typeof(ThicknessTypeConverter) },
{ module.ImportReference(("Microsoft.Maui", "Microsoft.Maui.Converters", "CornerRadiusTypeConverter")), typeof(CornerRadiusTypeConverter) },
{ module.ImportReference(("Microsoft.Maui", "Microsoft.Maui.Converters", "EasingTypeConverter")), typeof(EasingTypeConverter) },
{ module.ImportReference(("Microsoft.Maui.Graphics", "Microsoft.Maui.Graphics.Converters", "ColorTypeConverter")), typeof(ColorTypeConverter) },
{ module.ImportReference(("Microsoft.Maui.Graphics", "Microsoft.Maui.Graphics.Converters", "PointTypeConverter")), typeof(PointTypeConverter) },
{ module.ImportReference(("Microsoft.Maui.Graphics", "Microsoft.Maui.Graphics.Converters", "RectTypeConverter")), typeof(RectangleTypeConverter) },
{ module.ImportReference(("Microsoft.Maui", "Microsoft.Maui.Converters", "FlexJustifyTypeConverter")), typeof(EnumTypeConverter<Layouts.FlexJustify>) },
{ module.ImportReference(("Microsoft.Maui", "Microsoft.Maui.Converters", "FlexDirectionTypeConverter")), typeof(EnumTypeConverter<Layouts.FlexDirection>) },
{ module.ImportReference(("Microsoft.Maui", "Microsoft.Maui.Converters", "FlexAlignContentTypeConverter")), typeof(EnumTypeConverter<Layouts.FlexAlignContent>) },
{ module.ImportReference(("Microsoft.Maui", "Microsoft.Maui.Converters", "FlexAlignItemsTypeConverter")), typeof(EnumTypeConverter<Layouts.FlexAlignItems>) },
{ module.ImportReference(("Microsoft.Maui", "Microsoft.Maui.Converters", "FlexAlignSelfTypeConverter")), typeof(EnumTypeConverter<Layouts.FlexAlignSelf>) },
{ module.ImportReference(("Microsoft.Maui", "Microsoft.Maui.Converters", "FlexWrapTypeConverter")), typeof(EnumTypeConverter<Layouts.FlexWrap>) },
{ module.ImportReference(("Microsoft.Maui", "Microsoft.Maui.Converters", "FlexBasisTypeConverter")), typeof(FlexBasisTypeConverter) },
};
}
var knownCompiledTypeConverters = context.Cache.GetKnownCompiledTypeConverters(module);
var str = (string)node.Value;
//If the TypeConverter has a ProvideCompiledAttribute that can be resolved, shortcut this
Type compiledConverterType;
if (typeConverter?.GetCustomAttribute(module, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "ProvideCompiledAttribute"))?.ConstructorArguments?.First().Value is string compiledConverterName
if (typeConverter?.GetCustomAttribute(context.Cache, module, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "ProvideCompiledAttribute"))?.ConstructorArguments?.First().Value is string compiledConverterName
&& (compiledConverterType = Type.GetType(compiledConverterName)) != null
|| (typeConverter != null && KnownCompiledTypeConverters.TryGetValue(typeConverter, out compiledConverterType)))
|| (typeConverter != null && knownCompiledTypeConverters.TryGetValue(typeConverter, out compiledConverterType)))
{
var compiledConverter = Activator.CreateInstance(compiledConverterType);
var converter = typeof(ICompiledTypeConverter).GetMethods().FirstOrDefault(md => md.Name == "ConvertFromString");
@ -202,14 +181,14 @@ namespace Microsoft.Maui.Controls.Build.Tasks
//If there's a [TypeConverter], use it
if (typeConverter != null)
{
var isExtendedConverter = typeConverter.ImplementsInterface(module.ImportReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "IExtendedTypeConverter")));
var typeConverterCtorRef = module.ImportCtorReference(typeConverter, paramCount: 0);
var isExtendedConverter = typeConverter.ImplementsInterface(context.Cache, module.ImportReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "IExtendedTypeConverter")));
var typeConverterCtorRef = module.ImportCtorReference(context.Cache, typeConverter, paramCount: 0);
var convertFromInvariantStringDefinition = isExtendedConverter
? module.ImportReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "IExtendedTypeConverter"))
.ResolveCached()
? module.ImportReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "IExtendedTypeConverter"))
.ResolveCached(context.Cache)
.Methods.FirstOrDefault(md => md.Name == "ConvertFromInvariantString" && md.Parameters.Count == 2)
: typeConverter.ResolveCached()
.AllMethods()
: typeConverter.ResolveCached(context.Cache)
.AllMethods(context.Cache)
.FirstOrDefault(md => md.methodDef.Name == "ConvertFromInvariantString" && md.methodDef.Parameters.Count == 1).methodDef;
var convertFromInvariantStringReference = module.ImportReference(convertFromInvariantStringDefinition);
@ -233,20 +212,20 @@ namespace Microsoft.Maui.Controls.Build.Tasks
var originalTypeRef = targetTypeRef;
var isNullable = false;
MethodReference nullableCtor = null;
if (targetTypeRef.ResolveCached().FullName == "System.Nullable`1")
if (targetTypeRef.ResolveCached(context.Cache).FullName == "System.Nullable`1")
{
var nullableTypeRef = targetTypeRef;
targetTypeRef = ((GenericInstanceType)targetTypeRef).GenericArguments[0];
isNullable = true;
nullableCtor = originalTypeRef.GetMethods(md => md.IsConstructor && md.Parameters.Count == 1, module).Single().Item1;
nullableCtor = originalTypeRef.GetMethods(context.Cache, md => md.IsConstructor && md.Parameters.Count == 1, module).Single().Item1;
nullableCtor = nullableCtor.ResolveGenericParameters(nullableTypeRef, module);
}
var implicitOperator = module.TypeSystem.String.GetImplicitOperatorTo(targetTypeRef, module);
var implicitOperator = module.TypeSystem.String.GetImplicitOperatorTo(context.Cache, targetTypeRef, module);
//Obvious Built-in conversions
if (targetTypeRef.ResolveCached().BaseType != null && targetTypeRef.ResolveCached().BaseType.FullName == "System.Enum")
yield return PushParsedEnum(targetTypeRef, str, node);
if (targetTypeRef.ResolveCached(context.Cache).BaseType != null && targetTypeRef.ResolveCached(context.Cache).BaseType.FullName == "System.Enum")
yield return PushParsedEnum(context.Cache, targetTypeRef, str, node);
else if (targetTypeRef.FullName == "System.Char")
yield return Instruction.Create(OpCodes.Ldc_I4, unchecked((int)TryFormat(Char.Parse, node, str)));
else if (targetTypeRef.FullName == "System.SByte")
@ -281,14 +260,14 @@ namespace Microsoft.Maui.Controls.Build.Tasks
var ts = TryFormat(s => TimeSpan.Parse(s, CultureInfo.InvariantCulture), node, str);
var ticks = ts.Ticks;
yield return Instruction.Create(OpCodes.Ldc_I8, ticks);
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("mscorlib", "System", "TimeSpan"), parameterTypes: new[] { ("mscorlib", "System", "Int64") }));
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(context.Cache, ("mscorlib", "System", "TimeSpan"), parameterTypes: new[] { ("mscorlib", "System", "Int64") }));
}
else if (targetTypeRef.FullName == "System.DateTime")
{
var dt = TryFormat(s => DateTime.Parse(s, CultureInfo.InvariantCulture), node, str);
var ticks = dt.Ticks;
yield return Instruction.Create(OpCodes.Ldc_I8, ticks);
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("mscorlib", "System", "DateTime"), parameterTypes: new[] { ("mscorlib", "System", "Int64") }));
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(context.Cache, ("mscorlib", "System", "DateTime"), parameterTypes: new[] { ("mscorlib", "System", "Int64") }));
}
else if (targetTypeRef.FullName == "System.String" && str.StartsWith("{}", StringComparison.Ordinal))
yield return Instruction.Create(OpCodes.Ldstr, str.Substring(2));
@ -301,7 +280,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
decimal outdecimal;
if (decimal.TryParse(str, NumberStyles.Number, CultureInfo.InvariantCulture, out outdecimal))
{
var vardef = new VariableDefinition(module.ImportReference(("mscorlib", "System", "Decimal")));
var vardef = new VariableDefinition(module.ImportReference(context.Cache, ("mscorlib", "System", "Decimal")));
context.Body.Variables.Add(vardef);
//Use an extra temp var so we can push the value to the stack, just like other cases
// IL_0003: ldstr "adecimal"
@ -312,10 +291,10 @@ namespace Microsoft.Maui.Controls.Build.Tasks
// IL_0016: pop
yield return Create(Ldstr, str);
yield return Create(Ldc_I4, 0x6f); //NumberStyles.Number
yield return Create(Call, module.ImportPropertyGetterReference(("mscorlib", "System.Globalization", "CultureInfo"),
yield return Create(Call, module.ImportPropertyGetterReference(context.Cache, ("mscorlib", "System.Globalization", "CultureInfo"),
propertyName: "InvariantCulture", isStatic: true));
yield return Create(Ldloca, vardef);
yield return Create(Call, module.ImportMethodReference(("mscorlib", "System", "Decimal"),
yield return Create(Call, module.ImportMethodReference(context.Cache, ("mscorlib", "System", "Decimal"),
methodName: "TryParse",
parameterTypes: new[] {
("mscorlib", "System", "String"),
@ -330,7 +309,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
else
{
yield return Create(Ldc_I4_0);
yield return Create(Newobj, module.ImportCtorReference(("mscorlib", "System", "Decimal"), parameterTypes: new[] { ("mscorlib", "System", "Int32") }));
yield return Create(Newobj, module.ImportCtorReference(context.Cache, ("mscorlib", "System", "Decimal"), parameterTypes: new[] { ("mscorlib", "System", "Int32") }));
}
}
else if (implicitOperator != null)
@ -347,9 +326,9 @@ namespace Microsoft.Maui.Controls.Build.Tasks
yield return Create(Box, module.ImportReference(originalTypeRef));
}
static Instruction PushParsedEnum(TypeReference enumRef, string value, IXmlLineInfo lineInfo)
static Instruction PushParsedEnum(XamlCache cache, TypeReference enumRef, string value, IXmlLineInfo lineInfo)
{
var enumDef = enumRef.ResolveCached();
var enumDef = enumRef.ResolveCached(cache);
if (!enumDef.IsEnum)
throw new InvalidOperationException();
@ -456,13 +435,13 @@ namespace Microsoft.Maui.Controls.Build.Tasks
{
yield return Create(Ldc_I4, xmlLineInfo.LineNumber);
yield return Create(Ldc_I4, xmlLineInfo.LinePosition);
ctor = module.ImportCtorReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "XmlLineInfo"), parameterTypes: new[] {
ctor = module.ImportCtorReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "XmlLineInfo"), parameterTypes: new[] {
("mscorlib", "System", "Int32"),
("mscorlib", "System", "Int32"),
});
}
else
ctor = module.ImportCtorReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "XmlLineInfo"), parameterTypes: null);
ctor = module.ImportCtorReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "XmlLineInfo"), parameterTypes: null);
yield return Create(Newobj, ctor);
}
@ -512,7 +491,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
yield return Instruction.Create(OpCodes.Ldc_I4, nodes.Count);
yield return Instruction.Create(OpCodes.Add);
yield return Instruction.Create(OpCodes.Newarr, module.TypeSystem.Object);
var finalArray = new VariableDefinition(module.ImportArrayReference(("mscorlib", "System", "Object")));
var finalArray = new VariableDefinition(module.ImportArrayReference(context.Cache, ("mscorlib", "System", "Object")));
context.Body.Variables.Add(finalArray);
yield return Instruction.Create(OpCodes.Stloc, finalArray);
@ -525,7 +504,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
yield return Create(Ldloc, finalArray); //destinationArray
yield return Create(Ldc_I4, nodes.Count); //destinationIndex
yield return Create(Ldloc, parentObjectLength); //length
yield return Create(Call, module.ImportMethodReference(("mscorlib", "System", "Array"),
yield return Create(Call, module.ImportMethodReference(context.Cache, ("mscorlib", "System", "Array"),
methodName: "Copy",
parameterTypes: new[] {
("mscorlib", "System", "Array"),
@ -546,14 +525,14 @@ namespace Microsoft.Maui.Controls.Build.Tasks
var en = nodes[i];
yield return Instruction.Create(OpCodes.Dup);
yield return Instruction.Create(OpCodes.Ldc_I4, i);
foreach (var instruction in context.Variables[en].LoadAs(module.TypeSystem.Object, module))
foreach (var instruction in context.Variables[en].LoadAs(context.Cache, module.TypeSystem.Object, module))
yield return instruction;
yield return Instruction.Create(OpCodes.Stelem_Ref);
}
}
}
static IEnumerable<Instruction> PushTargetProperty(FieldReference bpRef, PropertyReference propertyRef, TypeReference declaringTypeReference, ModuleDefinition module)
static IEnumerable<Instruction> PushTargetProperty(ILContext context, FieldReference bpRef, PropertyReference propertyRef, TypeReference declaringTypeReference, ModuleDefinition module)
{
if (bpRef != null)
{
@ -563,9 +542,9 @@ namespace Microsoft.Maui.Controls.Build.Tasks
if (propertyRef != null)
{
yield return Create(Ldtoken, module.ImportReference(declaringTypeReference ?? propertyRef.DeclaringType));
yield return Create(Call, module.ImportMethodReference(("mscorlib", "System", "Type"), methodName: "GetTypeFromHandle", parameterTypes: new[] { ("mscorlib", "System", "RuntimeTypeHandle") }, isStatic: true));
yield return Create(Call, module.ImportMethodReference(context.Cache, ("mscorlib", "System", "Type"), methodName: "GetTypeFromHandle", parameterTypes: new[] { ("mscorlib", "System", "RuntimeTypeHandle") }, isStatic: true));
yield return Create(Ldstr, propertyRef.Name);
yield return Create(Call, module.ImportMethodReference(("System.Reflection.Extensions", "System.Reflection", "RuntimeReflectionExtensions"),
yield return Create(Call, module.ImportMethodReference(context.Cache, ("System.Reflection.Extensions", "System.Reflection", "RuntimeReflectionExtensions"),
methodName: "GetRuntimeProperty",
parameterTypes: new[]{
("mscorlib", "System", "Type"),
@ -587,27 +566,27 @@ namespace Microsoft.Maui.Controls.Build.Tasks
yield break;
#endif
var addService = module.ImportMethodReference(("Microsoft.Maui.Controls.Xaml", "Microsoft.Maui.Controls.Xaml.Internals", "XamlServiceProvider"),
var addService = module.ImportMethodReference(context.Cache, ("Microsoft.Maui.Controls.Xaml", "Microsoft.Maui.Controls.Xaml.Internals", "XamlServiceProvider"),
methodName: "Add",
parameterTypes: new[] {
("mscorlib", "System", "Type"),
("mscorlib", "System", "Object"),
});
yield return Create(Newobj, module.ImportCtorReference(("Microsoft.Maui.Controls.Xaml", "Microsoft.Maui.Controls.Xaml.Internals", "XamlServiceProvider"), parameterTypes: null));
yield return Create(Newobj, module.ImportCtorReference(context.Cache, ("Microsoft.Maui.Controls.Xaml", "Microsoft.Maui.Controls.Xaml.Internals", "XamlServiceProvider"), parameterTypes: null));
//Add a SimpleValueTargetProvider and register it as IProvideValueTarget and IReferenceProvider
var pushParentIl = node.PushParentObjectsArray(context).ToList();
if (pushParentIl[pushParentIl.Count - 1].OpCode != Ldnull)
{
yield return Create(Dup); //Keep the serviceProvider on the stack
yield return Create(Ldtoken, module.ImportReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "IProvideValueTarget")));
yield return Create(Call, module.ImportMethodReference(("mscorlib", "System", "Type"), methodName: "GetTypeFromHandle", parameterTypes: new[] { ("mscorlib", "System", "RuntimeTypeHandle") }, isStatic: true));
yield return Create(Ldtoken, module.ImportReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "IProvideValueTarget")));
yield return Create(Call, module.ImportMethodReference(context.Cache, ("mscorlib", "System", "Type"), methodName: "GetTypeFromHandle", parameterTypes: new[] { ("mscorlib", "System", "RuntimeTypeHandle") }, isStatic: true));
foreach (var instruction in pushParentIl)
yield return instruction;
foreach (var instruction in PushTargetProperty(bpRef, propertyRef, declaringTypeReference, module))
foreach (var instruction in PushTargetProperty(context, bpRef, propertyRef, declaringTypeReference, module))
yield return instruction;
if (context.Scopes.TryGetValue(node, out var scope))
@ -615,17 +594,17 @@ namespace Microsoft.Maui.Controls.Build.Tasks
else
yield return Create(Ldnull);
yield return Create(Newobj, module.ImportCtorReference(("Microsoft.Maui.Controls.Xaml", "Microsoft.Maui.Controls.Xaml.Internals", "SimpleValueTargetProvider"), paramCount: 3));
yield return Create(Newobj, module.ImportCtorReference(context.Cache, ("Microsoft.Maui.Controls.Xaml", "Microsoft.Maui.Controls.Xaml.Internals", "SimpleValueTargetProvider"), paramCount: 3));
//store the provider so we can register it again with a different key
yield return Create(Dup);
var refProvider = new VariableDefinition(module.ImportReference(("mscorlib", "System", "Object")));
var refProvider = new VariableDefinition(module.ImportReference(context.Cache, ("mscorlib", "System", "Object")));
context.Body.Variables.Add(refProvider);
yield return Create(Stloc, refProvider);
yield return Create(Callvirt, addService);
yield return Create(Dup); //Keep the serviceProvider on the stack
yield return Create(Ldtoken, module.ImportReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "IReferenceProvider")));
yield return Create(Call, module.ImportMethodReference(("mscorlib", "System", "Type"), methodName: "GetTypeFromHandle", parameterTypes: new[] { ("mscorlib", "System", "RuntimeTypeHandle") }, isStatic: true));
yield return Create(Ldtoken, module.ImportReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "IReferenceProvider")));
yield return Create(Call, module.ImportMethodReference(context.Cache, ("mscorlib", "System", "Type"), methodName: "GetTypeFromHandle", parameterTypes: new[] { ("mscorlib", "System", "RuntimeTypeHandle") }, isStatic: true));
yield return Create(Ldloc, refProvider);
yield return Create(Callvirt, addService);
}
@ -634,15 +613,15 @@ namespace Microsoft.Maui.Controls.Build.Tasks
if (node.NamespaceResolver != null)
{
yield return Create(Dup); //Duplicate the serviceProvider
yield return Create(Ldtoken, module.ImportReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "IXamlTypeResolver")));
yield return Create(Call, module.ImportMethodReference(("mscorlib", "System", "Type"), methodName: "GetTypeFromHandle", parameterTypes: new[] { ("mscorlib", "System", "RuntimeTypeHandle") }, isStatic: true));
yield return Create(Newobj, module.ImportCtorReference(("Microsoft.Maui.Controls.Xaml", "Microsoft.Maui.Controls.Xaml.Internals", "XmlNamespaceResolver"), parameterTypes: null));
yield return Create(Ldtoken, module.ImportReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "IXamlTypeResolver")));
yield return Create(Call, module.ImportMethodReference(context.Cache, ("mscorlib", "System", "Type"), methodName: "GetTypeFromHandle", parameterTypes: new[] { ("mscorlib", "System", "RuntimeTypeHandle") }, isStatic: true));
yield return Create(Newobj, module.ImportCtorReference(context.Cache, ("Microsoft.Maui.Controls.Xaml", "Microsoft.Maui.Controls.Xaml.Internals", "XmlNamespaceResolver"), parameterTypes: null));
foreach (var kvp in node.NamespaceResolver.GetNamespacesInScope(XmlNamespaceScope.ExcludeXml))
{
yield return Create(Dup); //dup the resolver
yield return Create(Ldstr, kvp.Key);
yield return Create(Ldstr, kvp.Value);
yield return Create(Callvirt, module.ImportMethodReference(("Microsoft.Maui.Controls.Xaml", "Microsoft.Maui.Controls.Xaml.Internals", "XmlNamespaceResolver"),
yield return Create(Callvirt, module.ImportMethodReference(context.Cache, ("Microsoft.Maui.Controls.Xaml", "Microsoft.Maui.Controls.Xaml.Internals", "XmlNamespaceResolver"),
methodName: "Add",
parameterTypes: new[] {
("mscorlib", "System", "String"),
@ -650,20 +629,20 @@ namespace Microsoft.Maui.Controls.Build.Tasks
}));
}
yield return Create(Ldtoken, context.Body.Method.DeclaringType);
yield return Create(Call, module.ImportMethodReference(("mscorlib", "System", "Type"), methodName: "GetTypeFromHandle", parameterTypes: new[] { ("mscorlib", "System", "RuntimeTypeHandle") }, isStatic: true));
yield return Create(Callvirt, module.ImportPropertyGetterReference(("mscorlib", "System", "Type"), propertyName: "Assembly", flatten: true));
yield return Create(Newobj, module.ImportCtorReference(("Microsoft.Maui.Controls.Xaml", "Microsoft.Maui.Controls.Xaml.Internals", "XamlTypeResolver"), paramCount: 2));
yield return Create(Call, module.ImportMethodReference(context.Cache, ("mscorlib", "System", "Type"), methodName: "GetTypeFromHandle", parameterTypes: new[] { ("mscorlib", "System", "RuntimeTypeHandle") }, isStatic: true));
yield return Create(Callvirt, module.ImportPropertyGetterReference(context.Cache, ("mscorlib", "System", "Type"), propertyName: "Assembly", flatten: true));
yield return Create(Newobj, module.ImportCtorReference(context.Cache, ("Microsoft.Maui.Controls.Xaml", "Microsoft.Maui.Controls.Xaml.Internals", "XamlTypeResolver"), paramCount: 2));
yield return Create(Callvirt, addService);
}
if (node is IXmlLineInfo)
{
yield return Create(Dup); //Duplicate the serviceProvider
yield return Create(Ldtoken, module.ImportReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "IXmlLineInfoProvider")));
yield return Create(Call, module.ImportMethodReference(("mscorlib", "System", "Type"), methodName: "GetTypeFromHandle", parameterTypes: new[] { ("mscorlib", "System", "RuntimeTypeHandle") }, isStatic: true));
yield return Create(Ldtoken, module.ImportReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "IXmlLineInfoProvider")));
yield return Create(Call, module.ImportMethodReference(context.Cache, ("mscorlib", "System", "Type"), methodName: "GetTypeFromHandle", parameterTypes: new[] { ("mscorlib", "System", "RuntimeTypeHandle") }, isStatic: true));
foreach (var instruction in node.PushXmlLineInfo(context))
yield return instruction;
yield return Create(Newobj, module.ImportCtorReference(("Microsoft.Maui.Controls.Xaml", "Microsoft.Maui.Controls.Xaml.Internals", "XmlLineInfoProvider"), parameterTypes: new[] { ("System.Xml.ReaderWriter", "System.Xml", "IXmlLineInfo") }));
yield return Create(Newobj, module.ImportCtorReference(context.Cache, ("Microsoft.Maui.Controls.Xaml", "Microsoft.Maui.Controls.Xaml.Internals", "XmlLineInfoProvider"), parameterTypes: new[] { ("System.Xml.ReaderWriter", "System.Xml", "IXmlLineInfo") }));
yield return Create(Callvirt, addService);
}
}

Просмотреть файл

@ -34,7 +34,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
if (field == null)
return;
Context.IL.Emit(OpCodes.Ldarg_0);
Context.IL.Append(Context.Variables[(IElementNode)parentNode].LoadAs(field.FieldType, Context.Module));
Context.IL.Append(Context.Variables[(IElementNode)parentNode].LoadAs(Context.Cache, field.FieldType, Context.Module));
Context.IL.Emit(OpCodes.Stfld, field);
}

Просмотреть файл

@ -57,7 +57,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
namescopeVarDef = Context.Scopes[parentNode].Item1;
namesInNamescope = Context.Scopes[parentNode].Item2;
}
if (setNameScope && Context.Variables[node].VariableType.InheritsFromOrImplements(Context.Body.Method.Module.ImportReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "BindableObject"))))
if (setNameScope && Context.Variables[node].VariableType.InheritsFromOrImplements(Context.Cache, Context.Body.Method.Module.ImportReference(Context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "BindableObject"))))
SetNameScope(node, namescopeVarDef);
Context.Scopes[node] = new Tuple<VariableDefinition, IList<string>>(namescopeVarDef, namesInNamescope);
}
@ -66,7 +66,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
{
var namescopeVarDef = GetOrCreateNameScope(node);
IList<string> namesInNamescope = new List<string>();
if (Context.Variables[node].VariableType.InheritsFromOrImplements(Context.Body.Method.Module.ImportReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "BindableObject"))))
if (Context.Variables[node].VariableType.InheritsFromOrImplements(Context.Cache, Context.Body.Method.Module.ImportReference(Context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "BindableObject"))))
SetNameScope(node, namescopeVarDef);
Context.Scopes[node] = new System.Tuple<VariableDefinition, IList<string>>(namescopeVarDef, namesInNamescope);
}
@ -89,15 +89,15 @@ namespace Microsoft.Maui.Controls.Build.Tasks
VariableDefinition GetOrCreateNameScope(ElementNode node)
{
var module = Context.Body.Method.Module;
var vardef = new VariableDefinition(module.ImportReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Internals", "NameScope")));
var vardef = new VariableDefinition(module.ImportReference(Context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Internals", "NameScope")));
Context.Body.Variables.Add(vardef);
var stloc = Instruction.Create(OpCodes.Stloc, vardef);
if (Context.Variables[node].VariableType.InheritsFromOrImplements(Context.Body.Method.Module.ImportReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "BindableObject"))))
if (Context.Variables[node].VariableType.InheritsFromOrImplements(Context.Cache, Context.Body.Method.Module.ImportReference(Context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "BindableObject"))))
{
var namescoperef = ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "BindableObject");
Context.IL.Append(Context.Variables[node].LoadAs(module.GetTypeDefinition(namescoperef), module));
Context.IL.Emit(OpCodes.Call, module.ImportMethodReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Internals", "NameScope"),
Context.IL.Append(Context.Variables[node].LoadAs(Context.Cache, module.GetTypeDefinition(Context.Cache, namescoperef), module));
Context.IL.Emit(OpCodes.Call, module.ImportMethodReference(Context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Internals", "NameScope"),
methodName: "GetNameScope",
parameterTypes: new[] { namescoperef },
isStatic: true));
@ -106,7 +106,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
Context.IL.Emit(OpCodes.Pop);
}
Context.IL.Emit(OpCodes.Newobj, module.ImportCtorReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Internals", "NameScope"), parameterTypes: null));
Context.IL.Emit(OpCodes.Newobj, module.ImportCtorReference(Context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Internals", "NameScope"), parameterTypes: null));
Context.IL.Append(stloc);
return vardef;
@ -115,9 +115,9 @@ namespace Microsoft.Maui.Controls.Build.Tasks
VariableDefinition CreateNamescope()
{
var module = Context.Body.Method.Module;
var vardef = new VariableDefinition(module.ImportReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Internals", "NameScope")));
var vardef = new VariableDefinition(module.ImportReference(Context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Internals", "NameScope")));
Context.Body.Variables.Add(vardef);
Context.IL.Emit(OpCodes.Newobj, module.ImportCtorReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Internals", "NameScope"), parameterTypes: null));
Context.IL.Emit(OpCodes.Newobj, module.ImportCtorReference(Context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Internals", "NameScope"), parameterTypes: null));
Context.IL.Emit(OpCodes.Stloc, vardef);
return vardef;
}
@ -129,9 +129,9 @@ namespace Microsoft.Maui.Controls.Build.Tasks
("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "BindableObject"),
("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Internals", "INameScope"),
};
Context.IL.Append(Context.Variables[node].LoadAs(module.GetTypeDefinition(parameterTypes[0]), module));
Context.IL.Append(ns.LoadAs(module.GetTypeDefinition(parameterTypes[1]), module));
Context.IL.Emit(OpCodes.Call, module.ImportMethodReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Internals", "NameScope"),
Context.IL.Append(Context.Variables[node].LoadAs(Context.Cache, module.GetTypeDefinition(Context.Cache, parameterTypes[0]), module));
Context.IL.Append(ns.LoadAs(Context.Cache, module.GetTypeDefinition(Context.Cache, parameterTypes[1]), module));
Context.IL.Emit(OpCodes.Call, module.ImportMethodReference(Context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Internals", "NameScope"),
methodName: "SetNameScope",
parameterTypes: parameterTypes,
isStatic: true));
@ -145,10 +145,11 @@ namespace Microsoft.Maui.Controls.Build.Tasks
var module = Context.Body.Method.Module;
var namescopeType = ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Internals", "INameScope");
Context.IL.Append(namescopeVarDef.LoadAs(module.GetTypeDefinition(namescopeType), module));
Context.IL.Append(namescopeVarDef.LoadAs(Context.Cache, module.GetTypeDefinition(Context.Cache, namescopeType), module));
Context.IL.Emit(OpCodes.Ldstr, str);
Context.IL.Append(element.LoadAs(module.TypeSystem.Object, module));
Context.IL.Emit(OpCodes.Callvirt, module.ImportMethodReference(namescopeType,
Context.IL.Append(element.LoadAs(Context.Cache, module.TypeSystem.Object, module));
Context.IL.Emit(OpCodes.Callvirt, module.ImportMethodReference(Context.Cache,
namescopeType,
methodName: "RegisterName",
parameterTypes: new[] {
("mscorlib", "System", "String"),
@ -158,20 +159,20 @@ namespace Microsoft.Maui.Controls.Build.Tasks
void SetStyleId(string str, VariableDefinition element)
{
if (!element.VariableType.InheritsFromOrImplements(Context.Body.Method.Module.ImportReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "Element"))))
if (!element.VariableType.InheritsFromOrImplements(Context.Cache, Context.Body.Method.Module.ImportReference(Context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "Element"))))
return;
var module = Context.Body.Method.Module;
var elementType = ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "Element");
var elementTypeRef = module.GetTypeDefinition(elementType);
var elementTypeRef = module.GetTypeDefinition(Context.Cache, elementType);
var nop = Instruction.Create(OpCodes.Nop);
Context.IL.Append(element.LoadAs(elementTypeRef, module));
Context.IL.Emit(OpCodes.Callvirt, module.ImportPropertyGetterReference(elementType, propertyName: "StyleId"));
Context.IL.Append(element.LoadAs(Context.Cache, elementTypeRef, module));
Context.IL.Emit(OpCodes.Callvirt, module.ImportPropertyGetterReference(Context.Cache, elementType, propertyName: "StyleId"));
Context.IL.Emit(OpCodes.Brtrue, nop);
Context.IL.Append(element.LoadAs(elementTypeRef, module));
Context.IL.Append(element.LoadAs(Context.Cache, elementTypeRef, module));
Context.IL.Emit(OpCodes.Ldstr, str);
Context.IL.Emit(OpCodes.Callvirt, module.ImportPropertySetterReference(elementType, propertyName: "StyleId"));
Context.IL.Emit(OpCodes.Callvirt, module.ImportPropertySetterReference(Context.Cache, elementType, propertyName: "StyleId"));
Context.IL.Append(nop);
}
}

Просмотреть файл

@ -15,9 +15,6 @@ namespace Microsoft.Maui.Controls.Build.Tasks
{
class SetPropertiesVisitor : IXamlNodeVisitor
{
static int dtcount;
static int typedBindingCount;
static readonly IList<XmlName> skips = new List<XmlName>
{
XmlName.xKey,
@ -63,7 +60,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
if (!Context.Variables.ContainsKey((IElementNode)parentNode))
return;
var parentVar = Context.Variables[(IElementNode)parentNode];
if ((contentProperty = GetContentProperty(parentVar.VariableType)) != null)
if ((contentProperty = GetContentProperty(Context.Cache, parentVar.VariableType)) != null)
propertyName = new XmlName(((IElementNode)parentNode).NamespaceURI, contentProperty);
else
return;
@ -116,7 +113,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
if (parentNode is IElementNode && propertyName != XmlName.Empty)
{
bpRef = GetBindablePropertyReference(Context.Variables[(IElementNode)parentNode], propertyName.NamespaceURI, ref localName, out _, Context, node);
propertyRef = Context.Variables[(IElementNode)parentNode].VariableType.GetProperty(pd => pd.Name == localName, out declaringTypeReference);
propertyRef = Context.Variables[(IElementNode)parentNode].VariableType.GetProperty(Context.Cache, pd => pd.Name == localName, out declaringTypeReference);
}
Context.IL.Append(ProvideValue(vardefref, Context, Module, node, bpRef: bpRef, propertyRef: propertyRef, propertyDeclaringTypeRef: declaringTypeReference));
if (vardef != vardefref.VariableDefinition)
@ -142,10 +139,10 @@ namespace Microsoft.Maui.Controls.Build.Tasks
if (CanAddToResourceDictionary(parentVar, parentVar.VariableType, node, node, Context))
{
Context.IL.Append(parentVar.LoadAs(Module.GetTypeDefinition(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "ResourceDictionary")), Module));
Context.IL.Append(parentVar.LoadAs(Context.Cache, Module.GetTypeDefinition(Context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "ResourceDictionary")), Module));
Context.IL.Append(AddToResourceDictionary(parentVar, node, node, Context));
}
else if ((contentProperty = GetContentProperty(parentVar.VariableType)) != null)
else if ((contentProperty = GetContentProperty(Context.Cache, parentVar.VariableType)) != null)
{
var name = new XmlName(node.NamespaceURI, contentProperty);
if (skips.Contains(name))
@ -155,16 +152,16 @@ namespace Microsoft.Maui.Controls.Build.Tasks
Context.IL.Append(SetPropertyValue(Context.Variables[(IElementNode)parentNode], name, node, Context, node));
}
// Collection element, implicit content, or implicit collection element.
else if (parentVar.VariableType.ImplementsInterface(Module.ImportReference(("mscorlib", "System.Collections", "IEnumerable")))
&& parentVar.VariableType.GetMethods(md => md.Name == "Add" && md.Parameters.Count == 1, Module).Any())
else if (parentVar.VariableType.ImplementsInterface(Context.Cache, Module.ImportReference(Context.Cache, ("mscorlib", "System.Collections", "IEnumerable")))
&& parentVar.VariableType.GetMethods(Context.Cache, md => md.Name == "Add" && md.Parameters.Count == 1, Module).Any())
{
var elementType = parentVar.VariableType;
var adderTuple = elementType.GetMethods(md => md.Name == "Add" && md.Parameters.Count == 1, Module).First();
var adderTuple = elementType.GetMethods(Context.Cache, md => md.Name == "Add" && md.Parameters.Count == 1, Module).First();
var adderRef = Module.ImportReference(adderTuple.Item1);
adderRef = Module.ImportReference(adderRef.ResolveGenericParameters(adderTuple.Item2, Module));
Context.IL.Emit(Ldloc, parentVar);
Context.IL.Append(vardef.LoadAs(adderRef.Parameters[0].ParameterType.ResolveGenericParameters(adderRef), Module));
Context.IL.Append(vardef.LoadAs(Context.Cache, adderRef.Parameters[0].ParameterType.ResolveGenericParameters(adderRef), Module));
Context.IL.Emit(Callvirt, adderRef);
if (adderRef.ReturnType.FullName != "System.Void")
Context.IL.Emit(Pop);
@ -198,13 +195,13 @@ namespace Microsoft.Maui.Controls.Build.Tasks
Context.IL.Append(AddToResourceDictionary(parent, node, node, Context));
return;
}
var adderTuple = propertyType.GetMethods(md => md.Name == "Add" && md.Parameters.Count == 1, Module).FirstOrDefault() ??
var adderTuple = propertyType.GetMethods(Context.Cache, md => md.Name == "Add" && md.Parameters.Count == 1, Module).FirstOrDefault() ??
throw new BuildException(BuildExceptionCode.AdderMissing, node, null, parent.VariableType, localname);
var adderRef = Module.ImportReference(adderTuple.Item1);
adderRef = Module.ImportReference(adderRef.ResolveGenericParameters(adderTuple.Item2, Module));
Context.IL.Append(vardef.LoadAs(adderRef.Parameters[0].ParameterType.ResolveGenericParameters(adderRef), Module));
Context.IL.Append(vardef.LoadAs(Context.Cache, adderRef.Parameters[0].ParameterType.ResolveGenericParameters(adderRef), Module));
Context.IL.Emit(OpCodes.Callvirt, adderRef);
if (adderRef.ReturnType.FullName != "System.Void")
Context.IL.Emit(OpCodes.Pop);
@ -241,9 +238,9 @@ namespace Microsoft.Maui.Controls.Build.Tasks
return parentList.CollectionItems.Contains(node);
}
internal static string GetContentProperty(TypeReference typeRef)
internal static string GetContentProperty(XamlCache cache, TypeReference typeRef)
{
var typeDef = typeRef.ResolveCached();
var typeDef = typeRef.ResolveCached(cache);
var attributes = typeDef.CustomAttributes;
var attr =
attributes.FirstOrDefault(cad => ContentPropertyAttribute.ContentPropertyTypes.Contains(cad.AttributeType.FullName));
@ -251,7 +248,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
return attr.ConstructorArguments[0].Value as string;
if (typeDef.BaseType == null)
return null;
return GetContentProperty(typeDef.BaseType);
return GetContentProperty(cache, typeDef.BaseType);
}
public static IEnumerable<Instruction> ProvideValue(VariableDefinitionReference vardefref, ILContext context,
@ -261,10 +258,10 @@ namespace Microsoft.Maui.Controls.Build.Tasks
GenericInstanceType markupExtension;
IList<TypeReference> genericArguments;
if (vardefref.VariableDefinition.VariableType.FullName == "Microsoft.Maui.Controls.Xaml.ArrayExtension" &&
vardefref.VariableDefinition.VariableType.ImplementsGenericInterface("Microsoft.Maui.Controls.Xaml.IMarkupExtension`1",
vardefref.VariableDefinition.VariableType.ImplementsGenericInterface(context.Cache, "Microsoft.Maui.Controls.Xaml.IMarkupExtension`1",
out markupExtension, out genericArguments))
{
var markExt = markupExtension.ResolveCached();
var markExt = markupExtension.ResolveCached(context.Cache);
var provideValueInfo = markExt.Methods.First(md => md.Name == "ProvideValue");
var provideValue = module.ImportReference(provideValueInfo);
provideValue =
@ -276,7 +273,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
vardefref.VariableDefinition = new VariableDefinition(module.ImportReference(arrayTypeRef.MakeArrayType()));
else
vardefref.VariableDefinition = new VariableDefinition(module.ImportReference(genericArguments.First()));
foreach (var instruction in context.Variables[node].LoadAs(markupExtension, module))
foreach (var instruction in context.Variables[node].LoadAs(context.Cache, markupExtension, module))
yield return instruction;
foreach (var instruction in node.PushServiceProvider(context, bpRef, propertyRef, propertyDeclaringTypeRef))
yield return instruction;
@ -286,10 +283,10 @@ namespace Microsoft.Maui.Controls.Build.Tasks
yield return Instruction.Create(OpCodes.Castclass, module.ImportReference(arrayTypeRef.MakeArrayType()));
yield return Instruction.Create(OpCodes.Stloc, vardefref.VariableDefinition);
}
else if (vardefref.VariableDefinition.VariableType.ImplementsGenericInterface("Microsoft.Maui.Controls.Xaml.IMarkupExtension`1",
else if (vardefref.VariableDefinition.VariableType.ImplementsGenericInterface(context.Cache, "Microsoft.Maui.Controls.Xaml.IMarkupExtension`1",
out markupExtension, out genericArguments))
{
var acceptEmptyServiceProvider = vardefref.VariableDefinition.VariableType.GetCustomAttribute(module, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "AcceptEmptyServiceProviderAttribute")) != null;
var acceptEmptyServiceProvider = vardefref.VariableDefinition.VariableType.GetCustomAttribute(context.Cache, module, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "AcceptEmptyServiceProviderAttribute")) != null;
if (vardefref.VariableDefinition.VariableType.FullName == "Microsoft.Maui.Controls.Xaml.BindingExtension"
&& (node.Properties == null || !node.Properties.ContainsKey(new XmlName("", "Source"))) //do not compile bindings if Source is set
&& bpRef != null //do not compile bindings if we're not gonna SetBinding
@ -297,14 +294,14 @@ namespace Microsoft.Maui.Controls.Build.Tasks
foreach (var instruction in CompileBindingPath(node, context, vardefref.VariableDefinition))
yield return instruction;
var markExt = markupExtension.ResolveCached();
var markExt = markupExtension.ResolveCached(context.Cache);
var provideValueInfo = markExt.Methods.First(md => md.Name == "ProvideValue");
var provideValue = module.ImportReference(provideValueInfo);
provideValue =
module.ImportReference(provideValue.ResolveGenericParameters(markupExtension, module));
vardefref.VariableDefinition = new VariableDefinition(module.ImportReference(genericArguments.First()));
foreach (var instruction in context.Variables[node].LoadAs(markupExtension, module))
foreach (var instruction in context.Variables[node].LoadAs(context.Cache, markupExtension, module))
yield return instruction;
if (acceptEmptyServiceProvider)
yield return Instruction.Create(OpCodes.Ldnull);
@ -314,29 +311,30 @@ namespace Microsoft.Maui.Controls.Build.Tasks
yield return Instruction.Create(OpCodes.Callvirt, provideValue);
yield return Instruction.Create(OpCodes.Stloc, vardefref.VariableDefinition);
}
else if (context.Variables[node].VariableType.ImplementsInterface(module.ImportReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "IMarkupExtension"))))
else if (context.Variables[node].VariableType.ImplementsInterface(context.Cache, module.ImportReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "IMarkupExtension"))))
{
var acceptEmptyServiceProvider = context.Variables[node].VariableType.GetCustomAttribute(module, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "AcceptEmptyServiceProviderAttribute")) != null;
var acceptEmptyServiceProvider = context.Variables[node].VariableType.GetCustomAttribute(context.Cache, module, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "AcceptEmptyServiceProviderAttribute")) != null;
var markupExtensionType = ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "IMarkupExtension");
vardefref.VariableDefinition = new VariableDefinition(module.TypeSystem.Object);
foreach (var instruction in context.Variables[node].LoadAs(module.GetTypeDefinition(markupExtensionType), module))
foreach (var instruction in context.Variables[node].LoadAs(context.Cache, module.GetTypeDefinition(context.Cache, markupExtensionType), module))
yield return instruction;
if (acceptEmptyServiceProvider)
yield return Create(Ldnull);
else
foreach (var instruction in node.PushServiceProvider(context, bpRef, propertyRef, propertyDeclaringTypeRef))
yield return instruction;
yield return Create(Callvirt, module.ImportMethodReference(markupExtensionType,
yield return Create(Callvirt, module.ImportMethodReference(context.Cache,
markupExtensionType,
methodName: "ProvideValue",
parameterTypes: new[] { ("System.ComponentModel", "System", "IServiceProvider") }));
yield return Create(Stloc, vardefref.VariableDefinition);
}
else if (context.Variables[node].VariableType.ImplementsInterface(module.ImportReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "IValueProvider"))))
else if (context.Variables[node].VariableType.ImplementsInterface(context.Cache, module.ImportReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "IValueProvider"))))
{
var acceptEmptyServiceProvider = context.Variables[node].VariableType.GetCustomAttribute(module, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "AcceptEmptyServiceProviderAttribute")) != null;
var acceptEmptyServiceProvider = context.Variables[node].VariableType.GetCustomAttribute(context.Cache, module, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "AcceptEmptyServiceProviderAttribute")) != null;
var valueProviderType = context.Variables[node].VariableType;
//If the IValueProvider has a ProvideCompiledAttribute that can be resolved, shortcut this
var compiledValueProviderName = valueProviderType?.GetCustomAttribute(module, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "ProvideCompiledAttribute"))?.ConstructorArguments?[0].Value as string;
var compiledValueProviderName = valueProviderType?.GetCustomAttribute(context.Cache, module, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "ProvideCompiledAttribute"))?.ConstructorArguments?[0].Value as string;
Type compiledValueProviderType;
if (compiledValueProviderName != null && (compiledValueProviderType = Type.GetType(compiledValueProviderName)) != null)
{
@ -354,14 +352,15 @@ namespace Microsoft.Maui.Controls.Build.Tasks
var valueProviderInterface = ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "IValueProvider");
vardefref.VariableDefinition = new VariableDefinition(module.TypeSystem.Object);
foreach (var instruction in context.Variables[node].LoadAs(module.GetTypeDefinition(valueProviderInterface), module))
foreach (var instruction in context.Variables[node].LoadAs(context.Cache, module.GetTypeDefinition(context.Cache, valueProviderInterface), module))
yield return instruction;
if (acceptEmptyServiceProvider)
yield return Create(Ldnull);
else
foreach (var instruction in node.PushServiceProvider(context, bpRef, propertyRef, propertyDeclaringTypeRef))
yield return instruction;
yield return Create(Callvirt, module.ImportMethodReference(valueProviderInterface,
yield return Create(Callvirt, module.ImportMethodReference(context.Cache,
valueProviderInterface,
methodName: "ProvideValue",
parameterTypes: new[] { ("System.ComponentModel", "System", "IServiceProvider") }));
yield return Create(Stloc, vardefref.VariableDefinition);
@ -420,11 +419,11 @@ namespace Microsoft.Maui.Controls.Build.Tasks
var dtXType = new XmlType(namespaceuri, dataType, null);
var tSourceRef = dtXType.GetTypeReference(module, (IXmlLineInfo)node);
var tSourceRef = dtXType.GetTypeReference(context.Cache, module, (IXmlLineInfo)node);
if (tSourceRef == null)
yield break; //throw
var properties = ParsePath(path, tSourceRef, node as IXmlLineInfo, module);
var properties = ParsePath(context, path, tSourceRef, node as IXmlLineInfo, module);
TypeReference tPropertyRef = tSourceRef;
if (properties != null && properties.Count > 0)
{
@ -432,24 +431,24 @@ namespace Microsoft.Maui.Controls.Build.Tasks
tPropertyRef = lastProp.property.PropertyType.ResolveGenericParameters(lastProp.propDeclTypeRef);
}
tPropertyRef = module.ImportReference(tPropertyRef);
var valuetupleRef = context.Module.ImportReference(module.ImportReference(("mscorlib", "System", "ValueTuple`2")).MakeGenericInstanceType(new[] { tPropertyRef, module.TypeSystem.Boolean }));
var funcRef = module.ImportReference(module.ImportReference(("mscorlib", "System", "Func`2")).MakeGenericInstanceType(new[] { tSourceRef, valuetupleRef }));
var actionRef = module.ImportReference(module.ImportReference(("mscorlib", "System", "Action`2")).MakeGenericInstanceType(new[] { tSourceRef, tPropertyRef }));
var funcObjRef = module.ImportReference(module.ImportReference(("mscorlib", "System", "Func`2")).MakeGenericInstanceType(new[] { tSourceRef, module.TypeSystem.Object }));
var tupleRef = module.ImportReference(module.ImportReference(("mscorlib", "System", "Tuple`2")).MakeGenericInstanceType(new[] { funcObjRef, module.TypeSystem.String }));
var typedBindingRef = module.ImportReference(module.ImportReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Internals", "TypedBinding`2")).MakeGenericInstanceType(new[] { tSourceRef, tPropertyRef }));
var valuetupleRef = context.Module.ImportReference(module.ImportReference(context.Cache, ("mscorlib", "System", "ValueTuple`2")).MakeGenericInstanceType(new[] { tPropertyRef, module.TypeSystem.Boolean }));
var funcRef = module.ImportReference(module.ImportReference(context.Cache, ("mscorlib", "System", "Func`2")).MakeGenericInstanceType(new[] { tSourceRef, valuetupleRef }));
var actionRef = module.ImportReference(module.ImportReference(context.Cache, ("mscorlib", "System", "Action`2")).MakeGenericInstanceType(new[] { tSourceRef, tPropertyRef }));
var funcObjRef = module.ImportReference(module.ImportReference(context.Cache, ("mscorlib", "System", "Func`2")).MakeGenericInstanceType(new[] { tSourceRef, module.TypeSystem.Object }));
var tupleRef = module.ImportReference(module.ImportReference(context.Cache, ("mscorlib", "System", "Tuple`2")).MakeGenericInstanceType(new[] { funcObjRef, module.TypeSystem.String }));
var typedBindingRef = module.ImportReference(module.ImportReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Internals", "TypedBinding`2")).MakeGenericInstanceType(new[] { tSourceRef, tPropertyRef }));
//FIXME: make sure the non-deprecated one is used
var ctorInfo = module.ImportReference(typedBindingRef.ResolveCached().Methods.FirstOrDefault(md =>
var ctorInfo = module.ImportReference(typedBindingRef.ResolveCached(context.Cache).Methods.FirstOrDefault(md =>
md.IsConstructor
&& !md.IsStatic
&& md.Parameters.Count == 3
&& !md.HasCustomAttributes(module.ImportReference(("mscorlib", "System", "ObsoleteAttribute")))));
&& !md.HasCustomAttributes(module.ImportReference(context.Cache, ("mscorlib", "System", "ObsoleteAttribute")))));
var ctorinforef = ctorInfo.MakeGeneric(typedBindingRef, funcRef, actionRef, tupleRef);
var bindingExtensionType = ("Microsoft.Maui.Controls.Xaml", "Microsoft.Maui.Controls.Xaml", "BindingExtension");
foreach (var instruction in bindingExt.LoadAs(module.GetTypeDefinition(bindingExtensionType), module))
foreach (var instruction in bindingExt.LoadAs(context.Cache, module.GetTypeDefinition(context.Cache, bindingExtensionType), module))
yield return instruction;
foreach (var instruction in CompiledBindingGetGetter(tSourceRef, tPropertyRef, properties, node, context))
yield return instruction;
@ -468,10 +467,10 @@ namespace Microsoft.Maui.Controls.Build.Tasks
else
yield return Create(Ldnull);
yield return Create(Newobj, module.ImportReference(ctorinforef));
yield return Create(Callvirt, module.ImportPropertySetterReference(bindingExtensionType, propertyName: "TypedBinding"));
yield return Create(Callvirt, module.ImportPropertySetterReference(context.Cache, bindingExtensionType, propertyName: "TypedBinding"));
}
static IList<(PropertyDefinition property, TypeReference propDeclTypeRef, string indexArg)> ParsePath(string path, TypeReference tSourceRef, IXmlLineInfo lineInfo, ModuleDefinition module)
static IList<(PropertyDefinition property, TypeReference propDeclTypeRef, string indexArg)> ParsePath(ILContext context, string path, TypeReference tSourceRef, IXmlLineInfo lineInfo, ModuleDefinition module)
{
if (string.IsNullOrWhiteSpace(path))
return null;
@ -505,29 +504,32 @@ namespace Microsoft.Maui.Controls.Build.Tasks
if (p.Length > 0)
{
var property = previousPartTypeRef.GetProperty(pd => pd.Name == p && pd.GetMethod != null && pd.GetMethod.IsPublic, out var propDeclTypeRef)
var property = previousPartTypeRef.GetProperty(context.Cache, pd => pd.Name == p && pd.GetMethod != null && pd.GetMethod.IsPublic, out var propDeclTypeRef)
?? throw new BuildException(BuildExceptionCode.BindingPropertyNotFound, lineInfo, null, p, previousPartTypeRef);
properties.Add((property, propDeclTypeRef, null));
previousPartTypeRef = property.PropertyType.ResolveGenericParameters(propDeclTypeRef);
}
if (indexArg != null)
{
var defaultMemberAttribute = previousPartTypeRef.GetCustomAttribute(module, ("mscorlib", "System.Reflection", "DefaultMemberAttribute"));
var defaultMemberAttribute = previousPartTypeRef.GetCustomAttribute(context.Cache, module, ("mscorlib", "System.Reflection", "DefaultMemberAttribute"));
var indexerName = defaultMemberAttribute?.ConstructorArguments?.FirstOrDefault().Value as string ?? "Item";
PropertyDefinition indexer = null;
TypeReference indexerDeclTypeRef = null;
if (int.TryParse(indexArg, out _))
indexer = previousPartTypeRef.GetProperty(pd => pd.Name == indexerName
indexer = previousPartTypeRef.GetProperty(context.Cache,
pd => pd.Name == indexerName
&& pd.GetMethod != null
&& TypeRefComparer.Default.Equals(pd.GetMethod.Parameters[0].ParameterType.ResolveGenericParameters(previousPartTypeRef), module.ImportReference(("mscorlib", "System", "Int32")))
&& TypeRefComparer.Default.Equals(pd.GetMethod.Parameters[0].ParameterType.ResolveGenericParameters(previousPartTypeRef), module.ImportReference(context.Cache, ("mscorlib", "System", "Int32")))
&& pd.GetMethod.IsPublic, out indexerDeclTypeRef);
indexer = indexer ?? previousPartTypeRef.GetProperty(pd => pd.Name == indexerName
indexer = indexer ?? previousPartTypeRef.GetProperty(context.Cache,
pd => pd.Name == indexerName
&& pd.GetMethod != null
&& TypeRefComparer.Default.Equals(pd.GetMethod.Parameters[0].ParameterType.ResolveGenericParameters(previousPartTypeRef), module.ImportReference(("mscorlib", "System", "String")))
&& TypeRefComparer.Default.Equals(pd.GetMethod.Parameters[0].ParameterType.ResolveGenericParameters(previousPartTypeRef), module.ImportReference(context.Cache, ("mscorlib", "System", "String")))
&& pd.GetMethod.IsPublic, out indexerDeclTypeRef);
indexer = indexer ?? previousPartTypeRef.GetProperty(pd => pd.Name == indexerName
indexer = indexer ?? previousPartTypeRef.GetProperty(context.Cache,
pd => pd.Name == indexerName
&& pd.GetMethod != null
&& TypeRefComparer.Default.Equals(pd.GetMethod.Parameters[0].ParameterType.ResolveGenericParameters(previousPartTypeRef), module.ImportReference(("mscorlib", "System", "Object")))
&& TypeRefComparer.Default.Equals(pd.GetMethod.Parameters[0].ParameterType.ResolveGenericParameters(previousPartTypeRef), module.ImportReference(context.Cache, ("mscorlib", "System", "Object")))
&& pd.GetMethod.IsPublic, out indexerDeclTypeRef);
properties.Add((indexer, indexerDeclTypeRef, indexArg));
@ -611,15 +613,15 @@ namespace Microsoft.Maui.Controls.Build.Tasks
// }
var module = context.Module;
var tupleRef = module.ImportReference(module.ImportReference(("mscorlib", "System", "ValueTuple`2")).MakeGenericInstanceType(new[] { tPropertyRef, module.TypeSystem.Boolean }));
var tupleCtorRef = module.ImportCtorReference(tupleRef, 2);
var tupleRef = module.ImportReference(module.ImportReference(context.Cache, ("mscorlib", "System", "ValueTuple`2")).MakeGenericInstanceType(new[] { tPropertyRef, module.TypeSystem.Boolean }));
var tupleCtorRef = module.ImportCtorReference(context.Cache, tupleRef, 2);
tupleCtorRef = module.ImportReference(tupleCtorRef.ResolveGenericParameters(tupleRef, module));
var getter = new MethodDefinition($"<{context.Body.Method.Name}>typedBindingsM__{typedBindingCount++}",
var getter = new MethodDefinition($"<{context.Body.Method.Name}>typedBindingsM__{context.Cache.TypedBindingCount++}",
MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.Static,
tupleRef)
{
Parameters = { new ParameterDefinition(tSourceRef) },
CustomAttributes = { new CustomAttribute(module.ImportCtorReference(("mscorlib", "System.Runtime.CompilerServices", "CompilerGeneratedAttribute"), parameterTypes: null)) }
CustomAttributes = { new CustomAttribute(module.ImportCtorReference(context.Cache, ("mscorlib", "System.Runtime.CompilerServices", "CompilerGeneratedAttribute"), parameterTypes: null)) }
};
getter.Body.InitLocals = true;
@ -679,7 +681,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
// IL_0301: newobj instance void class [mscorlib] System.Func`2<class ViewModel, valuetype[mscorlib] System.ValueTuple`2<string, bool>>::'.ctor'(object, native int)
yield return Create(Ldnull);
yield return Create(Ldftn, getter);
yield return Create(Newobj, module.ImportCtorReference(("mscorlib", "System", "Func`2"), paramCount: 2, classArguments: new[] { tSourceRef, tupleRef }));
yield return Create(Newobj, module.ImportCtorReference(context.Cache, ("mscorlib", "System", "Func`2"), paramCount: 2, classArguments: new[] { tSourceRef, tupleRef }));
}
static IEnumerable<Instruction> CompiledBindingGetSetter(TypeReference tSourceRef, TypeReference tPropertyRef, IList<(PropertyDefinition property, TypeReference propDeclTypeRef, string indexArg)> properties, ElementNode node, ILContext context)
@ -702,7 +704,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
// }
var module = context.Module;
var setter = new MethodDefinition($"<{context.Body.Method.Name}>typedBindingsM__{typedBindingCount++}",
var setter = new MethodDefinition($"<{context.Body.Method.Name}>typedBindingsM__{context.Cache.TypedBindingCount++}",
MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.Static,
module.TypeSystem.Void)
{
@ -711,7 +713,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
new ParameterDefinition(tPropertyRef)
},
CustomAttributes = {
new CustomAttribute (module.ImportCtorReference(("mscorlib", "System.Runtime.CompilerServices", "CompilerGeneratedAttribute"), parameterTypes: null))
new CustomAttribute (module.ImportCtorReference(context.Cache, ("mscorlib", "System.Runtime.CompilerServices", "CompilerGeneratedAttribute"), parameterTypes: null))
}
};
setter.Body.InitLocals = true;
@ -801,7 +803,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
// IL_002b: newobj instance void class [mscorlib]System.Action`2<class ViewModel, string>::'.ctor'(object, native int)
yield return Create(Ldnull);
yield return Create(Ldftn, setter);
yield return Create(Newobj, module.ImportCtorReference(("mscorlib", "System", "Action`2"),
yield return Create(Newobj, module.ImportCtorReference(context.Cache, ("mscorlib", "System", "Action`2"),
paramCount: 2,
classArguments:
new[] { tSourceRef, tPropertyRef }));
@ -834,13 +836,13 @@ namespace Microsoft.Maui.Controls.Build.Tasks
for (int i = 0; i < properties.Count; i++)
{
var tuple = properties[i];
var partGetter = new MethodDefinition($"<{context.Body.Method.Name}>typedBindingsM__{typedBindingCount++}", MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.Static, module.TypeSystem.Object)
var partGetter = new MethodDefinition($"<{context.Body.Method.Name}>typedBindingsM__{context.Cache.TypedBindingCount++}", MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.Static, module.TypeSystem.Object)
{
Parameters = {
new ParameterDefinition(tSourceRef)
},
CustomAttributes = {
new CustomAttribute (module.ImportCtorReference(("mscorlib", "System.Runtime.CompilerServices", "CompilerGeneratedAttribute"), parameterTypes: null))
new CustomAttribute (module.ImportCtorReference(context.Cache, ("mscorlib", "System.Runtime.CompilerServices", "CompilerGeneratedAttribute"), parameterTypes: null))
}
};
partGetter.Body.InitLocals = true;
@ -875,11 +877,11 @@ namespace Microsoft.Maui.Controls.Build.Tasks
partGetters.Add(partGetter);
}
var funcObjRef = context.Module.ImportReference(module.ImportReference(("mscorlib", "System", "Func`2")).MakeGenericInstanceType(new[] { tSourceRef, module.TypeSystem.Object }));
var tupleRef = context.Module.ImportReference(module.ImportReference(("mscorlib", "System", "Tuple`2")).MakeGenericInstanceType(new[] { funcObjRef, module.TypeSystem.String }));
var funcCtor = module.ImportReference(funcObjRef.ResolveCached().GetConstructors().First());
var funcObjRef = context.Module.ImportReference(module.ImportReference(context.Cache, ("mscorlib", "System", "Func`2")).MakeGenericInstanceType(new[] { tSourceRef, module.TypeSystem.Object }));
var tupleRef = context.Module.ImportReference(module.ImportReference(context.Cache, ("mscorlib", "System", "Tuple`2")).MakeGenericInstanceType(new[] { funcObjRef, module.TypeSystem.String }));
var funcCtor = module.ImportReference(funcObjRef.ResolveCached(context.Cache).GetConstructors().First());
funcCtor = funcCtor.MakeGeneric(funcObjRef, new[] { tSourceRef, module.TypeSystem.Object });
var tupleCtor = module.ImportReference(tupleRef.ResolveCached().GetConstructors().First());
var tupleCtor = module.ImportReference(tupleRef.ResolveCached(context.Cache).GetConstructors().First());
tupleCtor = tupleCtor.MakeGeneric(tupleRef, new[] { funcObjRef, module.TypeSystem.String });
// IL_003a: ldc.i4.2
@ -925,7 +927,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
var bpRef = GetBindablePropertyReference(parent, propertyName.NamespaceURI, ref localName, out System.Boolean attached, context, iXmlLineInfo);
//If the target is an event, connect
if (CanConnectEvent(parent, localName, valueNode, attached))
if (CanConnectEvent(parent, localName, valueNode, attached, context))
return ConnectEvent(parent, localName, valueNode, iXmlLineInfo, context);
//If Value is DynamicResource, SetDynamicResource
@ -978,7 +980,8 @@ namespace Microsoft.Maui.Controls.Build.Tasks
var bpOwnerType = parent.VariableType;
attached = GetNameAndTypeRef(ref bpOwnerType, namespaceURI, ref localName, context, iXmlLineInfo);
var name = $"{localName}Property";
FieldDefinition bpDef = bpOwnerType.GetField(fd => fd.Name == name &&
FieldDefinition bpDef = bpOwnerType.GetField(context.Cache,
fd => fd.Name == name &&
fd.IsStatic &&
(fd.IsPublic || fd.IsAssembly), out declaringTypeReference);
if (bpDef == null)
@ -993,9 +996,9 @@ namespace Microsoft.Maui.Controls.Build.Tasks
return bpRef;
}
static bool CanConnectEvent(VariableDefinition parent, string localName, INode valueNode, bool attached)
static bool CanConnectEvent(VariableDefinition parent, string localName, INode valueNode, bool attached, ILContext context)
{
return !attached && valueNode is ValueNode && parent.VariableType.GetEvent(ed => ed.Name == localName, out _) != null;
return !attached && valueNode is ValueNode && parent.VariableType.GetEvent(context.Cache, ed => ed.Name == localName, out _) != null;
}
static IEnumerable<Instruction> ConnectEvent(VariableDefinition parent, string localName, INode valueNode, IXmlLineInfo iXmlLineInfo, ILContext context)
@ -1003,7 +1006,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
var elementType = parent.VariableType;
var module = context.Body.Method.Module;
TypeReference eventDeclaringTypeRef;
var eventinfo = elementType.GetEvent(ed => ed.Name == localName, out eventDeclaringTypeRef);
var eventinfo = elementType.GetEvent(context.Cache, ed => ed.Name == localName, out eventDeclaringTypeRef);
var adder = module.ImportReference(eventinfo.AddMethod);
adder = adder.ResolveGenericParameters(eventDeclaringTypeRef, module);
@ -1024,20 +1027,20 @@ namespace Microsoft.Maui.Controls.Build.Tasks
var declaringType = context.Body.Method.DeclaringType;
while (declaringType.IsNested)
declaringType = declaringType.DeclaringType;
var handler = declaringType.AllMethods().FirstOrDefault(md =>
var handler = declaringType.AllMethods(context.Cache).FirstOrDefault(md =>
{
if (md.methodDef.Name != value as string)
return false;
//check if the handler signature matches the Invoke signature;
var invoke = module.ImportReference(eventinfo.EventType.ResolveCached().GetMethods().First(eventmd => eventmd.Name == "Invoke"));
var invoke = module.ImportReference(eventinfo.EventType.ResolveCached(context.Cache).GetMethods().First(eventmd => eventmd.Name == "Invoke"));
invoke = invoke.ResolveGenericParameters(eventinfo.EventType, module);
if (!md.methodDef.ReturnType.InheritsFromOrImplements(invoke.ReturnType) || invoke.Parameters.Count != md.methodDef.Parameters.Count)
if (!md.methodDef.ReturnType.InheritsFromOrImplements(context.Cache, invoke.ReturnType) || invoke.Parameters.Count != md.methodDef.Parameters.Count)
return false;
if (!invoke.ContainsGenericParameter)
for (var i = 0; i < invoke.Parameters.Count; i++)
if (!invoke.Parameters[i].ParameterType.InheritsFromOrImplements(md.methodDef.Parameters[i].ParameterType))
if (!invoke.Parameters[i].ParameterType.InheritsFromOrImplements(context.Cache, md.methodDef.Parameters[i].ParameterType))
return false;
//TODO check generic parameters if any
@ -1050,7 +1053,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
throw new BuildException(MissingEventHandler, iXmlLineInfo, null, value, declaringType);
//FIXME: eventually get the right ctor instead fo the First() one, just in case another one could exists (not even sure it's possible).
var ctor = module.ImportReference(eventinfo.EventType.ResolveCached().GetConstructors().First());
var ctor = module.ImportReference(eventinfo.EventType.ResolveCached(context.Cache).GetConstructors().First());
ctor = ctor.ResolveGenericParameters(eventinfo.EventType, module);
if (handler.methodDef.IsStatic)
@ -1060,7 +1063,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
else
{
if (context.Root is VariableDefinition)
foreach (var instruction in (context.Root as VariableDefinition).LoadAs(ctor.Parameters[0].ParameterType.ResolveGenericParameters(ctor), module))
foreach (var instruction in (context.Root as VariableDefinition).LoadAs(context.Cache, ctor.Parameters[0].ParameterType.ResolveGenericParameters(ctor), module))
yield return instruction;
else if (context.Root is FieldDefinition)
{
@ -1104,13 +1107,14 @@ namespace Microsoft.Maui.Controls.Build.Tasks
var dynamicResourceType = ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Internals", "DynamicResource");
var dynamicResourceHandlerType = ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Internals", "IDynamicResourceHandler");
foreach (var instruction in parent.LoadAs(module.GetTypeDefinition(dynamicResourceHandlerType), module))
foreach (var instruction in parent.LoadAs(context.Cache, module.GetTypeDefinition(context.Cache, dynamicResourceHandlerType), module))
yield return instruction;
yield return Create(Ldsfld, bpRef);
foreach (var instruction in context.Variables[elementNode].LoadAs(module.GetTypeDefinition(dynamicResourceType), module))
foreach (var instruction in context.Variables[elementNode].LoadAs(context.Cache, module.GetTypeDefinition(context.Cache, dynamicResourceType), module))
yield return instruction;
yield return Create(Callvirt, module.ImportPropertyGetterReference(dynamicResourceType, propertyName: "Key"));
yield return Create(Callvirt, module.ImportMethodReference(dynamicResourceHandlerType,
yield return Create(Callvirt, module.ImportPropertyGetterReference(context.Cache, dynamicResourceType, propertyName: "Key"));
yield return Create(Callvirt, module.ImportMethodReference(context.Cache,
dynamicResourceHandlerType,
methodName: "SetDynamicResource",
parameterTypes: new[] {
("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "BindableProperty"),
@ -1129,11 +1133,11 @@ namespace Microsoft.Maui.Controls.Build.Tasks
if (!context.Variables.TryGetValue(valueNode as IElementNode, out VariableDefinition varValue))
return false;
var implicitOperator = varValue.VariableType.GetImplicitOperatorTo(module.ImportReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "BindingBase")), module);
var implicitOperator = varValue.VariableType.GetImplicitOperatorTo(context.Cache, module.ImportReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "BindingBase")), module);
if (implicitOperator != null)
return true;
return varValue.VariableType.InheritsFromOrImplements(module.ImportReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "BindingBase")));
return varValue.VariableType.InheritsFromOrImplements(context.Cache, module.ImportReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "BindingBase")));
}
static IEnumerable<Instruction> SetBinding(VariableDefinition parent, FieldReference bpRef, IElementNode elementNode, IXmlLineInfo iXmlLineInfo, ILContext context)
@ -1146,12 +1150,12 @@ namespace Microsoft.Maui.Controls.Build.Tasks
};
//TODO: check if parent is a BP
foreach (var instruction in parent.LoadAs(module.GetTypeDefinition(bindableObjectType), module))
foreach (var instruction in parent.LoadAs(context.Cache, module.GetTypeDefinition(context.Cache, bindableObjectType), module))
yield return instruction;
yield return Create(Ldsfld, bpRef);
foreach (var instruction in context.Variables[elementNode].LoadAs(module.GetTypeDefinition(parameterTypes[1]), module))
foreach (var instruction in context.Variables[elementNode].LoadAs(context.Cache, module.GetTypeDefinition(context.Cache, parameterTypes[1]), module))
yield return instruction;
yield return Create(Callvirt, module.ImportMethodReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "BindableObject"),
yield return Create(Callvirt, module.ImportMethodReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "BindableObject"),
methodName: "SetBinding",
parameterTypes: parameterTypes));
}
@ -1172,12 +1176,12 @@ namespace Microsoft.Maui.Controls.Build.Tasks
if (!context.Variables.TryGetValue(elementNode, out VariableDefinition varValue))
return false;
var bpTypeRef = bpRef.GetBindablePropertyType(iXmlLineInfo, module);
var bpTypeRef = bpRef.GetBindablePropertyType(context.Cache, iXmlLineInfo, module);
// If it's an attached BP, there's no second chance to handle IMarkupExtensions, so we try here.
// Worst case scenario ? InvalidCastException at runtime
if (attached && varValue.VariableType.FullName == "System.Object")
return true;
var implicitOperator = varValue.VariableType.GetImplicitOperatorTo(bpTypeRef, module);
var implicitOperator = varValue.VariableType.GetImplicitOperatorTo(context.Cache, bpTypeRef, module);
if (implicitOperator != null)
return true;
@ -1185,7 +1189,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
if (varValue.VariableType.IsValueType && bpTypeRef.FullName == "System.Object")
return true;
return varValue.VariableType.InheritsFromOrImplements(bpTypeRef);
return varValue.VariableType.InheritsFromOrImplements(context.Cache, bpTypeRef);
}
static bool CanGetValue(VariableDefinition parent, FieldReference bpRef, bool attached, IXmlLineInfo iXmlLineInfo, ILContext context, out TypeReference propertyType)
@ -1196,10 +1200,10 @@ namespace Microsoft.Maui.Controls.Build.Tasks
if (bpRef == null)
return false;
if (!parent.VariableType.InheritsFromOrImplements(module.ImportReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "BindableObject"))))
if (!parent.VariableType.InheritsFromOrImplements(context.Cache, module.ImportReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "BindableObject"))))
return false;
propertyType = bpRef.GetBindablePropertyType(iXmlLineInfo, module);
propertyType = bpRef.GetBindablePropertyType(context.Cache, iXmlLineInfo, module);
return true;
}
@ -1215,7 +1219,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
// IL_000d: ldstr "foo"
// IL_0012: callvirt instance void class [Microsoft.Maui.Controls]Microsoft.Maui.Controls.BindableObject::SetValue(class [Microsoft.Maui.Controls]Microsoft.Maui.Controls.BindableProperty, object)
foreach (var instruction in parent.LoadAs(module.GetTypeDefinition(bindableObjectType), module))
foreach (var instruction in parent.LoadAs(context.Cache, module.GetTypeDefinition(context.Cache, bindableObjectType), module))
yield return instruction;
yield return Create(Ldsfld, bpRef);
@ -1227,13 +1231,14 @@ namespace Microsoft.Maui.Controls.Build.Tasks
}
else if (elementNode != null)
{
var bpTypeRef = bpRef.GetBindablePropertyType(iXmlLineInfo, module);
foreach (var instruction in context.Variables[elementNode].LoadAs(bpTypeRef, module))
var bpTypeRef = bpRef.GetBindablePropertyType(context.Cache, iXmlLineInfo, module);
foreach (var instruction in context.Variables[elementNode].LoadAs(context.Cache, bpTypeRef, module))
yield return instruction;
if (bpTypeRef.IsValueType)
yield return Create(Box, module.ImportReference(bpTypeRef));
}
yield return Create(Callvirt, module.ImportMethodReference(bindableObjectType,
yield return Create(Callvirt, module.ImportMethodReference(context.Cache,
bindableObjectType,
methodName: "SetValue",
parameterTypes: new[] {
("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "BindableProperty"),
@ -1243,7 +1248,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
static IEnumerable<Instruction> GetValue(VariableDefinition parent, FieldReference bpRef, IXmlLineInfo iXmlLineInfo, ILContext context, out TypeReference propertyType)
{
propertyType = bpRef.GetBindablePropertyType(iXmlLineInfo, context.Body.Method.Module);
propertyType = bpRef.GetBindablePropertyType(context.Cache, iXmlLineInfo, context.Body.Method.Module);
return GetValue(parent, bpRef, iXmlLineInfo, context);
}
@ -1252,11 +1257,12 @@ namespace Microsoft.Maui.Controls.Build.Tasks
var module = context.Body.Method.Module;
var bindableObjectType = ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "BindableObject");
foreach (var instruction in parent.LoadAs(module.GetTypeDefinition(bindableObjectType), module))
foreach (var instruction in parent.LoadAs(context.Cache, module.GetTypeDefinition(context.Cache, bindableObjectType), module))
yield return instruction;
yield return Create(Ldsfld, bpRef);
yield return Create(Callvirt, module.ImportMethodReference(bindableObjectType,
yield return Create(Callvirt, module.ImportMethodReference(context.Cache,
bindableObjectType,
methodName: "GetValue",
parameterTypes: new[] { ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "BindableProperty") }));
}
@ -1265,7 +1271,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
{
var module = context.Body.Method.Module;
TypeReference declaringTypeReference;
var property = parent.VariableType.GetProperty(pd => pd.Name == localName, out declaringTypeReference);
var property = parent.VariableType.GetProperty(context.Cache, pd => pd.Name == localName, out declaringTypeReference);
if (property == null)
return false;
var propertyType = property.PropertyType.ResolveGenericParameters(declaringTypeReference);
@ -1274,7 +1280,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
return false;
var valueNode = node as ValueNode;
if (valueNode != null && valueNode.CanConvertValue(context, propertyType, new ICustomAttributeProvider[] { property, propertyType.ResolveCached() }))
if (valueNode != null && valueNode.CanConvertValue(context, propertyType, new ICustomAttributeProvider[] { property, propertyType.ResolveCached(context.Cache) }))
return true;
var elementNode = node as IElementNode;
@ -1282,9 +1288,9 @@ namespace Microsoft.Maui.Controls.Build.Tasks
return false;
var vardef = context.Variables[elementNode];
var implicitOperator = vardef.VariableType.GetImplicitOperatorTo(propertyType, module);
var implicitOperator = vardef.VariableType.GetImplicitOperatorTo(context.Cache, propertyType, module);
if (vardef.VariableType.InheritsFromOrImplements(propertyType))
if (vardef.VariableType.InheritsFromOrImplements(context.Cache, propertyType))
return true;
if (implicitOperator != null)
return true;
@ -1303,14 +1309,14 @@ namespace Microsoft.Maui.Controls.Build.Tasks
var module = context.Body.Method.Module;
propertyType = null;
TypeReference declaringTypeReference;
var property = parent.VariableType.GetProperty(pd => pd.Name == localName, out declaringTypeReference);
var property = parent.VariableType.GetProperty(context.Cache, pd => pd.Name == localName, out declaringTypeReference);
if (property == null)
return false;
var propertyGetter = property.GetMethod;
if (propertyGetter == null || !propertyGetter.IsPublic || propertyGetter.IsStatic)
return false;
module.ImportReference(parent.VariableType.ResolveCached());
module.ImportReference(parent.VariableType.ResolveCached(context.Cache));
var propertyGetterRef = module.ImportReference(module.ImportReference(propertyGetter).ResolveGenericParameters(declaringTypeReference, module));
propertyGetterRef.ImportTypes(module);
propertyType = propertyGetterRef.ReturnType.ResolveGenericParameters(declaringTypeReference);
@ -1322,7 +1328,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
{
var module = context.Body.Method.Module;
TypeReference declaringTypeReference;
var property = parent.VariableType.GetProperty(pd => pd.Name == localName, out declaringTypeReference);
var property = parent.VariableType.GetProperty(context.Cache, pd => pd.Name == localName, out declaringTypeReference);
var propertyIsObsolete = property.CustomAttributes.Any(ca => ca.AttributeType.FullName == "System.ObsoleteAttribute");
if (propertyIsObsolete)
context.LoggingHelper.LogWarning("XamlC", null, null, context.XamlFilePath, iXmlLineInfo.LineNumber, iXmlLineInfo.LinePosition, 0, 0, $"Property {localName} is deprecated.", null);
@ -1336,7 +1342,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
// IL_0008: ldstr "foo"
// IL_000d: callvirt instance void class [Microsoft.Maui.Controls]Microsoft.Maui.Controls.Label::set_Text(string)
module.ImportReference(parent.VariableType.ResolveCached());
module.ImportReference(parent.VariableType.ResolveCached(context.Cache));
var propertySetterRef = module.ImportReference(module.ImportReference(propertySetter).ResolveGenericParameters(declaringTypeReference, module));
propertySetterRef.ImportTypes(module);
var propertyType = property.PropertyType.ResolveGenericParameters(declaringTypeReference);
@ -1351,7 +1357,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
if (valueNode != null)
{
foreach (var instruction in valueNode.PushConvertedValue(context, propertyType, new ICustomAttributeProvider[] { property, propertyType.ResolveCached() }, valueNode.PushServiceProvider(context, propertyRef: property), false, true))
foreach (var instruction in valueNode.PushConvertedValue(context, propertyType, new ICustomAttributeProvider[] { property, propertyType.ResolveCached(context.Cache) }, valueNode.PushServiceProvider(context, propertyRef: property), false, true))
yield return instruction;
if (parent.VariableType.IsValueType)
yield return Instruction.Create(OpCodes.Call, propertySetterRef);
@ -1360,7 +1366,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
}
else if (elementNode != null)
{
foreach (var instruction in context.Variables[elementNode].LoadAs(propertyType, module))
foreach (var instruction in context.Variables[elementNode].LoadAs(context.Cache, propertyType, module))
yield return instruction;
if (parent.VariableType.IsValueType)
yield return Instruction.Create(OpCodes.Call, propertySetterRef);
@ -1372,10 +1378,10 @@ namespace Microsoft.Maui.Controls.Build.Tasks
static IEnumerable<Instruction> Get(VariableDefinition parent, string localName, IXmlLineInfo iXmlLineInfo, ILContext context, out TypeReference propertyType)
{
var module = context.Body.Method.Module;
var property = parent.VariableType.GetProperty(pd => pd.Name == localName, out var declaringTypeReference);
var property = parent.VariableType.GetProperty(context.Cache, pd => pd.Name == localName, out var declaringTypeReference);
var propertyGetter = property.GetMethod;
module.ImportReference(parent.VariableType.ResolveCached());
module.ImportReference(parent.VariableType.ResolveCached(context.Cache));
var propertyGetterRef = module.ImportReference(module.ImportReference(propertyGetter).ResolveGenericParameters(declaringTypeReference, module));
propertyGetterRef.ImportTypes(module);
propertyType = propertyGetterRef.ReturnType.ResolveGenericParameters(declaringTypeReference);
@ -1408,7 +1414,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
if (!context.Variables.TryGetValue(elementNode, out VariableDefinition varValue))
return false;
var adderTuple = propertyType.GetMethods(md => md.Name == "Add"
var adderTuple = propertyType.GetMethods(context.Cache, md => md.Name == "Add"
&& md.Parameters.Count == 1, module).FirstOrDefault();
if (adderTuple == null)
return false;
@ -1416,10 +1422,10 @@ namespace Microsoft.Maui.Controls.Build.Tasks
var adderRef = module.ImportReference(adderTuple.Item1);
adderRef = module.ImportReference(adderRef.ResolveGenericParameters(adderTuple.Item2, module));
var paramType = adderRef.Parameters[0].ParameterType.ResolveGenericParameters(adderRef);
if (varValue.VariableType.InheritsFromOrImplements(paramType))
if (varValue.VariableType.InheritsFromOrImplements(context.Cache, paramType))
return true;
if (varValue.VariableType.GetImplicitOperatorTo(paramType, module) != null)
if (varValue.VariableType.GetImplicitOperatorTo(context.Cache, paramType, module) != null)
return true;
if (paramType.FullName == "System.Object" && varValue.VariableType.IsValueType)
@ -1428,19 +1434,17 @@ namespace Microsoft.Maui.Controls.Build.Tasks
return CanAddToResourceDictionary(parent, propertyType, elementNode, lineInfo, context);
}
static Dictionary<VariableDefinition, IList<string>> resourceNamesInUse = new Dictionary<VariableDefinition, IList<string>>();
static bool CanAddToResourceDictionary(VariableDefinition parent, TypeReference collectionType, IElementNode node, IXmlLineInfo lineInfo, ILContext context)
{
if (collectionType.FullName != "Microsoft.Maui.Controls.ResourceDictionary"
&& collectionType.ResolveCached().BaseType?.FullName != "Microsoft.Maui.Controls.ResourceDictionary")
&& collectionType.ResolveCached(context.Cache).BaseType?.FullName != "Microsoft.Maui.Controls.ResourceDictionary")
return false;
if (node.Properties.ContainsKey(XmlName.xKey))
{
var valueNode = node.Properties[XmlName.xKey] as ValueNode ?? throw new BuildException(XKeyNotLiteral, lineInfo, null);
var key = (valueNode).Value as string;
if (!resourceNamesInUse.TryGetValue(parent, out var names))
resourceNamesInUse[parent] = (names = new List<string>());
var names = context.Cache.GetResourceNamesInUse(parent);
if (names.Contains(key))
throw new BuildException(ResourceDictDuplicateKey, lineInfo, null, key);
return true;
@ -1449,7 +1453,8 @@ namespace Microsoft.Maui.Controls.Build.Tasks
//is there a RD.Add() overrides that accepts this ?
var nodeTypeRef = context.Variables[node].VariableType;
var module = context.Body.Method.Module;
if (module.ImportMethodReference(module.GetTypeDefinition(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "ResourceDictionary")),
if (module.ImportMethodReference(context.Cache,
module.GetTypeDefinition(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "ResourceDictionary")),
methodName: "Add",
parameterTypes: new[] { (nodeTypeRef) }) != null)
return true;
@ -1473,11 +1478,11 @@ namespace Microsoft.Maui.Controls.Build.Tasks
yield break;
}
var adderTuple = propertyType.GetMethods(md => md.Name == "Add" && md.Parameters.Count == 1, module).FirstOrDefault();
var adderTuple = propertyType.GetMethods(context.Cache, md => md.Name == "Add" && md.Parameters.Count == 1, module).FirstOrDefault();
var adderRef = module.ImportReference(adderTuple.Item1);
adderRef = module.ImportReference(adderRef.ResolveGenericParameters(adderTuple.Item2, module));
foreach (var instruction in vardef.LoadAs(adderRef.Parameters[0].ParameterType.ResolveGenericParameters(adderRef), module))
foreach (var instruction in vardef.LoadAs(context.Cache, adderRef.Parameters[0].ParameterType.ResolveGenericParameters(adderRef), module))
yield return instruction;
yield return Instruction.Create(OpCodes.Callvirt, adderRef);
if (adderRef.ReturnType.FullName != "System.Void")
@ -1490,7 +1495,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
if (node.Properties.ContainsKey(XmlName.xKey))
{
var names = resourceNamesInUse[parent];
var names = context.Cache.GetResourceNamesInUse(parent);
var valueNode = node.Properties[XmlName.xKey] as ValueNode ?? throw new BuildException(XKeyNotLiteral, lineInfo, null);
var key = (valueNode).Value as string;
names.Add(key);
@ -1499,9 +1504,9 @@ namespace Microsoft.Maui.Controls.Build.Tasks
// IL_0019: ldstr "foo"
// IL_001e: callvirt instance void class [Microsoft.Maui.Controls]Microsoft.Maui.Controls.ResourceDictionary::Add(string, object)
yield return Create(Ldstr, (key));
foreach (var instruction in context.Variables[node].LoadAs(module.TypeSystem.Object, module))
foreach (var instruction in context.Variables[node].LoadAs(context.Cache, module.TypeSystem.Object, module))
yield return instruction;
yield return Create(Callvirt, module.ImportMethodReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "ResourceDictionary"),
yield return Create(Callvirt, module.ImportMethodReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "ResourceDictionary"),
methodName: "Add",
parameterTypes: new[] {
("mscorlib", "System", "String"),
@ -1512,7 +1517,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
var nodeTypeRef = context.Variables[node].VariableType;
yield return Create(Ldloc, context.Variables[node]);
yield return Create(Callvirt, module.ImportMethodReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "ResourceDictionary"),
yield return Create(Callvirt, module.ImportMethodReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "ResourceDictionary"),
methodName: "Add",
parameterTypes: new[] { (nodeTypeRef.Scope.Name, nodeTypeRef.Namespace, nodeTypeRef.Name) }));
yield break;
@ -1526,7 +1531,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
{
var typename = localname.Substring(0, dotIdx);
localname = localname.Substring(dotIdx + 1);
elementType = new XmlType(namespaceURI, typename, null).GetTypeReference(context.Body.Method.Module, lineInfo);
elementType = new XmlType(namespaceURI, typename, null).GetTypeReference(context.Cache, context.Body.Method.Module, lineInfo);
return true;
}
return false;
@ -1539,7 +1544,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
var dataTemplateType = ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "ElementTemplate");
var parentVar = parentContext.Variables[parentNode];
//Push the DataTemplate to the stack, for setting the template
parentContext.IL.Append(parentVar.LoadAs(module.GetTypeDefinition(dataTemplateType), module));
parentContext.IL.Append(parentVar.LoadAs(parentContext.Cache, module.GetTypeDefinition(parentContext.Cache, dataTemplateType), module));
//Create nested class
// .class nested private auto ansi sealed beforefieldinit '<Main>c__AnonStorey0'
@ -1548,19 +1553,19 @@ namespace Microsoft.Maui.Controls.Build.Tasks
var anonType = new TypeDefinition(
null,
"<" + parentContext.Body.Method.Name + ">_anonXamlCDataTemplate_" + dtcount++,
"<" + parentContext.Body.Method.Name + ">_anonXamlCDataTemplate_" + parentContext.Cache.DataTemplateCount++,
TypeAttributes.BeforeFieldInit |
TypeAttributes.Sealed |
TypeAttributes.NestedPrivate)
{
BaseType = module.TypeSystem.Object,
CustomAttributes = {
new CustomAttribute (module.ImportCtorReference(("mscorlib", "System.Runtime.CompilerServices", "CompilerGeneratedAttribute"), parameterTypes: null)),
new CustomAttribute (module.ImportCtorReference(parentContext.Cache, ("mscorlib", "System.Runtime.CompilerServices", "CompilerGeneratedAttribute"), parameterTypes: null)),
}
};
parentContext.Body.Method.DeclaringType.NestedTypes.Add(anonType);
var ctor = anonType.AddDefaultConstructor();
var ctor = anonType.AddDefaultConstructor(parentContext.Cache);
var loadTemplate = new MethodDefinition("LoadDataTemplate",
MethodAttributes.Assembly | MethodAttributes.HideBySig,
@ -1568,7 +1573,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
loadTemplate.Body.InitLocals = true;
anonType.Methods.Add(loadTemplate);
var parentValues = new FieldDefinition("parentValues", FieldAttributes.Assembly, module.ImportArrayReference(("mscorlib", "System", "Object")));
var parentValues = new FieldDefinition("parentValues", FieldAttributes.Assembly, module.ImportArrayReference(parentContext.Cache, ("mscorlib", "System", "Object")));
anonType.Fields.Add(parentValues);
TypeReference rootType = null;
@ -1585,7 +1590,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
//Fill the loadTemplate Body
var templateIl = loadTemplate.Body.GetILProcessor();
templateIl.Emit(OpCodes.Nop);
var templateContext = new ILContext(templateIl, loadTemplate.Body, module, parentValues)
var templateContext = new ILContext(templateIl, loadTemplate.Body, module, parentContext.Cache, parentValues)
{
Root = root,
XamlFilePath = parentContext.XamlFilePath,
@ -1596,7 +1601,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
node.Accept(new SetResourcesVisitor(templateContext), null);
node.Accept(new SetPropertiesVisitor(templateContext, stopOnResourceDictionary: true), null);
templateIl.Append(templateContext.Variables[node].LoadAs(module.TypeSystem.Object, module));
templateIl.Append(templateContext.Variables[node].LoadAs(parentContext.Cache, module.TypeSystem.Object, module));
templateIl.Emit(OpCodes.Ret);
//Instanciate nested class
@ -1609,7 +1614,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
parentIl.Emit(OpCodes.Stfld, parentValues);
parentIl.Emit(OpCodes.Dup); //Duplicate the nestedclass instance
if (parentContext.Root is VariableDefinition)
parentIl.Append((parentContext.Root as VariableDefinition).LoadAs(module.TypeSystem.Object, module));
parentIl.Append((parentContext.Root as VariableDefinition).LoadAs(parentContext.Cache, module.TypeSystem.Object, module));
else if (parentContext.Root is FieldDefinition)
{
parentIl.Emit(OpCodes.Ldarg_0);
@ -1621,11 +1626,11 @@ namespace Microsoft.Maui.Controls.Build.Tasks
//SetDataTemplate
parentIl.Emit(Ldftn, loadTemplate);
parentIl.Emit(Newobj, module.ImportCtorReference(("mscorlib", "System", "Func`1"),
parentIl.Emit(Newobj, module.ImportCtorReference(parentContext.Cache, ("mscorlib", "System", "Func`1"),
classArguments: new[] { ("mscorlib", "System", "Object") },
paramCount: 2));
parentContext.IL.Emit(OpCodes.Callvirt, module.ImportPropertySetterReference(dataTemplateType, propertyName: "LoadTemplate"));
parentContext.IL.Emit(OpCodes.Callvirt, module.ImportPropertySetterReference(parentContext.Cache, dataTemplateType, propertyName: "LoadTemplate"));
loadTemplate.Body.Optimize();
}
@ -1635,7 +1640,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
if (propertyName != XmlName.xName)
return false;
var attributes = variableDefinition.VariableType.ResolveCached()
var attributes = variableDefinition.VariableType.ResolveCached(Context.Cache)
.CustomAttributes.Where(attribute => attribute.AttributeType.FullName == "Microsoft.Maui.Controls.Xaml.RuntimeNamePropertyAttribute").ToList();
if (!attributes.Any())

Просмотреть файл

@ -73,7 +73,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
{
var parentVar = Context.Variables[(IElementNode)node];
return parentVar.VariableType.FullName == "Microsoft.Maui.Controls.ResourceDictionary"
|| parentVar.VariableType.ResolveCached().BaseType?.FullName == "Microsoft.Maui.Controls.ResourceDictionary";
|| parentVar.VariableType.ResolveCached(Context.Cache).BaseType?.FullName == "Microsoft.Maui.Controls.ResourceDictionary";
}
public bool SkipChildren(INode node, INode parentNode)

Просмотреть файл

@ -10,24 +10,24 @@ namespace Microsoft.Maui.Controls.Build.Tasks
{
static class TypeDefinitionExtensions
{
public static MethodDefinition AddDefaultConstructor(this TypeDefinition targetType)
public static MethodDefinition AddDefaultConstructor(this TypeDefinition targetType, XamlCache cache)
{
var module = targetType.Module;
var parentType = module.ImportReference(("mscorlib", "System", "Object"));
var parentType = module.ImportReference(cache, ("mscorlib", "System", "Object"));
return AddDefaultConstructor(targetType, parentType);
return AddDefaultConstructor(targetType, cache, parentType);
}
public static MethodDefinition AddDefaultConstructor(this TypeDefinition targetType, TypeReference parentType)
public static MethodDefinition AddDefaultConstructor(this TypeDefinition targetType, XamlCache cache, TypeReference parentType)
{
var module = targetType.Module;
var voidType = module.ImportReference(("mscorlib", "System", "Void"));
var voidType = module.ImportReference(cache, ("mscorlib", "System", "Void"));
var methodAttributes = MethodAttributes.Public |
MethodAttributes.HideBySig |
MethodAttributes.SpecialName |
MethodAttributes.RTSpecialName;
var parentctor = module.ImportCtorReference(parentType, paramCount: 0) ?? module.ImportCtorReference(("mscorlib", "System", "Object"), parameterTypes: null);
var parentctor = module.ImportCtorReference(cache, parentType, paramCount: 0) ?? module.ImportCtorReference(cache, ("mscorlib", "System", "Object"), parameterTypes: null);
var ctor = new MethodDefinition(".ctor", methodAttributes, voidType)
{
@ -46,7 +46,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
return ctor;
}
public static IEnumerable<(MethodDefinition methodDef, TypeReference declTypeRef)> AllMethods(this TypeDefinition self)
public static IEnumerable<(MethodDefinition methodDef, TypeReference declTypeRef)> AllMethods(this TypeDefinition self, XamlCache cache)
{
TypeReference selfTypeRef = self;
while (self != null)
@ -54,7 +54,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
foreach (var md in self.Methods)
yield return (md, selfTypeRef);
selfTypeRef = self.BaseType;
self = self.BaseType?.ResolveCached();
self = self.BaseType?.ResolveCached(cache);
}
}
}

Просмотреть файл

@ -59,11 +59,11 @@ namespace Microsoft.Maui.Controls.Build.Tasks
static class TypeReferenceExtensions
{
public static PropertyDefinition GetProperty(this TypeReference typeRef, Func<PropertyDefinition, bool> predicate,
public static PropertyDefinition GetProperty(this TypeReference typeRef, XamlCache cache, Func<PropertyDefinition, bool> predicate,
out TypeReference declaringTypeRef)
{
declaringTypeRef = typeRef;
var typeDef = typeRef.ResolveCached();
var typeDef = typeRef.ResolveCached(cache);
var properties = typeDef.Properties.Where(predicate);
if (properties.Any())
return properties.Single();
@ -71,7 +71,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
{
foreach (var face in typeDef.Interfaces)
{
var p = face.InterfaceType.ResolveGenericParameters(typeRef).GetProperty(predicate, out var interfaceDeclaringTypeRef);
var p = face.InterfaceType.ResolveGenericParameters(typeRef).GetProperty(cache, predicate, out var interfaceDeclaringTypeRef);
if (p != null)
{
declaringTypeRef = interfaceDeclaringTypeRef;
@ -81,27 +81,27 @@ namespace Microsoft.Maui.Controls.Build.Tasks
}
if (typeDef.BaseType == null || typeDef.BaseType.FullName == "System.Object")
return null;
return typeDef.BaseType.ResolveGenericParameters(typeRef).GetProperty(predicate, out declaringTypeRef);
return typeDef.BaseType.ResolveGenericParameters(typeRef).GetProperty(cache, predicate, out declaringTypeRef);
}
public static EventDefinition GetEvent(this TypeReference typeRef, Func<EventDefinition, bool> predicate,
public static EventDefinition GetEvent(this TypeReference typeRef, XamlCache cache, Func<EventDefinition, bool> predicate,
out TypeReference declaringTypeRef)
{
declaringTypeRef = typeRef;
var typeDef = typeRef.ResolveCached();
var typeDef = typeRef.ResolveCached(cache);
var events = typeDef.Events.Where(predicate);
if (events.Any())
{
var ev = events.Single();
return ev.ResolveGenericEvent(declaringTypeRef);
return ev.ResolveGenericEvent(cache, declaringTypeRef);
}
if (typeDef.BaseType == null || typeDef.BaseType.FullName == "System.Object")
return null;
return typeDef.BaseType.ResolveGenericParameters(typeRef).GetEvent(predicate, out declaringTypeRef);
return typeDef.BaseType.ResolveGenericParameters(typeRef).GetEvent(cache, predicate, out declaringTypeRef);
}
//this resolves generic eventargs (https://bugzilla.xamarin.com/show_bug.cgi?id=57574)
static EventDefinition ResolveGenericEvent(this EventDefinition eventDef, TypeReference declaringTypeRef)
static EventDefinition ResolveGenericEvent(this EventDefinition eventDef, XamlCache cache, TypeReference declaringTypeRef)
{
if (eventDef == null)
throw new ArgumentNullException(nameof(eventDef));
@ -109,7 +109,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
throw new ArgumentNullException(nameof(declaringTypeRef));
if (!eventDef.EventType.IsGenericInstance)
return eventDef;
if (eventDef.EventType.ResolveCached().FullName != "System.EventHandler`1")
if (eventDef.EventType.ResolveCached(cache).FullName != "System.EventHandler`1")
return eventDef;
var git = eventDef.EventType as GenericInstanceType;
@ -121,37 +121,37 @@ namespace Microsoft.Maui.Controls.Build.Tasks
return eventDef;
}
public static FieldDefinition GetField(this TypeReference typeRef, Func<FieldDefinition, bool> predicate,
public static FieldDefinition GetField(this TypeReference typeRef, XamlCache cache, Func<FieldDefinition, bool> predicate,
out TypeReference declaringTypeRef)
{
declaringTypeRef = typeRef;
var typeDef = typeRef.ResolveCached();
var typeDef = typeRef.ResolveCached(cache);
var bp = typeDef.Fields.Where
(predicate);
if (bp.Any())
return bp.Single();
if (typeDef.BaseType == null || typeDef.BaseType.FullName == "System.Object")
return null;
return typeDef.BaseType.ResolveGenericParameters(typeRef).GetField(predicate, out declaringTypeRef);
return typeDef.BaseType.ResolveGenericParameters(typeRef).GetField(cache, predicate, out declaringTypeRef);
}
public static bool ImplementsInterface(this TypeReference typeRef, TypeReference @interface)
public static bool ImplementsInterface(this TypeReference typeRef, XamlCache cache, TypeReference @interface)
{
var typeDef = typeRef.ResolveCached();
var typeDef = typeRef.ResolveCached(cache);
if (typeDef.Interfaces.Any(tr => tr.InterfaceType.FullName == @interface.FullName))
return true;
var baseTypeRef = typeDef.BaseType;
if (baseTypeRef != null && baseTypeRef.FullName != "System.Object")
return baseTypeRef.ImplementsInterface(@interface);
return baseTypeRef.ImplementsInterface(cache, @interface);
return false;
}
public static bool ImplementsGenericInterface(this TypeReference typeRef, string @interface,
public static bool ImplementsGenericInterface(this TypeReference typeRef, XamlCache cache, string @interface,
out GenericInstanceType interfaceReference, out IList<TypeReference> genericArguments)
{
interfaceReference = null;
genericArguments = null;
var typeDef = typeRef.ResolveCached();
var typeDef = typeRef.ResolveCached(cache);
InterfaceImplementation iface;
if ((iface = typeDef.Interfaces.FirstOrDefault(tr =>
tr.InterfaceType.FullName.StartsWith(@interface, StringComparison.Ordinal) &&
@ -163,7 +163,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
}
var baseTypeRef = typeDef.BaseType;
if (baseTypeRef != null && baseTypeRef.FullName != "System.Object")
return baseTypeRef.ResolveGenericParameters(typeRef).ImplementsGenericInterface(@interface, out interfaceReference, out genericArguments);
return baseTypeRef.ResolveGenericParameters(typeRef).ImplementsGenericInterface(cache, @interface, out interfaceReference, out genericArguments);
return false;
}
@ -184,26 +184,26 @@ namespace Microsoft.Maui.Controls.Build.Tasks
"System.Collections.Generic.IReadOnlyList`1",
};
public static bool InheritsFromOrImplements(this TypeReference typeRef, TypeReference baseClass)
public static bool InheritsFromOrImplements(this TypeReference typeRef, XamlCache cache, TypeReference baseClass)
{
if (typeRef is GenericInstanceType genericInstance)
{
if (baseClass is GenericInstanceType genericInstanceBaseClass &&
TypeRefComparer.Default.Equals(genericInstance.ElementType, genericInstanceBaseClass.ElementType))
{
foreach (var parameter in genericInstanceBaseClass.ElementType.ResolveCached().GenericParameters)
foreach (var parameter in genericInstanceBaseClass.ElementType.ResolveCached(cache).GenericParameters)
{
var argument = genericInstance.GenericArguments[parameter.Position];
var baseClassArgument = genericInstanceBaseClass.GenericArguments[parameter.Position];
if (parameter.IsCovariant)
{
if (!argument.InheritsFromOrImplements(baseClassArgument))
if (!argument.InheritsFromOrImplements(cache, baseClassArgument))
return false;
}
else if (parameter.IsContravariant)
{
if (!baseClassArgument.InheritsFromOrImplements(argument))
if (!baseClassArgument.InheritsFromOrImplements(cache, argument))
return false;
}
else if (!TypeRefComparer.Default.Equals(argument, baseClassArgument))
@ -223,11 +223,11 @@ namespace Microsoft.Maui.Controls.Build.Tasks
if (typeRef.IsArray)
{
var array = (ArrayType)typeRef;
var arrayType = typeRef.ResolveCached();
var arrayType = typeRef.ResolveCached(cache);
if (arrayInterfaces.Contains(baseClass.FullName))
return true;
if (array.IsVector && //generic interfaces are not implemented on multidimensional arrays
arrayGenericInterfaces.Contains(baseClass.ResolveCached().FullName) &&
arrayGenericInterfaces.Contains(baseClass.ResolveCached(cache).FullName) &&
baseClass.IsGenericInstance &&
TypeRefComparer.Default.Equals((baseClass as GenericInstanceType).GenericArguments[0], arrayType))
return true;
@ -240,44 +240,44 @@ namespace Microsoft.Maui.Controls.Build.Tasks
if (typeRef.FullName == "System.Object")
return false;
var typeDef = typeRef.ResolveCached();
if (typeDef.Interfaces.Any(ir => ir.InterfaceType.ResolveGenericParameters(typeRef).InheritsFromOrImplements(baseClass)))
var typeDef = typeRef.ResolveCached(cache);
if (typeDef.Interfaces.Any(ir => ir.InterfaceType.ResolveGenericParameters(typeRef).InheritsFromOrImplements(cache, baseClass)))
return true;
if (typeDef.BaseType == null)
return false;
typeRef = typeDef.BaseType.ResolveGenericParameters(typeRef);
return typeRef.InheritsFromOrImplements(baseClass);
return typeRef.InheritsFromOrImplements(cache, baseClass);
}
static CustomAttribute GetCustomAttribute(this TypeReference typeRef, TypeReference attribute)
static CustomAttribute GetCustomAttribute(this TypeReference typeRef, XamlCache cache, TypeReference attribute)
{
var typeDef = typeRef.ResolveCached();
var typeDef = cache.Resolve(typeRef);
//FIXME: avoid string comparison. make sure the attribute TypeRef is the same one
var attr = typeDef.CustomAttributes.SingleOrDefault(ca => ca.AttributeType.FullName == attribute.FullName);
if (attr != null)
return attr;
var baseTypeRef = typeDef.BaseType;
if (baseTypeRef != null && baseTypeRef.FullName != "System.Object")
return baseTypeRef.GetCustomAttribute(attribute);
return baseTypeRef.GetCustomAttribute(cache, attribute);
return null;
}
public static CustomAttribute GetCustomAttribute(this TypeReference typeRef, ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName) attributeType)
public static CustomAttribute GetCustomAttribute(this TypeReference typeRef, XamlCache cache, ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName) attributeType)
{
return typeRef.GetCustomAttribute(module.ImportReference(attributeType));
return typeRef.GetCustomAttribute(cache, module.ImportReference(cache, attributeType));
}
public static IEnumerable<Tuple<MethodDefinition, TypeReference>> GetMethods(this TypeReference typeRef,
public static IEnumerable<Tuple<MethodDefinition, TypeReference>> GetMethods(this TypeReference typeRef, XamlCache cache,
Func<MethodDefinition, bool> predicate, ModuleDefinition module)
{
return typeRef.GetMethods((md, tr) => predicate(md), module);
return typeRef.GetMethods(cache, (md, tr) => predicate(md), module);
}
public static IEnumerable<Tuple<MethodDefinition, TypeReference>> GetMethods(this TypeReference typeRef,
public static IEnumerable<Tuple<MethodDefinition, TypeReference>> GetMethods(this TypeReference typeRef, XamlCache cache,
Func<MethodDefinition, TypeReference, bool> predicate, ModuleDefinition module)
{
var typeDef = typeRef.ResolveCached();
var typeDef = typeRef.ResolveCached(cache);
foreach (var method in typeDef.Methods.Where(md => predicate(md, typeRef)))
yield return new Tuple<MethodDefinition, TypeReference>(method, typeRef);
if (typeDef.IsInterface)
@ -290,7 +290,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
foreach (var arg in ((GenericInstanceType)typeRef).GenericArguments)
((GenericInstanceType)face.InterfaceType).GenericArguments[i++] = module.ImportReference(arg);
}
foreach (var tuple in face.InterfaceType.GetMethods(predicate, module))
foreach (var tuple in face.InterfaceType.GetMethods(cache, predicate, module))
yield return tuple;
}
yield break;
@ -298,20 +298,20 @@ namespace Microsoft.Maui.Controls.Build.Tasks
if (typeDef.BaseType == null || typeDef.BaseType.FullName == "System.Object")
yield break;
var baseType = typeDef.BaseType.ResolveGenericParameters(typeRef);
foreach (var tuple in baseType.GetMethods(predicate, module))
foreach (var tuple in baseType.GetMethods(cache, predicate, module))
yield return tuple;
}
public static MethodReference GetImplicitOperatorTo(this TypeReference fromType, TypeReference toType, ModuleDefinition module)
public static MethodReference GetImplicitOperatorTo(this TypeReference fromType, XamlCache cache, TypeReference toType, ModuleDefinition module)
{
if (TypeRefComparer.Default.Equals(fromType, toType))
return null;
var implicitOperatorsOnFromType = fromType.GetMethods(md => md.IsPublic
var implicitOperatorsOnFromType = fromType.GetMethods(cache, md => md.IsPublic
&& md.IsStatic
&& md.IsSpecialName
&& md.Name == "op_Implicit", module);
var implicitOperatorsOnToType = toType.GetMethods(md => md.IsPublic
var implicitOperatorsOnToType = toType.GetMethods(cache, md => md.IsPublic
&& md.IsStatic
&& md.IsSpecialName
&& md.Name == "op_Implicit", module);
@ -327,10 +327,10 @@ namespace Microsoft.Maui.Controls.Build.Tasks
var returnType = castDef.ReturnType;
if (returnType.IsGenericParameter)
returnType = ((GenericInstanceType)opDeclTypeRef).GenericArguments[((GenericParameter)returnType).Position];
if (!returnType.InheritsFromOrImplements(toType))
if (!returnType.InheritsFromOrImplements(cache, toType))
continue;
var paramType = cast.Parameters[0].ParameterType.ResolveGenericParameters(castDef);
if (!fromType.InheritsFromOrImplements(paramType))
if (!fromType.InheritsFromOrImplements(cache, paramType))
continue;
return castDef;
}
@ -421,12 +421,6 @@ namespace Microsoft.Maui.Controls.Build.Tasks
return self.ElementType.MakeGenericInstanceType(args.ToArray());
}
static Dictionary<TypeReference, TypeDefinition> resolves = new Dictionary<TypeReference, TypeDefinition>();
public static TypeDefinition ResolveCached(this TypeReference typeReference)
{
if (resolves.TryGetValue(typeReference, out var typeDefinition))
return typeDefinition;
return (resolves[typeReference] = typeReference.Resolve());
}
public static TypeDefinition ResolveCached(this TypeReference typeReference, XamlCache cache) => cache.Resolve(typeReference);
}
}

Просмотреть файл

@ -6,13 +6,13 @@ namespace Microsoft.Maui.Controls.Build.Tasks
{
static class VariableDefinitionExtensions
{
public static IEnumerable<Instruction> LoadAs(this VariableDefinition self, TypeReference type, ModuleDefinition module)
public static IEnumerable<Instruction> LoadAs(this VariableDefinition self, XamlCache cache, TypeReference type, ModuleDefinition module)
{
var implicitOperator = self.VariableType.GetImplicitOperatorTo(type, module);
var implicitOperator = self.VariableType.GetImplicitOperatorTo(cache, type, module);
yield return Instruction.Create(OpCodes.Ldloc, self);
if (!self.VariableType.InheritsFromOrImplements(type) && implicitOperator != null)
if (!self.VariableType.InheritsFromOrImplements(cache, type) && implicitOperator != null)
yield return Instruction.Create(OpCodes.Call, module.ImportReference(implicitOperator));
else if (self.VariableType.IsValueType && !type.IsValueType)
yield return Instruction.Create(OpCodes.Box, module.ImportReference(self.VariableType));

Просмотреть файл

@ -16,6 +16,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
{
public class XamlCTask : XamlTask
{
readonly XamlCache cache = new();
bool hasCompiledXamlResources;
public bool KeepXamlResources { get; set; }
public bool OptimizeIL { get; set; } = true;
@ -110,7 +111,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
{
LoggingHelper.LogMessage(Low, $"{new string(' ', 4)}Resource: {resource.Name}");
string classname;
if (!resource.IsXaml(module, out classname))
if (!resource.IsXaml(cache, module, out classname))
{
LoggingHelper.LogMessage(Low, $"{new string(' ', 6)}skipped.");
continue;
@ -260,11 +261,11 @@ namespace Microsoft.Maui.Controls.Build.Tasks
var module = body.Method.Module;
body.InitLocals = true;
var il = body.GetILProcessor();
var resourcePath = GetPathForType(module, initComp.DeclaringType);
var resourcePath = GetPathForType(cache, module, initComp.DeclaringType);
il.Emit(Nop);
var visitorContext = new ILContext(il, body, module)
var visitorContext = new ILContext(il, body, module, cache)
{
XamlFilePath = xamlFilePath,
LoggingHelper = loggingHelper,
@ -293,11 +294,11 @@ namespace Microsoft.Maui.Controls.Build.Tasks
}
}
internal static string GetPathForType(ModuleDefinition module, TypeReference type)
internal static string GetPathForType(XamlCache cache, ModuleDefinition module, TypeReference type)
{
foreach (var ca in type.Module.GetCustomAttributes())
{
if (!TypeRefComparer.Default.Equals(ca.AttributeType, module.ImportReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "XamlResourceIdAttribute"))))
if (!TypeRefComparer.Default.Equals(ca.AttributeType, module.ImportReference(cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "XamlResourceIdAttribute"))))
continue;
if (!TypeRefComparer.Default.Equals(ca.ConstructorArguments[2].Value as TypeReference, type))
continue;
@ -306,11 +307,11 @@ namespace Microsoft.Maui.Controls.Build.Tasks
return null;
}
internal static string GetResourceIdForPath(ModuleDefinition module, string path)
internal static string GetResourceIdForPath(XamlCache cache, ModuleDefinition module, string path)
{
foreach (var ca in module.GetCustomAttributes())
{
if (!TypeRefComparer.Default.Equals(ca.AttributeType, module.ImportReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "XamlResourceIdAttribute"))))
if (!TypeRefComparer.Default.Equals(ca.AttributeType, module.ImportReference(cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "XamlResourceIdAttribute"))))
continue;
if (ca.ConstructorArguments[1].Value as string != path)
continue;

Просмотреть файл

@ -0,0 +1,76 @@
using System;
using System.Collections.Generic;
using Microsoft.Maui.Controls.XamlC;
using Mono.Cecil;
using Mono.Cecil.Cil;
namespace Microsoft.Maui.Controls.Build.Tasks;
/// <summary>
/// Class for caching various Mono.Cecil objects
/// </summary>
class XamlCache
{
readonly Dictionary<ModuleDefinition, IList<XmlnsDefinitionAttribute>> _xmlnsDefinitions = new();
readonly Dictionary<TypeReference, TypeDefinition> _resolvedTypes = new();
readonly Dictionary<(ModuleDefinition module, string fieldRefKey), FieldReference> _fieldReferenceCache = new();
readonly Dictionary<(ModuleDefinition module, string typeKey), TypeReference> _typeReferenceCache = new();
readonly Dictionary<(ModuleDefinition module, string methodRefKey), MethodReference> _methodReferenceCache = new();
readonly Dictionary<(ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName)), TypeDefinition> _typeDefinitionCache = new();
readonly Dictionary<VariableDefinition, ICollection<string>> _resourceNamesInUse = new();
Dictionary<TypeReference, Type> _knownCompiledTypeConverters;
static TValue GetOrAdd<TKey, TValue>(Dictionary<TKey, TValue> dictionary, TKey key, Func<TKey, TValue> valueFactory)
{
if (!dictionary.TryGetValue(key, out TValue value))
{
value = dictionary[key] = valueFactory(key);
}
return value;
}
public IList<XmlnsDefinitionAttribute> GetXmlsDefinitions(ModuleDefinition module, Func<ModuleDefinition, IList<XmlnsDefinitionAttribute>> valueFactory) =>
GetOrAdd(_xmlnsDefinitions, module, valueFactory);
public TypeDefinition Resolve(TypeReference typeReference) =>
GetOrAdd(_resolvedTypes, typeReference, t => t.Resolve());
public FieldReference GetOrAddFieldReference((ModuleDefinition module, string fieldRefKey) key, Func<(ModuleDefinition module, string fieldRefKey), FieldReference> valueFactory) =>
GetOrAdd(_fieldReferenceCache, key, valueFactory);
public TypeReference GetOrAddTypeReference(ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName) type) =>
GetOrAdd(_typeReferenceCache, (module, type.ToString()), x => x.module.ImportReference(x.module.GetTypeDefinition(this, type)));
public TypeReference GetOrAddTypeReference(ModuleDefinition module, string typeKey, Func<(ModuleDefinition module, string typeKey), TypeReference> valueFactory) =>
GetOrAdd(_typeReferenceCache, (module, typeKey), valueFactory);
public MethodReference GetOrAddMethodReference(ModuleDefinition module, string methodRefKey, Func<(ModuleDefinition module, string methodRefKey), MethodReference> valueFactory) =>
GetOrAdd(_methodReferenceCache, (module, methodRefKey), valueFactory);
public TypeDefinition GetOrAddTypeDefinition(ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName) type, Func<(ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName)), TypeDefinition> valueFactory) =>
GetOrAdd(_typeDefinitionCache, (module, type), valueFactory);
public ICollection<string> GetResourceNamesInUse(VariableDefinition variableDefinition) =>
GetOrAdd(_resourceNamesInUse, variableDefinition, _ => new HashSet<string>(StringComparer.Ordinal));
public Dictionary<TypeReference, Type> GetKnownCompiledTypeConverters(ModuleDefinition module) => _knownCompiledTypeConverters ??= new(TypeRefComparer.Default)
{
{ module.ImportReference(this, ("Microsoft.Maui", "Microsoft.Maui.Converters", "ThicknessTypeConverter")), typeof(ThicknessTypeConverter) },
{ module.ImportReference(this, ("Microsoft.Maui", "Microsoft.Maui.Converters", "CornerRadiusTypeConverter")), typeof(CornerRadiusTypeConverter) },
{ module.ImportReference(this, ("Microsoft.Maui", "Microsoft.Maui.Converters", "EasingTypeConverter")), typeof(EasingTypeConverter) },
{ module.ImportReference(this, ("Microsoft.Maui.Graphics", "Microsoft.Maui.Graphics.Converters", "ColorTypeConverter")), typeof(ColorTypeConverter) },
{ module.ImportReference(this, ("Microsoft.Maui.Graphics", "Microsoft.Maui.Graphics.Converters", "PointTypeConverter")), typeof(PointTypeConverter) },
{ module.ImportReference(this, ("Microsoft.Maui.Graphics", "Microsoft.Maui.Graphics.Converters", "RectTypeConverter")), typeof(RectangleTypeConverter) },
{ module.ImportReference(this, ("Microsoft.Maui", "Microsoft.Maui.Converters", "FlexJustifyTypeConverter")), typeof(EnumTypeConverter<Layouts.FlexJustify>) },
{ module.ImportReference(this, ("Microsoft.Maui", "Microsoft.Maui.Converters", "FlexDirectionTypeConverter")), typeof(EnumTypeConverter<Layouts.FlexDirection>) },
{ module.ImportReference(this, ("Microsoft.Maui", "Microsoft.Maui.Converters", "FlexAlignContentTypeConverter")), typeof(EnumTypeConverter<Layouts.FlexAlignContent>) },
{ module.ImportReference(this, ("Microsoft.Maui", "Microsoft.Maui.Converters", "FlexAlignItemsTypeConverter")), typeof(EnumTypeConverter<Layouts.FlexAlignItems>) },
{ module.ImportReference(this, ("Microsoft.Maui", "Microsoft.Maui.Converters", "FlexAlignSelfTypeConverter")), typeof(EnumTypeConverter<Layouts.FlexAlignSelf>) },
{ module.ImportReference(this, ("Microsoft.Maui", "Microsoft.Maui.Converters", "FlexWrapTypeConverter")), typeof(EnumTypeConverter<Layouts.FlexWrap>) },
{ module.ImportReference(this, ("Microsoft.Maui", "Microsoft.Maui.Converters", "FlexBasisTypeConverter")), typeof(FlexBasisTypeConverter) },
};
// State used by SetPropertiesVisitor
public int DataTemplateCount { get; set; }
public int TypedBindingCount { get; set; }
}

Просмотреть файл

@ -14,7 +14,6 @@ using Mono.Cecil.Pdb;
namespace Microsoft.Maui.Controls.Build.Tasks
{
[LoadInSeparateAppDomain]
public abstract class XamlTask : MarshalByRefObject, ITask
{
[Required]
@ -68,7 +67,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
static class CecilExtensions
{
public static bool IsXaml(this EmbeddedResource resource, ModuleDefinition module, out string classname)
public static bool IsXaml(this EmbeddedResource resource, XamlCache cache, ModuleDefinition module, out string classname)
{
classname = null;
if (!resource.Name.EndsWith(".xaml", StringComparison.InvariantCulture))
@ -91,7 +90,7 @@ namespace Microsoft.Maui.Controls.Build.Tasks
//no x:Class, but it might be a RD without x:Class and with <?xaml-comp compile="true" ?>
//in that case, it has a XamlResourceIdAttribute
var typeRef = GetTypeForResourceId(module, resource.Name);
var typeRef = GetTypeForResourceId(cache, module, resource.Name);
if (typeRef != null)
{
classname = typeRef.FullName;
@ -102,11 +101,11 @@ namespace Microsoft.Maui.Controls.Build.Tasks
}
}
static TypeReference GetTypeForResourceId(ModuleDefinition module, string resourceId)
static TypeReference GetTypeForResourceId(XamlCache cache, ModuleDefinition module, string resourceId)
{
foreach (var ca in module.GetCustomAttributes())
{
if (!TypeRefComparer.Default.Equals(ca.AttributeType, module.ImportReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "XamlResourceIdAttribute"))))
if (!TypeRefComparer.Default.Equals(ca.AttributeType, module.ImportReference(cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "XamlResourceIdAttribute"))))
continue;
if (ca.ConstructorArguments[0].Value as string != resourceId)
continue;

Просмотреть файл

@ -10,10 +10,6 @@ namespace Microsoft.Maui.Controls.Build.Tasks
{
static class XmlTypeExtensions
{
static Dictionary<ModuleDefinition, IList<XmlnsDefinitionAttribute>> s_xmlnsDefinitions =
new Dictionary<ModuleDefinition, IList<XmlnsDefinitionAttribute>>();
static object _nsLock = new object();
static IList<XmlnsDefinitionAttribute> GatherXmlnsDefinitionAttributes(ModuleDefinition module)
{
var xmlnsDefinitions = new List<XmlnsDefinitionAttribute>();
@ -51,11 +47,10 @@ namespace Microsoft.Maui.Controls.Build.Tasks
}
}
s_xmlnsDefinitions[module] = xmlnsDefinitions;
return xmlnsDefinitions;
}
public static TypeReference GetTypeReference(string xmlType, ModuleDefinition module, BaseNode node)
public static TypeReference GetTypeReference(XamlCache cache, string xmlType, ModuleDefinition module, BaseNode node)
{
var split = xmlType.Split(':');
if (split.Length > 2)
@ -73,40 +68,35 @@ namespace Microsoft.Maui.Controls.Build.Tasks
name = split[0];
}
var namespaceuri = node.NamespaceResolver.LookupNamespace(prefix) ?? "";
return GetTypeReference(new XmlType(namespaceuri, name, null), module, node as IXmlLineInfo);
return GetTypeReference(new XmlType(namespaceuri, name, null), cache, module, node as IXmlLineInfo);
}
public static TypeReference GetTypeReference(string namespaceURI, string typename, ModuleDefinition module, IXmlLineInfo xmlInfo)
public static TypeReference GetTypeReference(XamlCache cache, string namespaceURI, string typename, ModuleDefinition module, IXmlLineInfo xmlInfo)
{
return new XmlType(namespaceURI, typename, null).GetTypeReference(module, xmlInfo);
return new XmlType(namespaceURI, typename, null).GetTypeReference(cache, module, xmlInfo);
}
public static bool TryGetTypeReference(this XmlType xmlType, ModuleDefinition module, IXmlLineInfo xmlInfo, out TypeReference typeReference)
public static bool TryGetTypeReference(this XmlType xmlType, XamlCache cache, ModuleDefinition module, IXmlLineInfo xmlInfo, out TypeReference typeReference)
{
IList<XmlnsDefinitionAttribute> xmlnsDefinitions = null;
lock (_nsLock)
{
if (!s_xmlnsDefinitions.TryGetValue(module, out xmlnsDefinitions))
xmlnsDefinitions = GatherXmlnsDefinitionAttributes(module);
}
IList<XmlnsDefinitionAttribute> xmlnsDefinitions = cache.GetXmlsDefinitions(module, GatherXmlnsDefinitionAttributes);
var typeArguments = xmlType.TypeArguments;
TypeReference type = xmlType.GetTypeReference(xmlnsDefinitions, module.Assembly.Name.Name, (typeInfo) =>
{
string typeName = typeInfo.typeName.Replace('+', '/'); //Nested types
return module.GetTypeDefinition((typeInfo.assemblyName, typeInfo.clrNamespace, typeName));
return module.GetTypeDefinition(cache, (typeInfo.assemblyName, typeInfo.clrNamespace, typeName));
});
if (type != null && typeArguments != null && type.HasGenericParameters)
type = module.ImportReference(type).MakeGenericInstanceType(typeArguments.Select(x => GetTypeReference(x, module, xmlInfo)).ToArray());
type = module.ImportReference(type).MakeGenericInstanceType(typeArguments.Select(x => x.GetTypeReference(cache, module, xmlInfo)).ToArray());
return (typeReference = (type == null) ? null : module.ImportReference(type)) != null;
}
public static TypeReference GetTypeReference(this XmlType xmlType, ModuleDefinition module, IXmlLineInfo xmlInfo)
public static TypeReference GetTypeReference(this XmlType xmlType, XamlCache cache, ModuleDefinition module, IXmlLineInfo xmlInfo)
{
if (TryGetTypeReference(xmlType, module, xmlInfo, out TypeReference typeReference))
if (TryGetTypeReference(xmlType, cache, module, xmlInfo, out TypeReference typeReference))
return typeReference;
throw new BuildException(BuildExceptionCode.TypeResolution, xmlInfo, null, $"{xmlType.NamespaceUri}:{xmlType.Name}");

Просмотреть файл

@ -6,6 +6,8 @@ namespace Microsoft.Maui.Controls.Design
public EasingDesignTypeConverter()
{ }
protected override bool ExclusiveToKnownValues => true;
protected override string[] KnownValues
=> new string[]
{

Просмотреть файл

@ -11,6 +11,8 @@ namespace Microsoft.Maui.Controls.Design
{
}
protected override bool ExclusiveToKnownValues => true;
protected override string[] KnownValues
=> new[]
{

Просмотреть файл

@ -6,6 +6,8 @@
{
}
protected override bool ExclusiveToKnownValues => true;
protected override string[] KnownValues
=> new string[] { "Start", "Center", "End", "Fill", "StartAndExpand", "CenterAndExpand", "EndAndExpand", "FillAndExpand" };
}

Просмотреть файл

@ -28,7 +28,27 @@ namespace Microsoft.Maui.Controls.Handlers.Compatibility
[Frame.CornerRadiusProperty.PropertyName] = (h, _) => h.UpdateCornerRadius(),
[Frame.BorderColorProperty.PropertyName] = (h, _) => h.UpdateBorderColor(),
[Microsoft.Maui.Controls.Compatibility.Layout.IsClippedToBoundsProperty.PropertyName] = (h, _) => h.UpdateClippedToBounds(),
[Frame.ContentProperty.PropertyName] = (h, _) => h.UpdateContent()
[Frame.ContentProperty.PropertyName] = (h, _) => h.UpdateContent(),
// TODO NET8. These are all needed because the AndroidBatchMapper doesn't run via the mapper it's a manual call on ViewHandler
// With NET8 we can move the BatchMapper call to the actual ViewHandler.Mapper.
// Because we most likely want to backport these fixes to NET7, I've just opted to add these manually for now on Frame
[nameof(IView.AutomationId)] = (h, v) => ViewHandler.MapAutomationId(h, v),
[nameof(IView.IsEnabled)] = (h, v) => ViewRenderer.VisualElementRendererMapper.UpdateProperty(h, v, nameof(IView.IsEnabled)),
[nameof(IView.Visibility)] = (h, v) => ViewRenderer.VisualElementRendererMapper.UpdateProperty(h, v, nameof(IView.Visibility)),
[nameof(IView.MinimumHeight)] = (h, v) => ViewRenderer.VisualElementRendererMapper.UpdateProperty(h, v, nameof(IView.MinimumHeight)),
[nameof(IView.MinimumWidth)] = (h, v) => ViewRenderer.VisualElementRendererMapper.UpdateProperty(h, v, nameof(IView.MinimumWidth)),
[nameof(IView.Opacity)] = (h, v) => ViewRenderer.VisualElementRendererMapper.UpdateProperty(h, v, nameof(IView.Opacity)),
[nameof(IView.TranslationX)] = (h, v) => ViewRenderer.VisualElementRendererMapper.UpdateProperty(h, v, nameof(IView.TranslationX)),
[nameof(IView.TranslationY)] = (h, v) => ViewRenderer.VisualElementRendererMapper.UpdateProperty(h, v, nameof(IView.TranslationY)),
[nameof(IView.Scale)] = (h, v) => ViewRenderer.VisualElementRendererMapper.UpdateProperty(h, v, nameof(IView.Scale)),
[nameof(IView.ScaleX)] = (h, v) => ViewRenderer.VisualElementRendererMapper.UpdateProperty(h, v, nameof(IView.ScaleX)),
[nameof(IView.ScaleY)] = (h, v) => ViewRenderer.VisualElementRendererMapper.UpdateProperty(h, v, nameof(IView.ScaleY)),
[nameof(IView.Rotation)] = (h, v) => ViewRenderer.VisualElementRendererMapper.UpdateProperty(h, v, nameof(IView.Rotation)),
[nameof(IView.RotationX)] = (h, v) => ViewRenderer.VisualElementRendererMapper.UpdateProperty(h, v, nameof(IView.RotationX)),
[nameof(IView.RotationY)] = (h, v) => ViewRenderer.VisualElementRendererMapper.UpdateProperty(h, v, nameof(IView.RotationY)),
[nameof(IView.AnchorX)] = (h, v) => ViewRenderer.VisualElementRendererMapper.UpdateProperty(h, v, nameof(IView.AnchorX)),
[nameof(IView.AnchorY)] = (h, v) => ViewRenderer.VisualElementRendererMapper.UpdateProperty(h, v, nameof(IView.AnchorY)),
};
public static CommandMapper<Frame, FrameRenderer> CommandMapper
@ -50,9 +70,18 @@ namespace Microsoft.Maui.Controls.Handlers.Compatibility
public event EventHandler<VisualElementChangedEventArgs>? ElementChanged;
public event EventHandler<PropertyChangedEventArgs>? ElementPropertyChanged;
public FrameRenderer(Context context) : base(context)
public FrameRenderer(Context context) : this(context, Mapper)
{
_viewHandlerWrapper = new ViewHandlerDelegator<Frame>(Mapper, CommandMapper, this);
}
public FrameRenderer(Context context, IPropertyMapper mapper)
: this(context, mapper, CommandMapper)
{
}
public FrameRenderer(Context context, IPropertyMapper mapper, CommandMapper commandMapper) : base(context)
{
_viewHandlerWrapper = new ViewHandlerDelegator<Frame>(mapper, commandMapper, this);
}
protected CardView Control => this;
@ -71,8 +100,16 @@ namespace Microsoft.Maui.Controls.Handlers.Compatibility
Size IViewHandler.GetDesiredSize(double widthMeasureSpec, double heightMeasureSpec)
{
double minWidth = 20;
if (Primitives.Dimension.IsExplicitSet(widthMeasureSpec) && !double.IsInfinity(widthMeasureSpec))
minWidth = widthMeasureSpec;
double minHeight = 20;
if (Primitives.Dimension.IsExplicitSet(widthMeasureSpec) && !double.IsInfinity(heightMeasureSpec))
minHeight = heightMeasureSpec;
return VisualElementRenderer<Frame>.GetDesiredSize(this, widthMeasureSpec, heightMeasureSpec,
new Size(20, 20));
new Size(minWidth, minHeight));
}
protected override void Dispose(bool disposing)

Просмотреть файл

@ -13,12 +13,33 @@ namespace Microsoft.Maui.Controls.Handlers.Compatibility
public class FrameRenderer : ViewRenderer<Frame, WBorder>
{
public static IPropertyMapper<Frame, FrameRenderer> Mapper
= new PropertyMapper<Frame, FrameRenderer>(VisualElementRendererMapper);
= new PropertyMapper<Frame, FrameRenderer>(VisualElementRendererMapper)
{
// https://github.com/dotnet/maui/issues/11880
// Dimension constraints need to be propagated to the container
// in order for the `PlatformMeasure` calls to return the correct
// get desired size
[nameof(IView.Width)] = MapWidth,
[nameof(IView.Height)] = MapHeight,
[nameof(IView.MinimumHeight)] = MapMinimumHeight,
[nameof(IView.MaximumHeight)] = MapMaximumHeight,
[nameof(IView.MinimumWidth)] = MapMinimumWidth,
[nameof(IView.MaximumWidth)] = MapMaximumWidth,
};
public static CommandMapper<Frame, FrameRenderer> CommandMapper
= new CommandMapper<Frame, FrameRenderer>(VisualElementRendererCommandMapper);
public FrameRenderer() : base(Mapper, CommandMapper)
public FrameRenderer() : this(Mapper, CommandMapper)
{
}
public FrameRenderer(IPropertyMapper mapper)
: this(mapper, CommandMapper)
{
}
public FrameRenderer(IPropertyMapper mapper, CommandMapper commandMapper) : base(mapper, commandMapper)
{
AutoPackage = false;
}
@ -68,21 +89,26 @@ namespace Microsoft.Maui.Controls.Handlers.Compatibility
protected override global::Windows.Foundation.Size ArrangeOverride(global::Windows.Foundation.Size finalSize)
{
Control.Arrange(new WRect(0, 0, finalSize.Width, finalSize.Height));
if (Element is IContentView cv)
cv.CrossPlatformArrange(new Rect(0, 0, finalSize.Width, finalSize.Height));
// We need this so the `Border` control will arrange and have a size
Control?.Arrange(new WRect(0, 0, finalSize.Width, finalSize.Height));
return finalSize;
if (Element is IContentView cv)
{
finalSize = cv.CrossPlatformArrange(new Rect(0, 0, finalSize.Width, finalSize.Height)).ToPlatform();
}
return new global::Windows.Foundation.Size(Math.Max(0, finalSize.Width), Math.Max(0, finalSize.Height));
}
protected override global::Windows.Foundation.Size MeasureOverride(global::Windows.Foundation.Size availableSize)
{
var size = base.MeasureOverride(availableSize);
if (Element is IContentView cv)
size = cv.CrossPlatformMeasure(availableSize.Width, availableSize.Height).ToPlatform();
{
var measureContent = cv.CrossPlatformMeasure(availableSize.Width, availableSize.Height).ToPlatform();
return measureContent;
}
return size;
return MinimumSize().ToPlatform();
}
protected override void UpdateBackgroundColor()
@ -135,5 +161,45 @@ namespace Microsoft.Maui.Controls.Handlers.Compatibility
Control.CornerRadius = WinUIHelpers.CreateCornerRadius(cornerRadius);
}
// https://github.com/dotnet/maui/issues/11880
// Dimension constraints need to be propagated to the container
// in order for the `PlatformMeasure` calls to return the correct
// get desired size
static void MapWidth(IViewHandler handler, IView view)
{
VisualElementRendererMapper.UpdateProperty(handler, view, nameof(IView.Width));
handler.ToPlatform().UpdateWidth(view);
}
static void MapHeight(IViewHandler handler, IView view)
{
VisualElementRendererMapper.UpdateProperty(handler, view, nameof(IView.Height));
handler.ToPlatform().UpdateHeight(view);
}
static void MapMinimumHeight(IViewHandler handler, IView view)
{
VisualElementRendererMapper.UpdateProperty(handler, view, nameof(IView.MinimumHeight));
handler.ToPlatform().UpdateMinimumHeight(view);
}
static void MapMaximumHeight(IViewHandler handler, IView view)
{
VisualElementRendererMapper.UpdateProperty(handler, view, nameof(IView.MaximumHeight));
handler.ToPlatform().UpdateMaximumHeight(view);
}
static void MapMinimumWidth(IViewHandler handler, IView view)
{
VisualElementRendererMapper.UpdateProperty(handler, view, nameof(IView.MinimumWidth));
handler.ToPlatform().UpdateMinimumWidth(view);
}
static void MapMaximumWidth(IViewHandler handler, IView view)
{
VisualElementRendererMapper.UpdateProperty(handler, view, nameof(IView.MaximumWidth));
handler.ToPlatform().UpdateMaximumWidth(view);
}
}
}

Просмотреть файл

@ -24,6 +24,16 @@ namespace Microsoft.Maui.Controls.Handlers.Compatibility
AddSubview(_actualView);
}
public FrameRenderer(IPropertyMapper mapper)
: this(mapper, CommandMapper)
{
}
public FrameRenderer(IPropertyMapper mapper, CommandMapper commandMapper) : base(mapper, commandMapper)
{
AutoPackage = false;
}
public override void AddSubview(UIView view)
{
if (view != _actualView)

Просмотреть файл

@ -21,12 +21,15 @@ namespace Microsoft.Maui.Controls.Shapes
public override PathF GetPath()
{
var width = WidthForPathComputation;
var height = HeightForPathComputation;
var path = new PathF();
float x = (float)StrokeThickness / 2;
float y = (float)StrokeThickness / 2;
float w = (float)(Width - StrokeThickness);
float h = (float)(Height - StrokeThickness);
float w = (float)(width - StrokeThickness);
float h = (float)(height - StrokeThickness);
path.AppendEllipse(x, y, w, h);

Просмотреть файл

@ -18,12 +18,15 @@ namespace Microsoft.Maui.Controls.Shapes
public override PathF GetPath()
{
var width = WidthForPathComputation;
var height = HeightForPathComputation;
var path = new PathF();
float x = (float)StrokeThickness / 2;
float y = (float)StrokeThickness / 2;
float w = (float)(Width - StrokeThickness);
float h = (float)(Height - StrokeThickness);
float w = (float)(width - StrokeThickness);
float h = (float)(height - StrokeThickness);
float cornerRadius = (float)Math.Max(RadiusX, RadiusY);
// TODO: Create specific Path taking into account RadiusX and RadiusY

Просмотреть файл

@ -15,13 +15,16 @@ namespace Microsoft.Maui.Controls.Shapes
public override PathF GetPath()
{
var width = WidthForPathComputation;
var height = HeightForPathComputation;
var path = new PathF();
float x = (float)StrokeThickness / 2;
float y = (float)StrokeThickness / 2;
float w = (float)(Width - StrokeThickness);
float h = (float)(Height - StrokeThickness);
float w = (float)(width - StrokeThickness);
float h = (float)(height - StrokeThickness);
float topLeftCornerRadius = (float)CornerRadius.TopLeft;
float topRightCornerRadius = (float)CornerRadius.TopRight;

Просмотреть файл

@ -34,7 +34,7 @@ namespace Microsoft.Maui.Controls.Handlers.Items
protected TItemsView ItemsView => VirtualView;
protected ItemsViewController<TItemsView> Controller { get; private set; }
protected internal ItemsViewController<TItemsView> Controller { get; private set; }
protected abstract ItemsViewLayout SelectLayout();

Просмотреть файл

@ -20,18 +20,16 @@ namespace Microsoft.Maui.Controls.Handlers.Items
protected override (bool, Size) NeedsContentSizeUpdate(Size currentSize)
{
var size = Size.Zero;
if (PlatformHandler?.VirtualView == null)
{
return (false, size);
return (false, currentSize);
}
var bounds = PlatformHandler.VirtualView.Frame;
if (bounds.Width <= 0 || bounds.Height <= 0)
{
return (false, size);
return (false, currentSize);
}
var desiredBounds = PlatformHandler.VirtualView.Measure(double.PositiveInfinity, bounds.Height);
@ -39,9 +37,12 @@ namespace Microsoft.Maui.Controls.Handlers.Items
if (desiredBounds.Width == currentSize.Width)
{
// Nothing in the cell needs more room, so leave it as it is
return (false, size);
return (false, currentSize);
}
// Keep the current height in the updated content size
desiredBounds.Height = bounds.Height;
return (true, desiredBounds);
}
}

Просмотреть файл

@ -16,7 +16,14 @@ namespace Microsoft.Maui.Controls.Handlers.Items
public IItemsViewSource ItemsSource { get; protected set; }
public TItemsView ItemsView { get; }
// ItemsViewLayout provides an accessor to the typed UICollectionViewLayout. It's also important to note that the
// initial UICollectionViewLayout which is passed in to the ItemsViewController (and accessed via the Layout property)
// _does not_ get updated when the layout is updated for the CollectionView. That property only refers to the
// original layout. So it's unlikely that you would ever want to use .Layout; use .ItemsViewLayout instead.
// See https://developer.apple.com/documentation/uikit/uicollectionviewcontroller/1623980-collectionviewlayout
protected ItemsViewLayout ItemsViewLayout { get; set; }
bool _initialized;
bool _isEmpty = true;
bool _emptyViewDisplayed;
@ -303,7 +310,7 @@ namespace Microsoft.Maui.Controls.Handlers.Items
{
if (cell == visibleCells[n])
{
Layout?.InvalidateLayout();
ItemsViewLayout?.InvalidateLayout();
return;
}
}

Просмотреть файл

@ -7,10 +7,11 @@ namespace Microsoft.Maui.Controls.Handlers.Items
{
class ListSource : IItemsViewSource, IList
{
IList _itemsSource;
readonly IList _itemsSource;
public ListSource()
{
_itemsSource = new List<object>();
}
public ListSource(IList list)

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше