From ebea3df8fc31f81e4c12dacb290c5f5a3db51d70 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Sat, 8 Feb 2020 17:12:09 -0800 Subject: [PATCH] Rename and refactor for XamlX structure and layering. --- XamlX.sln | 59 +-- src/Benchmarks/BenchCompiler.cs | 19 +- src/Benchmarks/Benchmarks.csproj | 2 +- ...tion.cs => BenchmarksXamlConfiguration.cs} | 10 +- src/Benchmarks/LoadBenchmark.cs | 10 +- src/Benchmarks/LoadComplexBenchmark.xml | 2 +- src/Benchmarks/LoadSimpleBenchmark.xml | 2 +- src/Benchmarks/Program.cs | 6 +- .../BenchmarksCompiler.csproj | 6 +- src/BenchmarksCompiler/Program.cs | 28 +- .../CecilAssembly.cs | 10 +- .../CecilCustomAttribute.cs | 8 +- .../CecilEmitter.cs | 47 +- .../CecilEvent.cs | 8 +- .../CecilField.cs | 8 +- .../CecilHelpers.cs | 3 - .../CecilMethod.cs | 27 +- .../CecilProperty.cs | 24 +- .../CecilType.cs | 68 +-- .../CecilTypeBuilder.cs | 23 +- .../CecilTypeCache.cs | 0 .../CecilTypeSystem.cs | 35 +- .../CustomMetadataResolver.cs | 0 .../UnresolvedCecilType.cs | 2 +- .../XamlX.IL.Cecil.csproj} | 2 +- src/XamlX.Runtime/Interfaces.cs | 10 +- src/XamlX.Runtime/XamlX.Runtime.csproj | 2 +- src/XamlX/Ast/Clr.cs | 404 ++++++++++-------- src/XamlX/Ast/Common.cs | 80 ++-- src/XamlX/Ast/CompilerHelpers.cs | 137 +++--- src/XamlX/Ast/Intrinsics.cs | 156 +++---- src/XamlX/Ast/Xaml.cs | 76 ++-- .../Ast/{XamlXDocument.cs => XamlDocument.cs} | 6 +- src/XamlX/Ast/Xml.cs | 16 +- src/XamlX/Compiler/XamlCompiler.cs | 81 ++++ src/XamlX/Compiler/XamlImperativeCompiler.cs | 110 +++++ src/XamlX/Emit/XamlEmitContext.cs | 285 ++++++++++++ src/XamlX/Emit/XamlEmitContextWithLocals.cs | 166 +++++++ src/XamlX/Emit/XamlLanguageEmitMappings.cs | 28 ++ src/XamlX/Emit/XamlRuntimeContext.cs | 66 +++ src/XamlX/Exceptions.cs | 26 +- .../CheckingILEmitter.cs} | 69 ++- .../Emitters/ManipulationGroupEmitter.cs | 14 +- .../Emitters/MarkupExtensionEmitter.cs | 24 +- src/XamlX/IL/Emitters/MethodCallEmitter.cs | 43 ++ .../Emitters/NewObjectEmitter.cs | 17 +- .../ObjectInitializationNodeEmitter.cs | 42 +- .../Emitters/PropertyAssignmentEmitter.cs | 34 +- .../PropertyValueManipulationEmitter.cs | 24 ++ src/XamlX/IL/Emitters/TextNodeEmitter.cs | 24 ++ .../Emitters/ValueWithManipulationsEmitter.cs | 29 ++ src/XamlX/IL/ILEmitContext.cs | 102 +++++ src/XamlX/IL/ILEmitHelpers.cs | 135 ++++++ src/XamlX/IL/IXamlILEmitter.cs | 33 ++ .../NamespaceInfoProvider.cs} | 60 +-- .../{Transform => IL}/RecordingIlEmitter.cs | 56 +-- .../XamlXContext.cs => IL/RuntimeContext.cs} | 200 ++++----- src/XamlX/{TypeSystem => IL}/SreTypeSystem.cs | 229 +++++----- src/XamlX/IL/XamlILCompiler.cs | 177 ++++++++ src/XamlX/IL/XamlILEmitterExtensions.cs | 168 ++++++++ .../CommaSeparatedParenthesesTreeParser.cs | 2 +- .../MeScanner.Shims.cs | 20 +- .../MeScanner.cs | 30 +- .../SystemXamlMarkupExtensionParser.cs | 22 +- ...amlXParser.cs => XDocumentXamlIlParser.cs} | 72 ++-- .../Parsers/XamlMarkupExtensionParser.cs | 16 +- .../Transform/AstTransformationContext.cs | 84 ++++ .../Transform/Emitters/MethodCallEmitter.cs | 44 -- .../PropertyValueManipulationEmitter.cs | 22 - .../Transform/Emitters/TextNodeEmitter.cs | 22 - .../Emitters/ValueWithManipulationsEmitter.cs | 27 -- src/XamlX/Transform/IXamlAstTransformer.cs | 13 + src/XamlX/Transform/NamespaceInfoHelper.cs | 59 +++ ...uration.cs => TransformerConfiguration.cs} | 86 ++-- ...r.cs => ConstructableObjectTransformer.cs} | 43 +- .../Transformers/ContentConvertTransformer.cs | 39 ++ ...PropertyValuesToAssignmentsTransformer.cs} | 64 +-- .../DeferredContentTransformer.cs | 39 ++ .../Transformers/FlattenAstTransformer.cs | 17 + ...ormer.cs => KnownDirectivesTransformer.cs} | 16 +- .../MarkupExtensionTransformer.cs | 25 ++ .../Transformers/NewObjectTransformer.cs | 30 ++ ...solver.cs => PropertyReferenceResolver.cs} | 28 +- ...s => ResolveContentPropertyTransformer.cs} | 28 +- ... ResolvePropertyValueAddersTransformer.cs} | 28 +- ...cs => TopDownInitializationTransformer.cs} | 32 +- ...ceResolver.cs => TypeReferenceResolver.cs} | 50 +-- ...ransformer.cs => XArgumentsTransformer.cs} | 16 +- ...former.cs => XamlIntrinsicsTransformer.cs} | 34 +- .../XamlXContentConvertTransformer.cs | 39 -- .../XamlXDeferredContentTransformer.cs | 39 -- .../Transformers/XamlXFlattenTransformer.cs | 17 - .../XamlXMarkupExtensionTransformer.cs | 25 -- src/XamlX/Transform/XamlContextBase.cs | 49 +++ .../Transform/XamlLanguageTypeMappings.cs | 57 +++ ...formHelpers.cs => XamlTransformHelpers.cs} | 141 ++---- .../XamlXAstTransformationContext.cs | 126 ------ src/XamlX/Transform/XamlXCompiler.cs | 272 ------------ src/XamlX/Transform/XamlXEmitContext.cs | 191 --------- .../Transform/XamlXLanguageTypeMappings.cs | 73 ---- ...XXmlnsMappings.cs => XamlXmlnsMappings.cs} | 18 +- src/XamlX/TypeSystem/TypeSystem.cs | 335 ++++++--------- src/XamlX/TypeSystem/TypeSystemExtensions.cs | 143 ------- src/XamlX/TypeSystem/TypeSystemHelpers.cs | 135 +----- .../{XamlXLocalsPool.cs => XamlLocalsPool.cs} | 27 +- src/XamlX/XamlNamespaces.cs | 2 +- src/XamlX/XamlX.csproj | 2 +- .../CecilNetstandardTests.csproj | 4 +- tests/CecilNetstandardTests/packages.config | 9 - tests/CecilTests/CecilTests.csproj | 4 +- tests/CecilTests/CompilerTestBase.cs | 3 +- tests/TestClasses/Class1.cs | 2 +- tests/Tests.Common.props | 2 +- tests/XamlParserTests/CompilerTestBase.cs | 36 +- tests/XamlParserTests/DebugHatch.cs | 2 +- tests/XamlParserTests/Helpers.cs | 2 +- tests/XamlParserTests/InitializationTests.cs | 1 - tests/XamlParserTests/IntrinsicsTests.cs | 2 +- tests/XamlParserTests/MarkupExtensionTests.cs | 4 +- tests/XamlParserTests/ParserTests.cs | 124 +++--- tests/XamlParserTests/ServiceProviderTests.cs | 24 +- tests/XamlParserTests/XamlParserTests.csproj | 4 +- 122 files changed, 3537 insertions(+), 2923 deletions(-) rename src/Benchmarks/{BenchmarksXamlXConfiguration.cs => BenchmarksXamlConfiguration.cs} (70%) rename src/{XamlX.Cecil => XamlX.IL.Cecil}/CecilAssembly.cs (83%) rename src/{XamlX.Cecil => XamlX.IL.Cecil}/CecilCustomAttribute.cs (79%) rename src/{XamlX.Cecil => XamlX.IL.Cecil}/CecilEmitter.cs (88%) rename src/{XamlX.Cecil => XamlX.IL.Cecil}/CecilEvent.cs (75%) rename src/{XamlX.Cecil => XamlX.IL.Cecil}/CecilField.cs (75%) rename src/{XamlX.Cecil => XamlX.IL.Cecil}/CecilHelpers.cs (98%) rename src/{XamlX.Cecil => XamlX.IL.Cecil}/CecilMethod.cs (84%) rename src/{XamlX.Cecil => XamlX.IL.Cecil}/CecilProperty.cs (65%) rename src/{XamlX.Cecil => XamlX.IL.Cecil}/CecilType.cs (72%) rename src/{XamlX.Cecil => XamlX.IL.Cecil}/CecilTypeBuilder.cs (82%) rename src/{XamlX.Cecil => XamlX.IL.Cecil}/CecilTypeCache.cs (100%) rename src/{XamlX.Cecil => XamlX.IL.Cecil}/CecilTypeSystem.cs (80%) rename src/{XamlX.Cecil => XamlX.IL.Cecil}/CustomMetadataResolver.cs (100%) rename src/{XamlX.Cecil => XamlX.IL.Cecil}/UnresolvedCecilType.cs (83%) rename src/{XamlX.Cecil/XamlX.Cecil.csproj => XamlX.IL.Cecil/XamlX.IL.Cecil.csproj} (89%) rename src/XamlX/Ast/{XamlXDocument.cs => XamlDocument.cs} (68%) create mode 100644 src/XamlX/Compiler/XamlCompiler.cs create mode 100644 src/XamlX/Compiler/XamlImperativeCompiler.cs create mode 100644 src/XamlX/Emit/XamlEmitContext.cs create mode 100644 src/XamlX/Emit/XamlEmitContextWithLocals.cs create mode 100644 src/XamlX/Emit/XamlLanguageEmitMappings.cs create mode 100644 src/XamlX/Emit/XamlRuntimeContext.cs rename src/XamlX/{Transform/CheckingIlEmitter.cs => IL/CheckingILEmitter.cs} (86%) rename src/XamlX/{Transform => IL}/Emitters/ManipulationGroupEmitter.cs (55%) rename src/XamlX/{Transform => IL}/Emitters/MarkupExtensionEmitter.cs (66%) create mode 100644 src/XamlX/IL/Emitters/MethodCallEmitter.cs rename src/XamlX/{Transform => IL}/Emitters/NewObjectEmitter.cs (50%) rename src/XamlX/{Transform => IL}/Emitters/ObjectInitializationNodeEmitter.cs (66%) rename src/XamlX/{Transform => IL}/Emitters/PropertyAssignmentEmitter.cs (79%) create mode 100644 src/XamlX/IL/Emitters/PropertyValueManipulationEmitter.cs create mode 100644 src/XamlX/IL/Emitters/TextNodeEmitter.cs create mode 100644 src/XamlX/IL/Emitters/ValueWithManipulationsEmitter.cs create mode 100644 src/XamlX/IL/ILEmitContext.cs create mode 100644 src/XamlX/IL/ILEmitHelpers.cs create mode 100644 src/XamlX/IL/IXamlILEmitter.cs rename src/XamlX/{Transform/XamlXNamespaceInfoHelper.cs => IL/NamespaceInfoProvider.cs} (67%) rename src/XamlX/{Transform => IL}/RecordingIlEmitter.cs (71%) rename src/XamlX/{Transform/XamlXContext.cs => IL/RuntimeContext.cs} (81%) rename src/XamlX/{TypeSystem => IL}/SreTypeSystem.cs (70%) create mode 100644 src/XamlX/IL/XamlILCompiler.cs create mode 100644 src/XamlX/IL/XamlILEmitterExtensions.cs rename src/XamlX/Parsers/{XDocumentXamlXParser.cs => XDocumentXamlIlParser.cs} (74%) create mode 100644 src/XamlX/Transform/AstTransformationContext.cs delete mode 100644 src/XamlX/Transform/Emitters/MethodCallEmitter.cs delete mode 100644 src/XamlX/Transform/Emitters/PropertyValueManipulationEmitter.cs delete mode 100644 src/XamlX/Transform/Emitters/TextNodeEmitter.cs delete mode 100644 src/XamlX/Transform/Emitters/ValueWithManipulationsEmitter.cs create mode 100644 src/XamlX/Transform/IXamlAstTransformer.cs create mode 100644 src/XamlX/Transform/NamespaceInfoHelper.cs rename src/XamlX/Transform/{XamlXTransformerConfiguration.cs => TransformerConfiguration.cs} (59%) rename src/XamlX/Transform/Transformers/{XamlXNewObjectTransformer.cs => ConstructableObjectTransformer.cs} (54%) create mode 100644 src/XamlX/Transform/Transformers/ContentConvertTransformer.cs rename src/XamlX/Transform/Transformers/{XamlXConvertPropertyValuesToAssignmentsTransformer.cs => ConvertPropertyValuesToAssignmentsTransformer.cs} (75%) create mode 100644 src/XamlX/Transform/Transformers/DeferredContentTransformer.cs create mode 100644 src/XamlX/Transform/Transformers/FlattenAstTransformer.cs rename src/XamlX/Transform/Transformers/{XamlXKnownDirectivesTransformer.cs => KnownDirectivesTransformer.cs} (57%) create mode 100644 src/XamlX/Transform/Transformers/MarkupExtensionTransformer.cs create mode 100644 src/XamlX/Transform/Transformers/NewObjectTransformer.cs rename src/XamlX/Transform/Transformers/{XamlXPropertyReferenceResolver.cs => PropertyReferenceResolver.cs} (73%) rename src/XamlX/Transform/Transformers/{XamlXResolveContentPropertyTransformer.cs => ResolveContentPropertyTransformer.cs} (61%) rename src/XamlX/Transform/Transformers/{XamlXResolvePropertyValueAddersTransformer.cs => ResolvePropertyValueAddersTransformer.cs} (59%) rename src/XamlX/Transform/Transformers/{XamlXTopDownInitializationTransformer.cs => TopDownInitializationTransformer.cs} (63%) rename src/XamlX/Transform/Transformers/{XamlXTypeReferenceResolver.cs => TypeReferenceResolver.cs} (70%) rename src/XamlX/Transform/Transformers/{XamlXXArgumentsTransformer.cs => XArgumentsTransformer.cs} (54%) rename src/XamlX/Transform/Transformers/{XamlXIntrinsicsTransformer.cs => XamlIntrinsicsTransformer.cs} (72%) delete mode 100644 src/XamlX/Transform/Transformers/XamlXContentConvertTransformer.cs delete mode 100644 src/XamlX/Transform/Transformers/XamlXDeferredContentTransformer.cs delete mode 100644 src/XamlX/Transform/Transformers/XamlXFlattenTransformer.cs delete mode 100644 src/XamlX/Transform/Transformers/XamlXMarkupExtensionTransformer.cs create mode 100644 src/XamlX/Transform/XamlContextBase.cs create mode 100644 src/XamlX/Transform/XamlLanguageTypeMappings.cs rename src/XamlX/Transform/{XamlXTransformHelpers.cs => XamlTransformHelpers.cs} (61%) delete mode 100644 src/XamlX/Transform/XamlXAstTransformationContext.cs delete mode 100644 src/XamlX/Transform/XamlXCompiler.cs delete mode 100644 src/XamlX/Transform/XamlXEmitContext.cs delete mode 100644 src/XamlX/Transform/XamlXLanguageTypeMappings.cs rename src/XamlX/Transform/{XamlXXmlnsMappings.cs => XamlXmlnsMappings.cs} (67%) delete mode 100644 src/XamlX/TypeSystem/TypeSystemExtensions.cs rename src/XamlX/TypeSystem/{XamlXLocalsPool.cs => XamlLocalsPool.cs} (55%) delete mode 100644 tests/CecilNetstandardTests/packages.config diff --git a/XamlX.sln b/XamlX.sln index 77725488..c84938ca 100644 --- a/XamlX.sln +++ b/XamlX.sln @@ -1,46 +1,39 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29411.108 +MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{4191DEF4-DBC9-4185-A1A6-11E80A7A9B34}" -ProjectSection(SolutionItems) = preProject - README.md = README.md -EndProjectSection + ProjectSection(SolutionItems) = preProject + README.md = README.md + EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XamlX", "src\XamlX\XamlX.csproj", "{3986513F-FAE6-4DA6-9221-51837AFC9B3C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "XamlX", "src\XamlX\XamlX.csproj", "{3986513F-FAE6-4DA6-9221-51837AFC9B3C}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{55203DEB-3DB3-4907-8275-7FBE48185148}" -ProjectSection(SolutionItems) = preProject - tests\Tests.Common.props = tests\Tests.Common.props -EndProjectSection + ProjectSection(SolutionItems) = preProject + tests\Tests.Common.props = tests\Tests.Common.props + EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XamlParserTests", "tests\XamlParserTests\XamlParserTests.csproj", "{6512A859-F453-4388-9DAA-9B0C3E62956E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "XamlParserTests", "tests\XamlParserTests\XamlParserTests.csproj", "{6512A859-F453-4388-9DAA-9B0C3E62956E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Benchmarks", "src\Benchmarks\Benchmarks.csproj", "{F1C1F27D-20E5-4097-8647-0BDD74CC11FB}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Benchmarks", "src\Benchmarks\Benchmarks.csproj", "{F1C1F27D-20E5-4097-8647-0BDD74CC11FB}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XamlX.Runtime", "src\XamlX.Runtime\XamlX.Runtime.csproj", "{E232146D-783D-4927-AB4D-26569AE50F78}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "XamlX.Runtime", "src\XamlX.Runtime\XamlX.Runtime.csproj", "{E232146D-783D-4927-AB4D-26569AE50F78}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XamlX.Cecil", "src\XamlX.Cecil\XamlX.Cecil.csproj", "{655CC2E8-C076-4DE8-8671-B7C7792DF7A3}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "XamlX.IL.Cecil", "src\XamlX.IL.Cecil\XamlX.IL.Cecil.csproj", "{655CC2E8-C076-4DE8-8671-B7C7792DF7A3}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CecilTests", "tests\CecilTests\CecilTests.csproj", "{20135939-0E5C-4906-9097-67F13945D042}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CecilTests", "tests\CecilTests\CecilTests.csproj", "{20135939-0E5C-4906-9097-67F13945D042}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CecilNetstandardTests", "tests\CecilNetstandardTests\CecilNetstandardTests.csproj", "{E7E2584A-1406-4B7A-9ADA-430C1FC9AEAE}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CecilNetstandardTests", "tests\CecilNetstandardTests\CecilNetstandardTests.csproj", "{E7E2584A-1406-4B7A-9ADA-430C1FC9AEAE}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BenchmarksCompiler", "src\BenchmarksCompiler\BenchmarksCompiler.csproj", "{0DC5F69A-C150-4590-90D7-303B9654011C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BenchmarksCompiler", "src\BenchmarksCompiler\BenchmarksCompiler.csproj", "{0DC5F69A-C150-4590-90D7-303B9654011C}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {3986513F-FAE6-4DA6-9221-51837AFC9B3C} = {4191DEF4-DBC9-4185-A1A6-11E80A7A9B34} - {6512A859-F453-4388-9DAA-9B0C3E62956E} = {55203DEB-3DB3-4907-8275-7FBE48185148} - {F1C1F27D-20E5-4097-8647-0BDD74CC11FB} = {4191DEF4-DBC9-4185-A1A6-11E80A7A9B34} - {E232146D-783D-4927-AB4D-26569AE50F78} = {4191DEF4-DBC9-4185-A1A6-11E80A7A9B34} - {655CC2E8-C076-4DE8-8671-B7C7792DF7A3} = {4191DEF4-DBC9-4185-A1A6-11E80A7A9B34} - {20135939-0E5C-4906-9097-67F13945D042} = {55203DEB-3DB3-4907-8275-7FBE48185148} - {E7E2584A-1406-4B7A-9ADA-430C1FC9AEAE} = {55203DEB-3DB3-4907-8275-7FBE48185148} - {0DC5F69A-C150-4590-90D7-303B9654011C} = {4191DEF4-DBC9-4185-A1A6-11E80A7A9B34} - EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {3986513F-FAE6-4DA6-9221-51837AFC9B3C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3986513F-FAE6-4DA6-9221-51837AFC9B3C}.Debug|Any CPU.Build.0 = Debug|Any CPU @@ -75,4 +68,20 @@ Global {0DC5F69A-C150-4590-90D7-303B9654011C}.Release|Any CPU.ActiveCfg = Release|Any CPU {0DC5F69A-C150-4590-90D7-303B9654011C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {3986513F-FAE6-4DA6-9221-51837AFC9B3C} = {4191DEF4-DBC9-4185-A1A6-11E80A7A9B34} + {6512A859-F453-4388-9DAA-9B0C3E62956E} = {55203DEB-3DB3-4907-8275-7FBE48185148} + {F1C1F27D-20E5-4097-8647-0BDD74CC11FB} = {4191DEF4-DBC9-4185-A1A6-11E80A7A9B34} + {E232146D-783D-4927-AB4D-26569AE50F78} = {4191DEF4-DBC9-4185-A1A6-11E80A7A9B34} + {655CC2E8-C076-4DE8-8671-B7C7792DF7A3} = {4191DEF4-DBC9-4185-A1A6-11E80A7A9B34} + {20135939-0E5C-4906-9097-67F13945D042} = {55203DEB-3DB3-4907-8275-7FBE48185148} + {E7E2584A-1406-4B7A-9ADA-430C1FC9AEAE} = {55203DEB-3DB3-4907-8275-7FBE48185148} + {0DC5F69A-C150-4590-90D7-303B9654011C} = {4191DEF4-DBC9-4185-A1A6-11E80A7A9B34} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {B701ADE9-89EA-4C9D-BB51-0AA4E8E07217} + EndGlobalSection EndGlobal diff --git a/src/Benchmarks/BenchCompiler.cs b/src/Benchmarks/BenchCompiler.cs index aa88c830..4a92d068 100644 --- a/src/Benchmarks/BenchCompiler.cs +++ b/src/Benchmarks/BenchCompiler.cs @@ -7,6 +7,8 @@ using System.Reflection; using System.Reflection.Emit; using XamlX.Ast; +using XamlX.Emit; +using XamlX.IL; using XamlX.Parsers; using XamlX.Runtime; using XamlX.Transform; @@ -33,18 +35,21 @@ public static Func Compile(string xaml) foreach (var p in xt.GetProperties()) p.GetCustomAttributes(); } - typeof(IXamlXParentStackProviderV1).Assembly.GetCustomAttributes(); + typeof(IXamlParentStackProviderV1).Assembly.GetCustomAttributes(); var typeSystem = new SreTypeSystem(); - var configuration = BenchmarksXamlXConfiguration.Configure(typeSystem); - var parsed = XDocumentXamlXParser.Parse(xaml); - - var compiler = new XamlXCompiler(configuration, true); + var configuration = BenchmarksXamlConfiguration.Configure(typeSystem); + var parsed = XDocumentXamlParser.Parse(xaml); + + var compiler = new XamlILCompiler( + configuration, + new XamlLanguageEmitMappings(), + true); compiler.Transform(parsed); - var parsedTsType = ((IXamlXAstValueNode) parsed.Root).Type.GetClrType(); + var parsedTsType = ((IXamlAstValueNode) parsed.Root).Type.GetClrType(); #if !NETCOREAPP var path = Path.GetDirectoryName(typeof(BenchCompiler).Assembly.GetModules()[0].FullyQualifiedName); @@ -63,7 +68,7 @@ public static Func Compile(string xaml) var parserTypeBuilder = ((SreTypeSystem) typeSystem).CreateTypeBuilder(t); compiler.Compile(parsed, parserTypeBuilder, contextTypeDef, "Populate", "Build", - "XamlXNamespaceInfo", "https://github.com/kekekeks/XamlX", null); + "XamlNamespaceInfo", "https://github.com/kekekeks/Xaml", null); var created = t.CreateType(); diff --git a/src/Benchmarks/Benchmarks.csproj b/src/Benchmarks/Benchmarks.csproj index 405e2556..ba713bda 100644 --- a/src/Benchmarks/Benchmarks.csproj +++ b/src/Benchmarks/Benchmarks.csproj @@ -1,4 +1,4 @@ - + Exe diff --git a/src/Benchmarks/BenchmarksXamlXConfiguration.cs b/src/Benchmarks/BenchmarksXamlConfiguration.cs similarity index 70% rename from src/Benchmarks/BenchmarksXamlXConfiguration.cs rename to src/Benchmarks/BenchmarksXamlConfiguration.cs index 12b094e3..f67c75b6 100644 --- a/src/Benchmarks/BenchmarksXamlXConfiguration.cs +++ b/src/Benchmarks/BenchmarksXamlConfiguration.cs @@ -3,13 +3,13 @@ namespace Benchmarks { - class BenchmarksXamlXConfiguration + class BenchmarksXamlConfiguration { - public static XamlXTransformerConfiguration Configure(IXamlXTypeSystem typeSystem) + public static TransformerConfiguration Configure(IXamlTypeSystem typeSystem) { - return new XamlXTransformerConfiguration(typeSystem, + return new TransformerConfiguration(typeSystem, typeSystem.FindAssembly("Benchmarks"), - new XamlXLanguageTypeMappings(typeSystem) + new XamlLanguageTypeMappings(typeSystem) { XmlnsAttributes = { @@ -20,7 +20,7 @@ public static XamlXTransformerConfiguration Configure(IXamlXTypeSystem typeSyste typeSystem.GetType("Benchmarks.ContentAttribute") }, RootObjectProvider = typeSystem.GetType("Portable.Xaml.IRootObjectProvider"), - ParentStackProvider = typeSystem.GetType("XamlX.Runtime.IXamlXParentStackProviderV1") + ParentStackProvider = typeSystem.GetType("XamlX.Runtime.IXamlParentStackProviderV1") }); } } diff --git a/src/Benchmarks/LoadBenchmark.cs b/src/Benchmarks/LoadBenchmark.cs index 001a67f4..1c94ea80 100644 --- a/src/Benchmarks/LoadBenchmark.cs +++ b/src/Benchmarks/LoadBenchmark.cs @@ -1,4 +1,4 @@ -using System; +using System; using BenchmarkDotNet.Attributes; using System.Collections.Generic; using System.IO; @@ -49,22 +49,22 @@ public void SystemXamlNoCache() */ private Func _compiled; [Benchmark] - public void XamlX() + public void Xaml() { _compiled = _compiled ?? BenchCompiler.Compile(new StreamReader(GetStream()).ReadToEnd()); _compiled(null); } - public virtual object LoadXamlXPrecompiled(IServiceProvider sp) + public virtual object LoadXamlPrecompiled(IServiceProvider sp) { // This method will be overridden by Cecil throw new NotImplementedException(); } [Benchmark] - public void XamlXPrecompiled() + public void XamlPrecompiled() { - LoadXamlXPrecompiled(null); + LoadXamlPrecompiled(null); } } diff --git a/src/Benchmarks/LoadComplexBenchmark.xml b/src/Benchmarks/LoadComplexBenchmark.xml index 06c2aba1..85ac76ea 100644 --- a/src/Benchmarks/LoadComplexBenchmark.xml +++ b/src/Benchmarks/LoadComplexBenchmark.xml @@ -1,4 +1,4 @@ - diff --git a/src/Benchmarks/LoadSimpleBenchmark.xml b/src/Benchmarks/LoadSimpleBenchmark.xml index 19e63421..20a0f061 100644 --- a/src/Benchmarks/LoadSimpleBenchmark.xml +++ b/src/Benchmarks/LoadSimpleBenchmark.xml @@ -1,4 +1,4 @@ - diff --git a/src/Benchmarks/Program.cs b/src/Benchmarks/Program.cs index 0f3077a4..9cba133b 100644 --- a/src/Benchmarks/Program.cs +++ b/src/Benchmarks/Program.cs @@ -1,4 +1,4 @@ -using System.Linq; +using System.Linq; using BenchmarkDotNet.Columns; using BenchmarkDotNet.Configs; using BenchmarkDotNet.Diagnosers; @@ -21,10 +21,10 @@ public static void Main(string[] args) { //var benchmark = new LoadSimpleBenchmark(); var benchmark = new LoadComplexBenchmark(); - benchmark.XamlXPrecompiled(); + benchmark.XamlPrecompiled(); for (int i = 0; i < 1000; i++) { - benchmark.XamlXPrecompiled(); + benchmark.XamlPrecompiled(); } return; } diff --git a/src/BenchmarksCompiler/BenchmarksCompiler.csproj b/src/BenchmarksCompiler/BenchmarksCompiler.csproj index 3bf9f7b0..f0216a76 100644 --- a/src/BenchmarksCompiler/BenchmarksCompiler.csproj +++ b/src/BenchmarksCompiler/BenchmarksCompiler.csproj @@ -1,4 +1,4 @@ - + Exe @@ -6,8 +6,8 @@ - - + + diff --git a/src/BenchmarksCompiler/Program.cs b/src/BenchmarksCompiler/Program.cs index 0fae9f09..42943b23 100644 --- a/src/BenchmarksCompiler/Program.cs +++ b/src/BenchmarksCompiler/Program.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Diagnostics; using System.IO; using System.Linq; @@ -6,6 +6,8 @@ using Mono.Cecil; using Mono.Cecil.Cil; using Mono.Cecil.Rocks; +using XamlX.Emit; +using XamlX.IL; using XamlX.Transform; using XamlX.TypeSystem; @@ -20,14 +22,20 @@ static void Main(string[] args) var refs = File.ReadAllLines(refsPath).Concat(new[] {target}); var typeSystem = new CecilTypeSystem(refs, target); var asm = typeSystem.GetAssembly(typeSystem.FindAssembly("Benchmarks")); - var config = Benchmarks.BenchmarksXamlXConfiguration.Configure(typeSystem); + var config = Benchmarks.BenchmarksXamlConfiguration.Configure(typeSystem); var loadBench = asm.MainModule.Types.First(t => t.Name == "LoadBenchmark"); - var baseMethod = loadBench.Methods.First(m => m.Name == "LoadXamlXPrecompiled"); + var baseMethod = loadBench.Methods.First(m => m.Name == "LoadXamlPrecompiled"); - var ct = new TypeDefinition("_XamlXRuntime", "XamlXContext", TypeAttributes.Class, + var ct = new TypeDefinition("_XamlRuntime", "XamlContext", TypeAttributes.Class, asm.MainModule.TypeSystem.Object); + + asm.MainModule.Types.Add(ct); + var ctb = typeSystem.CreateTypeBuilder(ct); - var compiler = new XamlXCompiler(config, true); + var compiler = new XamlILCompiler( + config, + new XamlLanguageEmitMappings(), + true); var contextTypeDef = compiler.CreateContextType(ctb); asm.MainModule.Types.Add(ct); @@ -42,7 +50,7 @@ static void Main(string[] args) if (bt != loadBench) continue; - var loadMethod = lb.Methods.FirstOrDefault(m => m.Name == "LoadXamlXPrecompiled"); + var loadMethod = lb.Methods.FirstOrDefault(m => m.Name == "LoadXamlPrecompiled"); if (loadMethod != null) lb.Methods.Remove(loadMethod); @@ -53,13 +61,13 @@ static void Main(string[] args) while (xml[0] > 128) xml = xml.Substring(1); - var parsed = XamlX.Parsers.XDocumentXamlXParser.Parse(xml); + var parsed = XamlX.Parsers.XDocumentXamlParser.Parse(xml); compiler.Transform(parsed); compiler.Compile(parsed, typeSystem.CreateTypeBuilder(lb), contextTypeDef, - "PopulateXamlXPrecompiled", "LoadXamlXPrecompiled", - "XamlXXmlInfo", resource.Name, null); + "PopulateXamlPrecompiled", "LoadXamlPrecompiled", + "XamlXmlInfo", resource.Name, null); - loadMethod = lb.Methods.First(m => m.Name == "LoadXamlXPrecompiled"); + loadMethod = lb.Methods.First(m => m.Name == "LoadXamlPrecompiled"); loadMethod.ReturnType = asm.MainModule.TypeSystem.Object; loadMethod.Overrides.Add(baseMethod); loadMethod.Body.OptimizeMacros(); diff --git a/src/XamlX.Cecil/CecilAssembly.cs b/src/XamlX.IL.Cecil/CecilAssembly.cs similarity index 83% rename from src/XamlX.Cecil/CecilAssembly.cs rename to src/XamlX.IL.Cecil/CecilAssembly.cs index cd4b6154..07e5ff22 100644 --- a/src/XamlX.Cecil/CecilAssembly.cs +++ b/src/XamlX.IL.Cecil/CecilAssembly.cs @@ -7,7 +7,7 @@ namespace XamlX.TypeSystem { partial class CecilTypeSystem { - private class CecilAssembly : IXamlXAssembly + private class CecilAssembly : IXamlAssembly { private Dictionary _typeCache = new Dictionary(); public CecilTypeSystem TypeSystem { get; } @@ -19,16 +19,16 @@ public CecilAssembly(CecilTypeSystem typeSystem, AssemblyDefinition assembly) Assembly = assembly; } - public bool Equals(IXamlXAssembly other) => other == this; + public bool Equals(IXamlAssembly other) => other == this; public string Name => Assembly.Name.Name; - private IReadOnlyList _attributes; + private IReadOnlyList _attributes; - public IReadOnlyList CustomAttributes => + public IReadOnlyList CustomAttributes => _attributes ?? (_attributes = Assembly.CustomAttributes.Select(ca => new CecilCustomAttribute(TypeSystem, ca)).ToList()); - public IXamlXType FindType(string fullName) + public IXamlType FindType(string fullName) { if (_typeCache.TryGetValue(fullName, out var rv)) return rv; diff --git a/src/XamlX.Cecil/CecilCustomAttribute.cs b/src/XamlX.IL.Cecil/CecilCustomAttribute.cs similarity index 79% rename from src/XamlX.Cecil/CecilCustomAttribute.cs rename to src/XamlX.IL.Cecil/CecilCustomAttribute.cs index 920ec5f4..a68c4fd4 100644 --- a/src/XamlX.Cecil/CecilCustomAttribute.cs +++ b/src/XamlX.IL.Cecil/CecilCustomAttribute.cs @@ -6,7 +6,7 @@ namespace XamlX.TypeSystem { partial class CecilTypeSystem { - class CecilCustomAttribute : IXamlXCustomAttribute + class CecilCustomAttribute : IXamlCustomAttribute { public CecilTypeSystem TypeSystem { get; } @@ -18,10 +18,10 @@ public CecilCustomAttribute(CecilTypeSystem typeSystem, CustomAttribute data) Data = data; } - public bool Equals(IXamlXCustomAttribute other) => other is CecilCustomAttribute ca && ca.Data == Data; + public bool Equals(IXamlCustomAttribute other) => other is CecilCustomAttribute ca && ca.Data == Data; - private IXamlXType _type; - public IXamlXType Type => _type ?? (_type = TypeSystem.Resolve(Data.AttributeType)); + private IXamlType _type; + public IXamlType Type => _type ?? (_type = TypeSystem.Resolve(Data.AttributeType)); private List _parameters; diff --git a/src/XamlX.Cecil/CecilEmitter.cs b/src/XamlX.IL.Cecil/CecilEmitter.cs similarity index 88% rename from src/XamlX.Cecil/CecilEmitter.cs rename to src/XamlX.IL.Cecil/CecilEmitter.cs index 2832f50e..870c413e 100644 --- a/src/XamlX.Cecil/CecilEmitter.cs +++ b/src/XamlX.IL.Cecil/CecilEmitter.cs @@ -8,6 +8,7 @@ using Mono.Cecil; using Mono.Cecil.Cil; using Mono.Cecil.Rocks; +using XamlX.IL; using MethodBody = Mono.Cecil.Cil.MethodBody; using SreOpCode = System.Reflection.Emit.OpCode; using SreOpCodes = System.Reflection.Emit.OpCodes; @@ -16,7 +17,7 @@ namespace XamlX.TypeSystem { partial class CecilTypeSystem { - public class CecilEmitter : IXamlXEmitter + public class CecilEmitter : IXamlILEmitter { TypeReference Import(TypeReference r) { @@ -61,18 +62,18 @@ static CecilEmitter() private readonly MethodDefinition _method; private CecilDebugPoint _pendingDebugPoint; private CecilDebugPoint _lastDebugPoint; - public CecilEmitter(IXamlXTypeSystem typeSystem, MethodDefinition method) + public CecilEmitter(IXamlTypeSystem typeSystem, MethodDefinition method) { _method = method; _body = method.Body; TypeSystem = typeSystem; - LocalsPool = new XamlXLocalsPool(this); + LocalsPool = new XamlLocalsPool(t => this.DefineLocal(t)); } - public IXamlXTypeSystem TypeSystem { get; } + public IXamlTypeSystem TypeSystem { get; } - IXamlXEmitter Emit(Instruction i) + IXamlILEmitter Emit(Instruction i) { _body.Instructions.Add(i); if (_pendingDebugPoint != null) @@ -109,45 +110,45 @@ private Instruction CreateI(OpCode code, int arg) private ModuleDefinition M => _body.Method.Module; - public IXamlXEmitter Emit(SreOpCode code) + public IXamlILEmitter Emit(SreOpCode code) => Emit(Instruction.Create(Dic[code])); - public IXamlXEmitter Emit(SreOpCode code, IXamlXField field) + public IXamlILEmitter Emit(SreOpCode code, IXamlField field) { return Emit(Instruction.Create(Dic[code], Import(((CecilField) field).Field))); } - public IXamlXEmitter Emit(SreOpCode code, IXamlXMethod method) + public IXamlILEmitter Emit(SreOpCode code, IXamlMethod method) => Emit(Instruction.Create(Dic[code], M.ImportReference(((CecilMethod) method).IlReference))); - public IXamlXEmitter Emit(SreOpCode code, IXamlXConstructor ctor) + public IXamlILEmitter Emit(SreOpCode code, IXamlConstructor ctor) => Emit(Instruction.Create(Dic[code], M.ImportReference(((CecilConstructor) ctor).IlReference))); - public IXamlXEmitter Emit(SreOpCode code, string arg) + public IXamlILEmitter Emit(SreOpCode code, string arg) => Emit(Instruction.Create(Dic[code], arg)); - public IXamlXEmitter Emit(SreOpCode code, int arg) + public IXamlILEmitter Emit(SreOpCode code, int arg) => Emit(CreateI(Dic[code], arg)); - public IXamlXEmitter Emit(SreOpCode code, long arg) + public IXamlILEmitter Emit(SreOpCode code, long arg) => Emit(Instruction.Create(Dic[code], arg)); - public IXamlXEmitter Emit(SreOpCode code, IXamlXType type) + public IXamlILEmitter Emit(SreOpCode code, IXamlType type) => Emit(Instruction.Create(Dic[code], Import(((ITypeReference) type).Reference))); - public IXamlXEmitter Emit(SreOpCode code, float arg) + public IXamlILEmitter Emit(SreOpCode code, float arg) => Emit(Instruction.Create(Dic[code], arg)); - public IXamlXEmitter Emit(SreOpCode code, double arg) + public IXamlILEmitter Emit(SreOpCode code, double arg) => Emit(Instruction.Create(Dic[code], arg)); - class CecilLocal : IXamlXLocal + class CecilLocal : IXamlLocal { public VariableDefinition Variable { get; set; } } - class CecilLabel : IXamlXLabel + class CecilLabel : IXamlLabel { private List _pendingConsumers; private Instruction _target; @@ -175,7 +176,7 @@ public void Mark(Instruction i) } } - public IXamlXLocal DefineLocal(IXamlXType type) + public IXamlLocal DefineLocal(IXamlType type) { var r = Import(((ITypeReference) type).Reference); var def = new VariableDefinition(r); @@ -183,18 +184,18 @@ public IXamlXLocal DefineLocal(IXamlXType type) return new CecilLocal {Variable = def}; } - public IXamlXLabel DefineLabel() => new CecilLabel(); + public IXamlLabel DefineLabel() => new CecilLabel(); - public IXamlXEmitter MarkLabel(IXamlXLabel label) + public IXamlILEmitter MarkLabel(IXamlLabel label) { _markedLabels.Add((CecilLabel) label); return this; } - public IXamlXEmitter Emit(SreOpCode code, IXamlXLabel label) + public IXamlILEmitter Emit(SreOpCode code, IXamlLabel label) => Emit(((CecilLabel)label).CreateInstruction(Dic[code])); - public IXamlXEmitter Emit(SreOpCode code, IXamlXLocal local) + public IXamlILEmitter Emit(SreOpCode code, IXamlLocal local) => Emit(Instruction.Create(Dic[code], ((CecilLocal) local).Variable)); private static readonly Guid LanguageGuid = new Guid("9a37fc74-96b5-4dbc-8b8a-c4e603735a63"); @@ -308,7 +309,7 @@ public void InsertSequencePoint(IFileSource file, int line, int position) } } - public XamlXLocalsPool LocalsPool { get; } + public XamlLocalsPool LocalsPool { get; } } } } diff --git a/src/XamlX.Cecil/CecilEvent.cs b/src/XamlX.IL.Cecil/CecilEvent.cs similarity index 75% rename from src/XamlX.Cecil/CecilEvent.cs rename to src/XamlX.IL.Cecil/CecilEvent.cs index 70761c48..3e964e34 100644 --- a/src/XamlX.Cecil/CecilEvent.cs +++ b/src/XamlX.IL.Cecil/CecilEvent.cs @@ -6,7 +6,7 @@ namespace XamlX.TypeSystem { partial class CecilTypeSystem { - class CecilEvent : IXamlXEventInfo + class CecilEvent : IXamlEventInfo { private readonly TypeReference _declaringType; public CecilTypeSystem TypeSystem { get; } @@ -18,12 +18,12 @@ public CecilEvent(CecilTypeSystem typeSystem, EventDefinition ev, TypeReference TypeSystem = typeSystem; Event = ev; } - public bool Equals(IXamlXEventInfo other) => other is CecilEvent cp && cp.Event == Event; + public bool Equals(IXamlEventInfo other) => other is CecilEvent cp && cp.Event == Event; public string Name => Event.Name; - private IXamlXMethod _getter; + private IXamlMethod _getter; - public IXamlXMethod Add => Event.AddMethod == null + public IXamlMethod Add => Event.AddMethod == null ? null : _getter ?? (_getter = TypeSystem.Resolve(Event.AddMethod, _declaringType)); diff --git a/src/XamlX.Cecil/CecilField.cs b/src/XamlX.IL.Cecil/CecilField.cs similarity index 75% rename from src/XamlX.Cecil/CecilField.cs rename to src/XamlX.IL.Cecil/CecilField.cs index ce27c797..57d912cc 100644 --- a/src/XamlX.Cecil/CecilField.cs +++ b/src/XamlX.IL.Cecil/CecilField.cs @@ -4,7 +4,7 @@ namespace XamlX.TypeSystem { partial class CecilTypeSystem { - public class CecilField : IXamlXField + public class CecilField : IXamlField { private readonly FieldDefinition _def; public CecilTypeSystem TypeSystem { get; } @@ -17,11 +17,11 @@ public CecilField(CecilTypeSystem typeSystem, FieldDefinition def, TypeReference Field = new FieldReference(def.Name, def.FieldType, declaringType); } - public bool Equals(IXamlXField other) => other is CecilField cf && cf.Field == Field; + public bool Equals(IXamlField other) => other is CecilField cf && cf.Field == Field; public string Name => Field.Name; - private IXamlXType _type; - public IXamlXType FieldType => _type ?? (_type = TypeSystem.Resolve(Field.FieldType.TransformGeneric(Field.DeclaringType))); + private IXamlType _type; + public IXamlType FieldType => _type ?? (_type = TypeSystem.Resolve(Field.FieldType.TransformGeneric(Field.DeclaringType))); public bool IsPublic => _def.IsPublic; public bool IsStatic => _def.IsStatic; public bool IsLiteral => _def.IsLiteral; diff --git a/src/XamlX.Cecil/CecilHelpers.cs b/src/XamlX.IL.Cecil/CecilHelpers.cs similarity index 98% rename from src/XamlX.Cecil/CecilHelpers.cs rename to src/XamlX.IL.Cecil/CecilHelpers.cs index 86517e40..370524b0 100644 --- a/src/XamlX.Cecil/CecilHelpers.cs +++ b/src/XamlX.IL.Cecil/CecilHelpers.cs @@ -4,9 +4,6 @@ namespace XamlX.TypeSystem { -#if !XAMLIL_CECIL_INTERNAL - public -#endif static class CecilHelpers { [ThreadStatic] private static int _recursionDepth; diff --git a/src/XamlX.Cecil/CecilMethod.cs b/src/XamlX.IL.Cecil/CecilMethod.cs similarity index 84% rename from src/XamlX.Cecil/CecilMethod.cs rename to src/XamlX.IL.Cecil/CecilMethod.cs index 11375891..7d1f0466 100644 --- a/src/XamlX.Cecil/CecilMethod.cs +++ b/src/XamlX.IL.Cecil/CecilMethod.cs @@ -2,6 +2,7 @@ using System.Diagnostics; using System.Linq; using Mono.Cecil; +using XamlX.IL; namespace XamlX.TypeSystem { @@ -60,43 +61,43 @@ MethodReference MakeRef(bool transform) public bool IsPublic => Definition.IsPublic; public bool IsStatic => Definition.IsStatic; - private IXamlXType _returnType; + private IXamlType _returnType; - public IXamlXType ReturnType => + public IXamlType ReturnType => _returnType ?? (_returnType = TypeSystem.Resolve(Reference.ReturnType)); - private IXamlXType _declaringType; + private IXamlType _declaringType; - public IXamlXType DeclaringType => + public IXamlType DeclaringType => _declaringType = _declaringType ?? (_declaringType = TypeSystem.Resolve(_declaringTypeReference)); - private IReadOnlyList _parameters; + private IReadOnlyList _parameters; - public IReadOnlyList Parameters => + public IReadOnlyList Parameters => _parameters ?? (_parameters = Reference.Parameters.Select(p => TypeSystem.Resolve(p.ParameterType)).ToList()); - private IXamlXEmitter _generator; + private IXamlILEmitter _generator; - public IXamlXEmitter Generator => + public IXamlILEmitter Generator => _generator ?? (_generator = new CecilEmitter(TypeSystem, Definition)); } [DebuggerDisplay("{" + nameof(Reference) + "}")] - class CecilMethod : CecilMethodBase, IXamlXMethodBuilder + class CecilMethod : CecilMethodBase, IXamlMethodBuilder { public CecilMethod(CecilTypeSystem typeSystem, MethodReference methodRef, TypeReference declaringType) : base(typeSystem, methodRef, declaringType) { } - public bool Equals(IXamlXMethod other) => + public bool Equals(IXamlMethod other) => // I hope this is enough... other is CecilMethod cm && DeclaringType.Equals(cm.DeclaringType) && Reference.FullName == cm.Reference.FullName; - public IXamlXMethod MakeGenericMethod(IReadOnlyList typeArguments) + public IXamlMethod MakeGenericMethod(IReadOnlyList typeArguments) { GenericInstanceMethod instantiation = new GenericInstanceMethod(Reference); foreach (var type in typeArguments.Cast().Select(r => r.Reference)) @@ -110,14 +111,14 @@ public IXamlXMethod MakeGenericMethod(IReadOnlyList typeArguments) } [DebuggerDisplay("{" + nameof(Reference) + "}")] - class CecilConstructor : CecilMethodBase, IXamlXConstructorBuilder + class CecilConstructor : CecilMethodBase, IXamlConstructorBuilder { public CecilConstructor(CecilTypeSystem typeSystem, MethodDefinition methodDef, TypeReference declaringType) : base(typeSystem, methodDef, declaringType) { } - public bool Equals(IXamlXConstructor other) => other is CecilConstructor cm + public bool Equals(IXamlConstructor other) => other is CecilConstructor cm && cm.Reference.Equals(Reference); } } diff --git a/src/XamlX.Cecil/CecilProperty.cs b/src/XamlX.IL.Cecil/CecilProperty.cs similarity index 65% rename from src/XamlX.Cecil/CecilProperty.cs rename to src/XamlX.IL.Cecil/CecilProperty.cs index d662e3d1..15239fb1 100644 --- a/src/XamlX.Cecil/CecilProperty.cs +++ b/src/XamlX.IL.Cecil/CecilProperty.cs @@ -6,7 +6,7 @@ namespace XamlX.TypeSystem { partial class CecilTypeSystem { - class CecilProperty : IXamlXProperty + class CecilProperty : IXamlProperty { private readonly TypeReference _declaringType; public CecilTypeSystem TypeSystem { get; } @@ -19,32 +19,32 @@ public CecilProperty(CecilTypeSystem typeSystem, PropertyDefinition property, Ty Property = property; } - public bool Equals(IXamlXProperty other) => other is CecilProperty cp && cp.Property == Property; + public bool Equals(IXamlProperty other) => other is CecilProperty cp && cp.Property == Property; public string Name => Property.Name; - private IXamlXType _type; + private IXamlType _type; - public IXamlXType PropertyType => + public IXamlType PropertyType => _type ?? (_type = TypeSystem.Resolve(Property.PropertyType.TransformGeneric(_declaringType))); - private IXamlXMethod _setter; + private IXamlMethod _setter; - public IXamlXMethod Setter => Property.SetMethod == null + public IXamlMethod Setter => Property.SetMethod == null ? null : _setter ?? (_setter = TypeSystem.Resolve(Property.SetMethod, _declaringType)); - private IXamlXMethod _getter; + private IXamlMethod _getter; - public IXamlXMethod Getter => Property.GetMethod == null + public IXamlMethod Getter => Property.GetMethod == null ? null : _getter ?? (_getter = TypeSystem.Resolve(Property.GetMethod, _declaringType)); - private IReadOnlyList _attributes; - public IReadOnlyList CustomAttributes => + private IReadOnlyList _attributes; + public IReadOnlyList CustomAttributes => _attributes ?? (_attributes = Property.CustomAttributes.Select(ca => new CecilCustomAttribute(TypeSystem, ca)).ToList()); - private IReadOnlyList _indexerParameters; - public IReadOnlyList IndexerParameters => + private IReadOnlyList _indexerParameters; + public IReadOnlyList IndexerParameters => _indexerParameters ?? (_indexerParameters = Property.Parameters.Select(param => TypeSystem.Resolve(param.ParameterType.TransformGeneric(_declaringType))).ToList()); } diff --git a/src/XamlX.Cecil/CecilType.cs b/src/XamlX.IL.Cecil/CecilType.cs similarity index 72% rename from src/XamlX.Cecil/CecilType.cs rename to src/XamlX.IL.Cecil/CecilType.cs index d0046c3c..f1206f11 100644 --- a/src/XamlX.Cecil/CecilType.cs +++ b/src/XamlX.IL.Cecil/CecilType.cs @@ -13,14 +13,14 @@ partial class CecilTypeSystem // consistency with CecilTypeBuilder [DebuggerDisplay("{" + nameof(Reference) + "}")] - class CecilType : IXamlXType, ITypeReference + class CecilType : IXamlType, ITypeReference { private readonly CecilAssembly _assembly; public CecilTypeSystem TypeSystem { get; } public TypeReference Reference { get; } public TypeDefinition Definition { get; } - private Dictionary _isAssignableFromCache = new Dictionary(); + private Dictionary _isAssignableFromCache = new Dictionary(); public CecilType(CecilTypeSystem typeSystem, CecilAssembly assembly, TypeDefinition definition) : this(typeSystem, assembly, definition, definition) { @@ -38,7 +38,7 @@ public CecilType(CecilTypeSystem typeSystem, CecilAssembly assembly, TypeDefinit Definition = ((CecilType)typeSystem.GetType("System.Array")).Definition; } - public bool Equals(IXamlXType other) + public bool Equals(IXamlType other) { if (ReferenceEquals(this, other)) return true; @@ -51,67 +51,67 @@ public bool Equals(IXamlXType other) public string Name => Reference.Name; public string FullName => Reference.FullName; public string Namespace => Reference.Namespace; - public IXamlXAssembly Assembly => _assembly; - protected IReadOnlyList _methods; + public IXamlAssembly Assembly => _assembly; + protected IReadOnlyList _methods; - public IReadOnlyList Methods => + public IReadOnlyList Methods => _methods ?? (_methods = Definition.GetMethods().Select(m => new CecilMethod(TypeSystem, m, Reference)).ToList()); - protected IReadOnlyList _constructors; + protected IReadOnlyList _constructors; - public IReadOnlyList Constructors => + public IReadOnlyList Constructors => _constructors ?? (_constructors = Definition.GetConstructors() .Select(c => new CecilConstructor(TypeSystem, c, Reference)).ToList()); - protected IReadOnlyList _fields; + protected IReadOnlyList _fields; - public IReadOnlyList Fields => + public IReadOnlyList Fields => _fields ?? (_fields = Definition.Fields .Select(f => new CecilField(TypeSystem, f, Reference)).ToList()); - protected IReadOnlyList _properties; + protected IReadOnlyList _properties; - public IReadOnlyList Properties => + public IReadOnlyList Properties => _properties ?? (_properties = Definition.Properties.Select(p => new CecilProperty(TypeSystem, p, Reference)).ToList()); - protected IReadOnlyList _events; + protected IReadOnlyList _events; - public IReadOnlyList Events => + public IReadOnlyList Events => _events ?? (_events = Definition.Events.Select(p => new CecilEvent(TypeSystem, p, Reference)).ToList()); - private IReadOnlyList _genericArguments; + private IReadOnlyList _genericArguments; - public IReadOnlyList GenericArguments => + public IReadOnlyList GenericArguments => _genericArguments ?? (_genericArguments = Reference is GenericInstanceType gi ? gi.GenericArguments.Select(ga => TypeSystem.Resolve(ga)).ToList() : null); - private IReadOnlyList _genericParameters; + private IReadOnlyList _genericParameters; - public IReadOnlyList GenericParameters => + public IReadOnlyList GenericParameters => _genericParameters ?? (_genericParameters = Reference is TypeDefinition td && td.HasGenericParameters ? td.GenericParameters.Select(gp => TypeSystem.Resolve(gp)).ToList() : null); - protected IReadOnlyList _attributes; - public IReadOnlyList CustomAttributes => + protected IReadOnlyList _attributes; + public IReadOnlyList CustomAttributes => _attributes ?? (_attributes = Definition.CustomAttributes.Select(ca => new CecilCustomAttribute(TypeSystem, ca)).ToList()); - public bool IsAssignableFrom(IXamlXType type) + public bool IsAssignableFrom(IXamlType type) { if (_isAssignableFromCache.TryGetValue(type, out var cached)) return cached; return _isAssignableFromCache[type] = IsAssignableFromCore(type); } - bool IsAssignableFromCore(IXamlXType type) + bool IsAssignableFromCore(IXamlType type) { if (!type.IsValueType - && type == XamlXPseudoType.Null) + && type == XamlPseudoType.Null) return true; if (type.IsValueType @@ -133,7 +133,7 @@ bool IsAssignableFromCore(IXamlXType type) return false; } - public IXamlXType MakeGenericType(IReadOnlyList typeArguments) + public IXamlType MakeGenericType(IReadOnlyList typeArguments) { if (Reference == Definition) { @@ -144,40 +144,40 @@ public IXamlXType MakeGenericType(IReadOnlyList typeArguments) throw new InvalidOperationException(); } - private IXamlXType _genericTypeDefinition; + private IXamlType _genericTypeDefinition; - public IXamlXType GenericTypeDefinition => + public IXamlType GenericTypeDefinition => _genericTypeDefinition ?? (_genericTypeDefinition = (Reference is GenericInstanceType) ? TypeSystem.Resolve(Definition) : null); public bool IsArray => Reference.IsArray; - private IXamlXType _arrayType; + private IXamlType _arrayType; - public IXamlXType ArrayElementType => + public IXamlType ArrayElementType => _arrayType ?? (_arrayType = IsArray ? TypeSystem.Resolve(Definition) : null); - public IXamlXType MakeArrayType(int dimensions) => TypeSystem.Resolve(Reference.MakeArrayType(dimensions)); + public IXamlType MakeArrayType(int dimensions) => TypeSystem.Resolve(Reference.MakeArrayType(dimensions)); - private IXamlXType _baseType; + private IXamlType _baseType; - public IXamlXType BaseType => Definition.BaseType == null + public IXamlType BaseType => Definition.BaseType == null ? null : _baseType ?? (_baseType = TypeSystem.Resolve( Definition.BaseType.TransformGeneric(Reference))); public bool IsValueType => Definition.IsValueType; public bool IsEnum => Definition.IsEnum; - protected IReadOnlyList _interfaces; + protected IReadOnlyList _interfaces; - public IReadOnlyList Interfaces => + public IReadOnlyList Interfaces => _interfaces ?? (_interfaces = Definition.Interfaces.Select(i => TypeSystem.Resolve(i.InterfaceType .TransformGeneric(Reference))).ToList()); public bool IsInterface => Definition.IsInterface; - public IXamlXType GetEnumUnderlyingType() + public IXamlType GetEnumUnderlyingType() { if (!IsEnum) return null; diff --git a/src/XamlX.Cecil/CecilTypeBuilder.cs b/src/XamlX.IL.Cecil/CecilTypeBuilder.cs similarity index 82% rename from src/XamlX.Cecil/CecilTypeBuilder.cs rename to src/XamlX.IL.Cecil/CecilTypeBuilder.cs index f7a1aab9..bc6ec090 100644 --- a/src/XamlX.Cecil/CecilTypeBuilder.cs +++ b/src/XamlX.IL.Cecil/CecilTypeBuilder.cs @@ -3,12 +3,13 @@ using System.Linq; using Mono.Cecil; using Mono.Cecil.Rocks; +using XamlX.IL; namespace XamlX.TypeSystem { partial class CecilTypeSystem { - class CecilTypeBuilder : CecilType, IXamlXTypeBuilder + class CecilTypeBuilder : CecilType, IXamlTypeBuilder { protected TypeReference SelfReference; public CecilTypeBuilder(CecilTypeSystem typeSystem, CecilAssembly assembly, TypeDefinition definition) @@ -17,10 +18,10 @@ public CecilTypeBuilder(CecilTypeSystem typeSystem, CecilAssembly assembly, Type SelfReference = definition; } - TypeReference GetReference(IXamlXType type) => + TypeReference GetReference(IXamlType type) => Definition.Module.ImportReference(((ITypeReference) type).Reference); - public IXamlXField DefineField(IXamlXType type, string name, bool isPublic, bool isStatic) + public IXamlField DefineField(IXamlType type, string name, bool isPublic, bool isStatic) { var r = GetReference(type); var attrs = default(FieldAttributes); @@ -36,14 +37,14 @@ public IXamlXField DefineField(IXamlXType type, string name, bool isPublic, bool return rv; } - public void AddInterfaceImplementation(IXamlXType type) + public void AddInterfaceImplementation(IXamlType type) { Definition.Interfaces.Add(new InterfaceImplementation(GetReference(type))); _interfaces = null; } - public IXamlXMethodBuilder DefineMethod(IXamlXType returnType, IEnumerable args, string name, bool isPublic, bool isStatic, - bool isInterfaceImpl, IXamlXMethod overrideMethod = null) + public IXamlMethodBuilder DefineMethod(IXamlType returnType, IEnumerable args, string name, bool isPublic, bool isStatic, + bool isInterfaceImpl, IXamlMethod overrideMethod = null) { var attrs = default(MethodAttributes); if (isPublic) @@ -67,7 +68,7 @@ public IXamlXMethodBuilder DefineMethod(IXamlXType returnType, IEnumerable DefineConstructor(bool isStatic, params IXamlType[] args) { var attrs = MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName; @@ -102,9 +103,9 @@ public IXamlXConstructorBuilder DefineConstructor(bool isStatic, params IXamlXTy return rv; } - public IXamlXType CreateType() => this; + public IXamlType CreateType() => this; - public IXamlXTypeBuilder DefineSubType(IXamlXType baseType, string name, bool isPublic) + public IXamlTypeBuilder DefineSubType(IXamlType baseType, string name, bool isPublic) { var td = new TypeDefinition("", name, isPublic ? TypeAttributes.NestedPublic : TypeAttributes.NestedPrivate, GetReference(baseType)); @@ -113,7 +114,7 @@ public IXamlXTypeBuilder DefineSubType(IXamlXType baseType, string name, bool is return new CecilTypeBuilder(TypeSystem, (CecilAssembly) Assembly, td); } - public void DefineGenericParameters(IReadOnlyList> args) + public void DefineGenericParameters(IReadOnlyList> args) { foreach (var arg in args) { diff --git a/src/XamlX.Cecil/CecilTypeCache.cs b/src/XamlX.IL.Cecil/CecilTypeCache.cs similarity index 100% rename from src/XamlX.Cecil/CecilTypeCache.cs rename to src/XamlX.IL.Cecil/CecilTypeCache.cs diff --git a/src/XamlX.Cecil/CecilTypeSystem.cs b/src/XamlX.IL.Cecil/CecilTypeSystem.cs similarity index 80% rename from src/XamlX.Cecil/CecilTypeSystem.cs rename to src/XamlX.IL.Cecil/CecilTypeSystem.cs index b6063951..f71e77cf 100644 --- a/src/XamlX.Cecil/CecilTypeSystem.cs +++ b/src/XamlX.IL.Cecil/CecilTypeSystem.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -6,20 +6,21 @@ using Mono.Cecil.Cil; using Mono.Cecil.Pdb; using Mono.Cecil.Rocks; +using XamlX.IL; namespace XamlX.TypeSystem { - #if !XAMLIL_CECIL_INTERNAL + #if !XAMLX_CECIL_INTERNAL public #endif - partial class CecilTypeSystem : IXamlXTypeSystem, IAssemblyResolver + partial class CecilTypeSystem : IXamlTypeSystem, IAssemblyResolver { private List _asms = new List(); private Dictionary _assemblyCache = new Dictionary(); - private Dictionary _typeReferenceCache = new Dictionary(); + private Dictionary _typeReferenceCache = new Dictionary(); private Dictionary _assemblyDic = new Dictionary(); - private Dictionary _unresolvedTypeCache = new Dictionary(); + private Dictionary _unresolvedTypeCache = new Dictionary(); private CustomMetadataResolver _resolver; private CecilTypeCache _typeCache; @@ -73,12 +74,12 @@ public CecilTypeSystem(IEnumerable paths, string targetPath = null) } } - public IXamlXAssembly TargetAssembly { get; private set; } + public IXamlAssembly TargetAssembly { get; private set; } public AssemblyDefinition TargetAssemblyDefinition { get; private set; } - public IReadOnlyList Assemblies => _asms.AsReadOnly(); - public IXamlXAssembly FindAssembly(string name) => _asms.FirstOrDefault(a => a.Assembly.Name.Name == name); + public IReadOnlyList Assemblies => _asms.AsReadOnly(); + public IXamlAssembly FindAssembly(string name) => _asms.FirstOrDefault(a => a.Assembly.Name.Name == name); - public IXamlXType FindType(string name) + public IXamlType FindType(string name) { foreach (var asm in _asms) { @@ -89,12 +90,12 @@ public IXamlXType FindType(string name) return null; } - public IXamlXType FindType(string name, string assembly) + public IXamlType FindType(string name, string assembly) => FindAssembly(assembly)?.FindType(name); - public TypeReference GetTypeReference(IXamlXType t) => ((ITypeReference)t).Reference; - public MethodReference GetMethodReference(IXamlXMethod t) => ((CecilMethod)t).IlReference; + public TypeReference GetTypeReference(IXamlType t) => ((ITypeReference)t).Reference; + public MethodReference GetMethodReference(IXamlMethod t) => ((CecilMethod)t).IlReference; CecilAssembly FindAsm(AssemblyDefinition d) { @@ -102,7 +103,7 @@ CecilAssembly FindAsm(AssemblyDefinition d) return asm; } - IXamlXType Resolve(TypeReference reference) + IXamlType Resolve(TypeReference reference) { if (!_typeReferenceCache.TryGetValue(reference, out var rv)) { @@ -135,7 +136,7 @@ IXamlXType Resolve(TypeReference reference) return rv; } - public IXamlXAssembly RegisterAssembly(AssemblyDefinition asm) + public IXamlAssembly RegisterAssembly(AssemblyDefinition asm) { var wrapped = new CecilAssembly(this, asm); _asms.Add(wrapped); @@ -156,7 +157,7 @@ public AssemblyDefinition CreateAndRegisterAssembly(string name, Version version return def; } - private IXamlXMethod Resolve(MethodDefinition method, TypeReference declaringType) + private IXamlMethod Resolve(MethodDefinition method, TypeReference declaringType) { return new CecilMethod(this, method, declaringType); } @@ -168,12 +169,12 @@ interface ITypeReference TypeReference Reference { get; } } - public IXamlXTypeBuilder CreateTypeBuilder(TypeDefinition def) + public IXamlTypeBuilder CreateTypeBuilder(TypeDefinition def) { return new CecilTypeBuilder(this, FindAsm(def.Module.Assembly), def); } - public AssemblyDefinition GetAssembly(IXamlXAssembly asm) + public AssemblyDefinition GetAssembly(IXamlAssembly asm) => ((CecilAssembly) asm).Assembly; } } diff --git a/src/XamlX.Cecil/CustomMetadataResolver.cs b/src/XamlX.IL.Cecil/CustomMetadataResolver.cs similarity index 100% rename from src/XamlX.Cecil/CustomMetadataResolver.cs rename to src/XamlX.IL.Cecil/CustomMetadataResolver.cs diff --git a/src/XamlX.Cecil/UnresolvedCecilType.cs b/src/XamlX.IL.Cecil/UnresolvedCecilType.cs similarity index 83% rename from src/XamlX.Cecil/UnresolvedCecilType.cs rename to src/XamlX.IL.Cecil/UnresolvedCecilType.cs index 6694d852..6988aaa1 100644 --- a/src/XamlX.Cecil/UnresolvedCecilType.cs +++ b/src/XamlX.IL.Cecil/UnresolvedCecilType.cs @@ -4,7 +4,7 @@ namespace XamlX.TypeSystem { partial class CecilTypeSystem { - class UnresolvedCecilType : XamlXPseudoType, ITypeReference + class UnresolvedCecilType : XamlPseudoType, ITypeReference { public TypeReference Reference { get; } diff --git a/src/XamlX.Cecil/XamlX.Cecil.csproj b/src/XamlX.IL.Cecil/XamlX.IL.Cecil.csproj similarity index 89% rename from src/XamlX.Cecil/XamlX.Cecil.csproj rename to src/XamlX.IL.Cecil/XamlX.IL.Cecil.csproj index a1528ebb..92949f34 100644 --- a/src/XamlX.Cecil/XamlX.Cecil.csproj +++ b/src/XamlX.IL.Cecil/XamlX.IL.Cecil.csproj @@ -1,4 +1,4 @@ - + netstandard2.0 diff --git a/src/XamlX.Runtime/Interfaces.cs b/src/XamlX.Runtime/Interfaces.cs index 871e6433..9098f88c 100644 --- a/src/XamlX.Runtime/Interfaces.cs +++ b/src/XamlX.Runtime/Interfaces.cs @@ -1,21 +1,21 @@ -using System; +using System; using System.Collections.Generic; namespace XamlX.Runtime { - public interface IXamlXParentStackProviderV1 + public interface IXamlParentStackProviderV1 { IEnumerable Parents { get; } } - public class XamlXXmlNamespaceInfoV1 + public class XamlXmlNamespaceInfoV1 { public string ClrNamespace { get; set; } public string ClrAssemblyName { get; set; } } - public interface IXamlXXmlNamespaceInfoProviderV1 + public interface IXamlXmlNamespaceInfoProviderV1 { - IReadOnlyDictionary> XmlNamespaces { get; } + IReadOnlyDictionary> XmlNamespaces { get; } } } \ No newline at end of file diff --git a/src/XamlX.Runtime/XamlX.Runtime.csproj b/src/XamlX.Runtime/XamlX.Runtime.csproj index 27560206..d2a210cd 100644 --- a/src/XamlX.Runtime/XamlX.Runtime.csproj +++ b/src/XamlX.Runtime/XamlX.Runtime.csproj @@ -1,4 +1,4 @@ - + netstandard2.0 diff --git a/src/XamlX/Ast/Clr.cs b/src/XamlX/Ast/Clr.cs index 8d47f51f..72512be4 100644 --- a/src/XamlX/Ast/Clr.cs +++ b/src/XamlX/Ast/Clr.cs @@ -1,20 +1,22 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; +using XamlX.Emit; +using XamlX.IL; using XamlX.Transform; using XamlX.TypeSystem; -using Visitor = XamlX.Ast.IXamlXAstVisitor; +using Visitor = XamlX.Ast.IXamlAstVisitor; namespace XamlX.Ast { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXAstClrTypeReference : XamlXAstNode, IXamlXAstTypeReference + class XamlAstClrTypeReference : XamlAstNode, IXamlAstTypeReference { - public IXamlXType Type { get; } + public IXamlType Type { get; } - public XamlXAstClrTypeReference(IXamlXLineInfo lineInfo, IXamlXType type, bool isMarkupExtension) : base(lineInfo) + public XamlAstClrTypeReference(IXamlLineInfo lineInfo, IXamlType type, bool isMarkupExtension) : base(lineInfo) { Type = type; IsMarkupExtension = isMarkupExtension; @@ -23,30 +25,30 @@ public XamlXAstClrTypeReference(IXamlXLineInfo lineInfo, IXamlXType type, bool i public override string ToString() => Type.GetFqn(); public bool IsMarkupExtension { get; } - public bool Equals(IXamlXAstTypeReference other) => - other is XamlXAstClrTypeReference clr && clr.Type.Equals(Type) && + public bool Equals(IXamlAstTypeReference other) => + other is XamlAstClrTypeReference clr && clr.Type.Equals(Type) && clr.IsMarkupExtension == IsMarkupExtension; } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXAstClrProperty : XamlXAstNode, IXamlXAstPropertyReference + class XamlAstClrProperty : XamlAstNode, IXamlAstPropertyReference { public string Name { get; set; } - public IXamlXMethod Getter { get; set; } - public List Setters { get; set; } = new List(); - public List CustomAttributes { get; set; } = new List(); - public IXamlXType DeclaringType { get; set; } - public Dictionary TypeConverters { get; set; } = new Dictionary(); + public IXamlMethod Getter { get; set; } + public List Setters { get; set; } = new List(); + public List CustomAttributes { get; set; } = new List(); + public IXamlType DeclaringType { get; set; } + public Dictionary TypeConverters { get; set; } = new Dictionary(); - public XamlXAstClrProperty(IXamlXLineInfo lineInfo, IXamlXProperty property, - XamlXTransformerConfiguration cfg) : base(lineInfo) + public XamlAstClrProperty(IXamlLineInfo lineInfo, IXamlProperty property, + TransformerConfiguration cfg) : base(lineInfo) { Name = property.Name; Getter = property.Getter; if (property.Setter != null) - Setters.Add(new XamlXDirectCallPropertySetter(property.Setter)); + Setters.Add(new XamlDirectCallPropertySetter(property.Setter)); CustomAttributes = property.CustomAttributes.ToList(); DeclaringType = (property.Getter ?? property.Setter)?.DeclaringType; var typeConverterAttributes = cfg.GetCustomAttribute(property, cfg.TypeMappings.TypeConverterAttributes); @@ -55,7 +57,7 @@ public XamlXAstClrProperty(IXamlXLineInfo lineInfo, IXamlXProperty property, foreach (var attr in typeConverterAttributes) { var typeConverter = - XamlXTransformHelpers.TryGetTypeConverterFromCustomAttribute(cfg, attr); + XamlTransformHelpers.TryGetTypeConverterFromCustomAttribute(cfg, attr); if (typeConverter != null) { TypeConverters[property.PropertyType] = typeConverter; @@ -65,8 +67,8 @@ public XamlXAstClrProperty(IXamlXLineInfo lineInfo, IXamlXProperty property, } } - public XamlXAstClrProperty(IXamlXLineInfo lineInfo, string name, IXamlXType declaringType, - IXamlXMethod getter, IEnumerable setters) : base(lineInfo) + public XamlAstClrProperty(IXamlLineInfo lineInfo, string name, IXamlType declaringType, + IXamlMethod getter, IEnumerable setters) : base(lineInfo) { Name = name; DeclaringType = declaringType; @@ -75,9 +77,9 @@ public XamlXAstClrProperty(IXamlXLineInfo lineInfo, string name, IXamlXType decl Setters.AddRange(setters); } - public XamlXAstClrProperty(IXamlXLineInfo lineInfo, string name, IXamlXType declaringType, - IXamlXMethod getter, params IXamlXMethod[] setters) : this(lineInfo, name, declaringType, - getter, setters.Select(x => new XamlXDirectCallPropertySetter(x))) + public XamlAstClrProperty(IXamlLineInfo lineInfo, string name, IXamlType declaringType, + IXamlMethod getter, params IXamlMethod[] setters) : this(lineInfo, name, declaringType, + getter, setters.Select(x => new XamlDirectCallPropertySetter(x))) { } @@ -85,18 +87,18 @@ public XamlXAstClrProperty(IXamlXLineInfo lineInfo, string name, IXamlXType decl public override string ToString() => DeclaringType.GetFqn() + "." + Name; } - class XamlXDirectCallPropertySetter : IXamlXPropertySetter + class XamlDirectCallPropertySetter : IXamlPropertySetter, IXamlEmitablePropertySetter { - private readonly IXamlXMethod _method; - public IXamlXType TargetType { get; } + private readonly IXamlMethod _method; + public IXamlType TargetType { get; } public PropertySetterBinderParameters BinderParameters { get; } = new PropertySetterBinderParameters(); - public IReadOnlyList Parameters { get; } - public void Emit(IXamlXEmitter codegen) + public IReadOnlyList Parameters { get; } + public void Emit(IXamlILEmitter codegen) { codegen.EmitCall(_method, true); } - public XamlXDirectCallPropertySetter(IXamlXMethod method) + public XamlDirectCallPropertySetter(IXamlMethod method) { _method = method; Parameters = method.ParametersWithThis().Skip(1).ToList(); @@ -104,7 +106,7 @@ public XamlXDirectCallPropertySetter(IXamlXMethod method) } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif class PropertySetterBinderParameters @@ -114,29 +116,28 @@ class PropertySetterBinderParameters public bool AllowRuntimeNull { get; set; } = true; } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - interface IXamlXPropertySetter + interface IXamlPropertySetter { - IXamlXType TargetType { get; } + IXamlType TargetType { get; } PropertySetterBinderParameters BinderParameters { get; } - IReadOnlyList Parameters { get; } - void Emit(IXamlXEmitter codegen); + IReadOnlyList Parameters { get; } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXPropertyAssignmentNode : XamlXAstNode, IXamlXAstManipulationNode + class XamlPropertyAssignmentNode : XamlAstNode, IXamlAstManipulationNode { - public XamlXAstClrProperty Property { get; } - public List PossibleSetters { get; set; } - public List Values { get; set; } + public XamlAstClrProperty Property { get; } + public List PossibleSetters { get; set; } + public List Values { get; set; } - public XamlXPropertyAssignmentNode(IXamlXLineInfo lineInfo, - XamlXAstClrProperty property, - IEnumerable setters, IEnumerable values) + public XamlPropertyAssignmentNode(IXamlLineInfo lineInfo, + XamlAstClrProperty property, + IEnumerable setters, IEnumerable values) : base(lineInfo) { Property = property; @@ -150,15 +151,15 @@ public override void VisitChildren(Visitor visitor) } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXPropertyValueManipulationNode : XamlXAstNode, IXamlXAstManipulationNode + class XamlPropertyValueManipulationNode : XamlAstNode, IXamlAstManipulationNode { - public XamlXAstClrProperty Property { get; set; } - public IXamlXAstManipulationNode Manipulation { get; set; } - public XamlXPropertyValueManipulationNode(IXamlXLineInfo lineInfo, - XamlXAstClrProperty property, IXamlXAstManipulationNode manipulation) + public XamlAstClrProperty Property { get; set; } + public IXamlAstManipulationNode Manipulation { get; set; } + public XamlPropertyValueManipulationNode(IXamlLineInfo lineInfo, + XamlAstClrProperty property, IXamlAstManipulationNode manipulation) : base(lineInfo) { Property = property; @@ -167,23 +168,23 @@ public XamlXPropertyValueManipulationNode(IXamlXLineInfo lineInfo, public override void VisitChildren(Visitor visitor) { - Manipulation = (IXamlXAstManipulationNode) Manipulation.Visit(visitor); + Manipulation = (IXamlAstManipulationNode) Manipulation.Visit(visitor); } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - abstract class XamlXMethodCallBaseNode : XamlXAstNode + abstract class XamlMethodCallBaseNode : XamlAstNode { - public IXamlXWrappedMethod Method { get; set; } - public List Arguments { get; set; } - public XamlXMethodCallBaseNode(IXamlXLineInfo lineInfo, - IXamlXWrappedMethod method, IEnumerable args) + public IXamlWrappedMethod Method { get; set; } + public List Arguments { get; set; } + public XamlMethodCallBaseNode(IXamlLineInfo lineInfo, + IXamlWrappedMethod method, IEnumerable args) : base(lineInfo) { Method = method; - Arguments = args?.ToList() ?? new List(); + Arguments = args?.ToList() ?? new List(); } public override void VisitChildren(Visitor visitor) @@ -192,53 +193,53 @@ public override void VisitChildren(Visitor visitor) } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXNoReturnMethodCallNode : XamlXMethodCallBaseNode, IXamlXAstManipulationNode + class XamlNoReturnMethodCallNode : XamlMethodCallBaseNode, IXamlAstManipulationNode { - public XamlXNoReturnMethodCallNode(IXamlXLineInfo lineInfo, IXamlXMethod method, IEnumerable args) - : base(lineInfo, new XamlXWrappedMethod(method), args) + public XamlNoReturnMethodCallNode(IXamlLineInfo lineInfo, IXamlMethod method, IEnumerable args) + : base(lineInfo, new XamlWrappedMethod(method), args) { } - public XamlXNoReturnMethodCallNode(IXamlXLineInfo lineInfo, IXamlXWrappedMethod method, IEnumerable args) + public XamlNoReturnMethodCallNode(IXamlLineInfo lineInfo, IXamlWrappedMethod method, IEnumerable args) : base(lineInfo, method, args) { } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXStaticOrTargetedReturnMethodCallNode : XamlXMethodCallBaseNode, IXamlXAstValueNode + class XamlStaticOrTargetedReturnMethodCallNode : XamlMethodCallBaseNode, IXamlAstValueNode { - public XamlXStaticOrTargetedReturnMethodCallNode(IXamlXLineInfo lineInfo, IXamlXWrappedMethod method, - IEnumerable args) + public XamlStaticOrTargetedReturnMethodCallNode(IXamlLineInfo lineInfo, IXamlWrappedMethod method, + IEnumerable args) : base(lineInfo, method, args) { - Type = new XamlXAstClrTypeReference(lineInfo, method.ReturnType, false); + Type = new XamlAstClrTypeReference(lineInfo, method.ReturnType, false); } - public XamlXStaticOrTargetedReturnMethodCallNode(IXamlXLineInfo lineInfo, IXamlXMethod method, - IEnumerable args) - : this(lineInfo, new XamlXWrappedMethod(method), args) + public XamlStaticOrTargetedReturnMethodCallNode(IXamlLineInfo lineInfo, IXamlMethod method, + IEnumerable args) + : this(lineInfo, new XamlWrappedMethod(method), args) { } - public IXamlXAstTypeReference Type { get; } + public IXamlAstTypeReference Type { get; } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXManipulationGroupNode : XamlXAstNode, IXamlXAstManipulationNode + class XamlManipulationGroupNode : XamlAstNode, IXamlAstManipulationNode { - public List Children { get; set; } = new List(); + public List Children { get; set; } = new List(); - public XamlXManipulationGroupNode(IXamlXLineInfo lineInfo, - IEnumerable children = null) + public XamlManipulationGroupNode(IXamlLineInfo lineInfo, + IEnumerable children = null) : base(lineInfo) { if (children != null) @@ -248,35 +249,35 @@ public XamlXManipulationGroupNode(IXamlXLineInfo lineInfo, public override void VisitChildren(Visitor visitor) => VisitList(Children, visitor); } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - abstract class XamlXValueWithSideEffectNodeBase : XamlXAstNode, IXamlXAstValueNode + abstract class XamlValueWithSideEffectNodeBase : XamlAstNode, IXamlAstValueNode { - protected XamlXValueWithSideEffectNodeBase(IXamlXLineInfo lineInfo, IXamlXAstValueNode value) : base(lineInfo) + protected XamlValueWithSideEffectNodeBase(IXamlLineInfo lineInfo, IXamlAstValueNode value) : base(lineInfo) { Value = value; } - public IXamlXAstValueNode Value { get; set; } - public virtual IXamlXAstTypeReference Type => Value.Type; + public IXamlAstValueNode Value { get; set; } + public virtual IXamlAstTypeReference Type => Value.Type; public override void VisitChildren(Visitor visitor) { - Value = (IXamlXAstValueNode) Value.Visit(visitor); + Value = (IXamlAstValueNode) Value.Visit(visitor); } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXValueWithManipulationNode : XamlXValueWithSideEffectNodeBase + class XamlValueWithManipulationNode : XamlValueWithSideEffectNodeBase { - public IXamlXAstManipulationNode Manipulation { get; set; } + public IXamlAstManipulationNode Manipulation { get; set; } - public XamlXValueWithManipulationNode(IXamlXLineInfo lineInfo, - IXamlXAstValueNode value, - IXamlXAstManipulationNode manipulation) : base(lineInfo, value) + public XamlValueWithManipulationNode(IXamlLineInfo lineInfo, + IXamlAstValueNode value, + IXamlAstManipulationNode manipulation) : base(lineInfo, value) { Value = value; Manipulation = manipulation; @@ -285,70 +286,99 @@ public XamlXValueWithManipulationNode(IXamlXLineInfo lineInfo, public override void VisitChildren(Visitor visitor) { base.VisitChildren(visitor); - Manipulation = (IXamlXAstManipulationNode) Manipulation?.Visit(visitor); + Manipulation = (IXamlAstManipulationNode) Manipulation?.Visit(visitor); } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXAstNewClrObjectNode : XamlXAstNode, IXamlXAstValueNode + class XamlAstNewClrObjectNode : XamlAstNode, IXamlAstValueNode { - public XamlXAstNewClrObjectNode(IXamlXLineInfo lineInfo, - XamlXAstClrTypeReference type, IXamlXConstructor ctor, - List arguments) : base(lineInfo) + public XamlAstNewClrObjectNode(IXamlLineInfo lineInfo, + XamlAstClrTypeReference type, IXamlConstructor ctor, + List arguments) : base(lineInfo) { Type = type; Constructor = ctor; Arguments = arguments; } - public IXamlXAstTypeReference Type { get; set; } - public IXamlXConstructor Constructor { get; } - public List Arguments { get; set; } = new List(); + public IXamlAstTypeReference Type { get; set; } + public IXamlConstructor Constructor { get; } + public List Arguments { get; set; } = new List(); public override void VisitChildren(Visitor visitor) { - Type = (IXamlXAstTypeReference) Type.Visit(visitor); + Type = (IXamlAstTypeReference)Type.Visit(visitor); VisitList(Arguments, visitor); } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXMarkupExtensionNode : XamlXAstNode, IXamlXAstValueNode, IXamlXAstNodeNeedsParentStack + class XamlAstConstructableObjectNode : XamlAstNode, IXamlAstValueNode { - public IXamlXAstValueNode Value { get; set; } - public IXamlXMethod ProvideValue { get; } + public XamlAstConstructableObjectNode(IXamlLineInfo lineInfo, + XamlAstClrTypeReference type, IXamlConstructor ctor, + List arguments, + List children) : base(lineInfo) + { + Type = type; + Constructor = ctor; + Arguments = arguments; + Children = children; + } + + public IXamlAstTypeReference Type { get; set; } + public IXamlConstructor Constructor { get; } + public List Arguments { get; set; } = new List(); + public List Children { get; set; } = new List(); + + public override void VisitChildren(Visitor visitor) + { + Type = (IXamlAstTypeReference)Type.Visit(visitor); + VisitList(Arguments, visitor); + VisitList(Children, visitor); + } + } - public XamlXMarkupExtensionNode(IXamlXLineInfo lineInfo, IXamlXMethod provideValue, - IXamlXAstValueNode value) : base(lineInfo) +#if !XAMLX_INTERNAL + public +#endif + class XamlMarkupExtensionNode : XamlAstNode, IXamlAstValueNode, IXamlAstNodeNeedsParentStack + { + public IXamlAstValueNode Value { get; set; } + public IXamlMethod ProvideValue { get; } + + public XamlMarkupExtensionNode(IXamlLineInfo lineInfo, IXamlMethod provideValue, + IXamlAstValueNode value) : base(lineInfo) { ProvideValue = provideValue; Value = value; - Type = new XamlXAstClrTypeReference(this, ProvideValue.ReturnType, false); + Type = new XamlAstClrTypeReference(this, ProvideValue.ReturnType, false); } public override void VisitChildren(Visitor visitor) { - Value = (IXamlXAstValueNode) Value.Visit(visitor); + Value = (IXamlAstValueNode) Value.Visit(visitor); } public bool NeedsParentStack => ProvideValue?.Parameters.Count > 0; - public IXamlXAstTypeReference Type { get; } + public IXamlAstTypeReference Type { get; } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXObjectInitializationNode : XamlXAstNode, IXamlXAstManipulationNode + class XamlObjectInitializationNode : XamlAstNode, IXamlAstManipulationNode { - public IXamlXAstManipulationNode Manipulation { get; set; } - public IXamlXType Type { get; set; } + public IXamlAstManipulationNode Manipulation { get; set; } + public IXamlType Type { get; set; } public bool SkipBeginInit { get; set; } - public XamlXObjectInitializationNode(IXamlXLineInfo lineInfo, - IXamlXAstManipulationNode manipulation, IXamlXType type) + public XamlObjectInitializationNode(IXamlLineInfo lineInfo, + IXamlAstManipulationNode manipulation, IXamlType type) : base(lineInfo) { Manipulation = manipulation; @@ -357,47 +387,46 @@ public XamlXObjectInitializationNode(IXamlXLineInfo lineInfo, public override void VisitChildren(Visitor visitor) { - Manipulation = (IXamlXAstManipulationNode) Manipulation.Visit(visitor); + Manipulation = (IXamlAstManipulationNode) Manipulation.Visit(visitor); } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXToArrayNode : XamlXAstNode, IXamlXAstValueNode + class XamlToArrayNode : XamlAstNode, IXamlAstValueNode { - public IXamlXAstValueNode Value { get; set; } - public XamlXToArrayNode(IXamlXLineInfo lineInfo, IXamlXAstTypeReference arrayType, - IXamlXAstValueNode value) : base(lineInfo) + public IXamlAstValueNode Value { get; set; } + public XamlToArrayNode(IXamlLineInfo lineInfo, IXamlAstTypeReference arrayType, + IXamlAstValueNode value) : base(lineInfo) { Type = arrayType; Value = value; } - public IXamlXAstTypeReference Type { get; } + public IXamlAstTypeReference Type { get; } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - interface IXamlXWrappedMethod + interface IXamlWrappedMethod { string Name { get; } - IXamlXType ReturnType { get; } - IXamlXType DeclaringType { get; } - IReadOnlyList ParametersWithThis { get; } - void Emit(XamlXEmitContext context, IXamlXEmitter codeGen, bool swallowResult); + IXamlType ReturnType { get; } + IXamlType DeclaringType { get; } + IReadOnlyList ParametersWithThis { get; } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXWrappedMethod : IXamlXWrappedMethod + class XamlWrappedMethod : IXamlWrappedMethod, IXamlEmitableWrappedMethod { - private readonly IXamlXMethod _method; + private readonly IXamlMethod _method; - public XamlXWrappedMethod(IXamlXMethod method) + public XamlWrappedMethod(IXamlMethod method) { _method = method; ParametersWithThis = @@ -406,23 +435,23 @@ public XamlXWrappedMethod(IXamlXMethod method) } public string Name => _method.Name; - public IXamlXType ReturnType { get; } - public IXamlXType DeclaringType => _method.DeclaringType; - public IReadOnlyList ParametersWithThis { get; } - public void Emit(XamlXEmitContext context, IXamlXEmitter codeGen, bool swallowResult) + public IXamlType ReturnType { get; } + public IXamlType DeclaringType => _method.DeclaringType; + public IReadOnlyList ParametersWithThis { get; } + public void Emit(XamlEmitContext context, IXamlILEmitter codeGen, bool swallowResult) { codeGen.EmitCall(_method, swallowResult); } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXWrappedMethodWithCasts : IXamlXWrappedMethod + class XamlWrappedMethodWithCasts : IXamlWrappedMethod, IXamlEmitableWrappedMethodWithLocals { - private readonly IXamlXWrappedMethod _method; + private readonly IXamlWrappedMethod _method; - public XamlXWrappedMethodWithCasts(IXamlXWrappedMethod method, IEnumerable newArgumentTypes) + public XamlWrappedMethodWithCasts(IXamlWrappedMethod method, IEnumerable newArgumentTypes) { _method = method; ParametersWithThis = newArgumentTypes.ToList(); @@ -431,10 +460,10 @@ public XamlXWrappedMethodWithCasts(IXamlXWrappedMethod method, IEnumerable _method.Name; - public IXamlXType ReturnType => _method.ReturnType; - public IXamlXType DeclaringType => _method.DeclaringType; - public IReadOnlyList ParametersWithThis { get; } - public void Emit(XamlXEmitContext context, IXamlXEmitter codeGen, bool swallowResult) + public IXamlType ReturnType => _method.ReturnType; + public IXamlType DeclaringType => _method.DeclaringType; + public IReadOnlyList ParametersWithThis { get; } + public void Emit(XamlEmitContextWithLocals context, IXamlILEmitter codeGen, bool swallowResult) { int firstCast = -1; for (var c = ParametersWithThis.Count - 1; c >= 0; c--) @@ -445,13 +474,13 @@ public void Emit(XamlXEmitContext context, IXamlXEmitter codeGen, bool swallowRe if (firstCast != -1) { - var locals = new Stack(); + var locals = new Stack(); for (var c = ParametersWithThis.Count - 1; c >= firstCast; c--) { codeGen.Castclass(_method.ParametersWithThis[c]); if (c > firstCast) { - var l = context.GetLocal(_method.ParametersWithThis[c]); + var l = context.GetLocalOfType(_method.ParametersWithThis[c]); codeGen.Stloc(l.Local); locals.Push(l); } @@ -464,19 +493,19 @@ public void Emit(XamlXEmitContext context, IXamlXEmitter codeGen, bool swallowRe } } - _method.Emit(context, codeGen, swallowResult); + context.Emit(_method, codeGen, swallowResult); } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXMethodWithCasts : IXamlXCustomEmitMethod + class XamlMethodWithCasts : IXamlCustomEmitMethod { - private readonly IXamlXMethod _method; - private readonly IReadOnlyList _baseParametersWithThis; + private readonly IXamlMethod _method; + private readonly IReadOnlyList _baseParametersWithThis; - public XamlXMethodWithCasts(IXamlXMethod method, IEnumerable newArgumentTypes) + public XamlMethodWithCasts(IXamlMethod method, IEnumerable newArgumentTypes) { _method = method; Parameters = newArgumentTypes.ToList(); @@ -486,12 +515,12 @@ public XamlXMethodWithCasts(IXamlXMethod method, IEnumerable newArgu } public string Name => _method.Name; - public IXamlXType ReturnType => _method.ReturnType; - public IXamlXType DeclaringType => _method.DeclaringType; + public IXamlType ReturnType => _method.ReturnType; + public IXamlType DeclaringType => _method.DeclaringType; public bool IsPublic => true; public bool IsStatic => true; - public IReadOnlyList Parameters { get; } - public void EmitCall(IXamlXEmitter codeGen) + public IReadOnlyList Parameters { get; } + public void EmitCall(IXamlILEmitter codeGen) { int firstCast = -1; for (var c = Parameters.Count - 1; c >= 0; c--) @@ -502,7 +531,7 @@ public void EmitCall(IXamlXEmitter codeGen) if (firstCast != -1) { - var locals = new Stack(); + var locals = new Stack(); for (var c = Parameters.Count - 1; c >= firstCast; c--) { codeGen.Castclass(_baseParametersWithThis[c]); @@ -527,39 +556,39 @@ public void EmitCall(IXamlXEmitter codeGen) codeGen.EmitCall(_method); } - public bool Equals(IXamlXMethod other) => - other is XamlXMethodWithCasts mwc && mwc._method.Equals(_method) && + public bool Equals(IXamlMethod other) => + other is XamlMethodWithCasts mwc && mwc._method.Equals(_method) && mwc.Parameters.SequenceEqual(Parameters); - public IXamlXMethod MakeGenericMethod(IReadOnlyList typeArguments) + public IXamlMethod MakeGenericMethod(IReadOnlyList typeArguments) { throw new InvalidOperationException(); } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXDeferredContentNode : XamlXAstNode, IXamlXAstValueNode, IXamlXAstEmitableNode + class XamlDeferredContentNode : XamlAstNode, IXamlAstValueNode, IXamlAstEmitableNode { - public IXamlXAstValueNode Value { get; set; } - public IXamlXAstTypeReference Type { get; } + public IXamlAstValueNode Value { get; set; } + public IXamlAstTypeReference Type { get; } - public XamlXDeferredContentNode(IXamlXAstValueNode value, - XamlXTransformerConfiguration config) : base(value) + public XamlDeferredContentNode(IXamlAstValueNode value, + TransformerConfiguration config) : base(value) { Value = value; var funcType = config.TypeSystem.GetType("System.Func`2") .MakeGenericType(config.TypeMappings.ServiceProvider, config.WellKnownTypes.Object); - Type = new XamlXAstClrTypeReference(value, funcType, false); + Type = new XamlAstClrTypeReference(value, funcType, false); } public override void VisitChildren(Visitor visitor) { - Value = (IXamlXAstValueNode) Value.Visit(visitor); + Value = (IXamlAstValueNode) Value.Visit(visitor); } - void CompileBuilder(XamlXEmitContext context) + void CompileBuilder(ILEmitContext context) { var il = context.Emitter; // Initialize the context @@ -573,7 +602,7 @@ void CompileBuilder(XamlXEmitContext context) { // Attempt to get the root object from parent service provider var noRoot = il.DefineLabel(); - using (var loc = context.GetLocal(context.Configuration.WellKnownTypes.Object)) + using (var loc = context.GetLocalOfType(context.Configuration.WellKnownTypes.Object)) il // if(arg == null) goto noRoot; .Ldarg_0() @@ -605,19 +634,20 @@ void CompileBuilder(XamlXEmitContext context) il.Ret(); } - public XamlXNodeEmitResult Emit(XamlXEmitContext context, IXamlXEmitter codeGen) + public XamlILNodeEmitResult Emit(XamlEmitContext context, IXamlILEmitter codeGen) { var so = context.Configuration.WellKnownTypes.Object; var isp = context.Configuration.TypeMappings.ServiceProvider; - var subType = context.CreateSubType("XamlXClosure_" + Guid.NewGuid(), so); + var subType = context.CreateSubType("XamlClosure_" + Guid.NewGuid(), so); var buildMethod = subType.DefineMethod(so, new[] { isp }, "Build", true, true, false); - CompileBuilder(new XamlXEmitContext(buildMethod.Generator, context.Configuration, - context.RuntimeContext, buildMethod.Generator.DefineLocal(context.RuntimeContext.ContextType), - (s, type) => subType.DefineSubType(type, s, false), context.File, - context.EnableIlVerification, context.Emitters)); + CompileBuilder(new ILEmitContext(buildMethod.Generator, context.Configuration, + context.EmitMappings, runtimeContext: context.RuntimeContext, + contextLocal: buildMethod.Generator.DefineLocal(context.RuntimeContext.ContextType), + createSubType: (s, type) => subType.DefineSubType(type, s, false), file: context.File, + emitters: context.Emitters)); var funcType = Type.GetClrType(); codeGen @@ -635,29 +665,29 @@ public XamlXNodeEmitResult Emit(XamlXEmitContext context, IXamlXEmitter codeGen) } subType.CreateType(); - return XamlXNodeEmitResult.Type(0, funcType); + return XamlILNodeEmitResult.Type(0, funcType); } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXDeferredContentInitializeIntermediateRootNode - : XamlXAstNode, IXamlXAstValueNode, IXamlXAstEmitableNode + class XamlDeferredContentInitializeIntermediateRootNode + : XamlAstNode, IXamlAstValueNode, IXamlAstEmitableNode { - public IXamlXAstValueNode Value { get; set; } + public IXamlAstValueNode Value { get; set; } - public XamlXDeferredContentInitializeIntermediateRootNode(IXamlXAstValueNode value) : base(value) + public XamlDeferredContentInitializeIntermediateRootNode(IXamlAstValueNode value) : base(value) { Value = value; } - public override void VisitChildren(IXamlXAstVisitor visitor) + public override void VisitChildren(IXamlAstVisitor visitor) { - Value = (IXamlXAstValueNode) Value.Visit(visitor); + Value = (IXamlAstValueNode) Value.Visit(visitor); } - public IXamlXAstTypeReference Type => Value.Type; - public XamlXNodeEmitResult Emit(XamlXEmitContext context, IXamlXEmitter codeGen) + public IXamlAstTypeReference Type => Value.Type; + public XamlILNodeEmitResult Emit(XamlEmitContext context, IXamlILEmitter codeGen) { codeGen .Ldloc(context.ContextLocal); @@ -666,9 +696,7 @@ public XamlXNodeEmitResult Emit(XamlXEmitContext context, IXamlXEmitter codeGen) .Stfld(context.RuntimeContext.IntermediateRootObjectField) .Ldloc(context.ContextLocal) .Ldfld(context.RuntimeContext.IntermediateRootObjectField); - return XamlXNodeEmitResult.Type(0, Value.Type.GetClrType()); + return XamlILNodeEmitResult.Type(0, Value.Type.GetClrType()); } - - } } diff --git a/src/XamlX/Ast/Common.cs b/src/XamlX/Ast/Common.cs index 79b71873..7e580414 100644 --- a/src/XamlX/Ast/Common.cs +++ b/src/XamlX/Ast/Common.cs @@ -1,46 +1,46 @@ using System.Collections.Generic; using XamlX.TypeSystem; -using Visitor = XamlX.Ast.IXamlXAstVisitor; +using Visitor = XamlX.Ast.IXamlAstVisitor; namespace XamlX.Ast { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - interface IXamlXLineInfo + interface IXamlLineInfo { int Line { get; set; } int Position { get; set; } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - interface IXamlXAstVisitor + interface IXamlAstVisitor { - IXamlXAstNode Visit(IXamlXAstNode node); - void Push(IXamlXAstNode node); + IXamlAstNode Visit(IXamlAstNode node); + void Push(IXamlAstNode node); void Pop(); } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - interface IXamlXAstNode : IXamlXLineInfo + interface IXamlAstNode : IXamlLineInfo { void VisitChildren(Visitor visitor); - IXamlXAstNode Visit(Visitor visitor); + IXamlAstNode Visit(Visitor visitor); } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - abstract class XamlXAstNode : IXamlXAstNode + abstract class XamlAstNode : IXamlAstNode { public int Line { get; set; } public int Position { get; set; } - public XamlXAstNode(IXamlXLineInfo lineInfo) + public XamlAstNode(IXamlLineInfo lineInfo) { Line = lineInfo.Line; Position = lineInfo.Position; @@ -51,7 +51,7 @@ public virtual void VisitChildren(Visitor visitor) } - public IXamlXAstNode Visit(Visitor visitor) + public IXamlAstNode Visit(Visitor visitor) { var node = visitor.Visit(this); try @@ -67,7 +67,7 @@ public IXamlXAstNode Visit(Visitor visitor) return node; } - protected static void VisitList(IList list, Visitor visitor) where T : IXamlXAstNode + protected static void VisitList(IList list, Visitor visitor) where T : IXamlAstNode { for (var c = 0; c < list.Count; c++) { @@ -76,81 +76,81 @@ protected static void VisitList(IList list, Visitor visitor) where T : IXa } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - interface IXamlXAstManipulationNode : IXamlXAstNode + interface IXamlAstManipulationNode : IXamlAstNode { } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - interface IXamlXAstNodeNeedsParentStack + interface IXamlAstNodeNeedsParentStack { bool NeedsParentStack { get; } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - interface IXamlXAstImperativeNode : IXamlXAstNode + interface IXamlAstImperativeNode : IXamlAstNode { } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - interface IXamlXAstValueNode : IXamlXAstNode + interface IXamlAstValueNode : IXamlAstNode { - IXamlXAstTypeReference Type { get; } + IXamlAstTypeReference Type { get; } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - interface IXamlXAstTypeReference : IXamlXAstNode + interface IXamlAstTypeReference : IXamlAstNode { bool IsMarkupExtension { get; } - bool Equals(IXamlXAstTypeReference other); + bool Equals(IXamlAstTypeReference other); } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - interface IXamlXAstPropertyReference : IXamlXAstNode + interface IXamlAstPropertyReference : IXamlAstNode { } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - static class XamlXAstExtensions + static class XamlAstExtensions { - public static IXamlXType GetClrType(this IXamlXAstTypeReference r) + public static IXamlType GetClrType(this IXamlAstTypeReference r) { - if (r is XamlXAstClrTypeReference clr) + if (r is XamlAstClrTypeReference clr) return clr.Type; - throw new XamlXParseException($"Unable to convert {r} to CLR type", r); + throw new XamlParseException($"Unable to convert {r} to CLR type", r); } - public static XamlXAstClrTypeReference GetClrTypeReference(this IXamlXAstTypeReference r) + public static XamlAstClrTypeReference GetClrTypeReference(this IXamlAstTypeReference r) { - if (r is XamlXAstClrTypeReference clr) + if (r is XamlAstClrTypeReference clr) return clr; - throw new XamlXParseException($"Unable to convert {r} to CLR type", r); + throw new XamlParseException($"Unable to convert {r} to CLR type", r); } - public static XamlXAstClrProperty GetClrProperty(this IXamlXAstPropertyReference r) + public static XamlAstClrProperty GetClrProperty(this IXamlAstPropertyReference r) { - if (r is XamlXAstClrProperty clr) + if (r is XamlAstClrProperty clr) return clr; - throw new XamlXParseException($"Unable to convert {r} to CLR property", r); + throw new XamlParseException($"Unable to convert {r} to CLR property", r); } } } diff --git a/src/XamlX/Ast/CompilerHelpers.cs b/src/XamlX/Ast/CompilerHelpers.cs index b5e3a11a..f079a035 100644 --- a/src/XamlX/Ast/CompilerHelpers.cs +++ b/src/XamlX/Ast/CompilerHelpers.cs @@ -1,46 +1,50 @@ using System.Reflection.Emit; using XamlX.Transform; -using XamlX.Transform.Emitters; +using XamlX.IL.Emitters; using XamlX.TypeSystem; -using Visitor = XamlX.Ast.IXamlXAstVisitor; +using Visitor = XamlX.Ast.IXamlAstVisitor; +using XamlX.IL; +using XamlX.Emit; + namespace XamlX.Ast { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXAstCompilerLocalNode : XamlXAstNode, IXamlXAstValueNode, IXamlXAstEmitableNode + class XamlAstCompilerLocalNode : XamlAstNode, IXamlAstValueNode, IXamlAstLocalsEmitableNode { - private XamlXAstClrTypeReference _typeReference; - public IXamlXType Type { get; } - public XamlXAstCompilerLocalNode(IXamlXLineInfo lineInfo, XamlXAstClrTypeReference type) : base(lineInfo) + private XamlAstClrTypeReference _typeReference; + public IXamlType Type { get; } + public XamlAstCompilerLocalNode(IXamlLineInfo lineInfo, XamlAstClrTypeReference type) : base(lineInfo) { Type = type.Type; _typeReference = type; } - public XamlXAstCompilerLocalNode(IXamlXAstValueNode value) : this(value, value.Type.GetClrTypeReference()) + public XamlAstCompilerLocalNode(IXamlAstValueNode value) : this(value, value.Type.GetClrTypeReference()) { } - IXamlXAstTypeReference IXamlXAstValueNode.Type => _typeReference; - public XamlXNodeEmitResult Emit(XamlXEmitContext context, IXamlXEmitter codeGen) + IXamlAstTypeReference IXamlAstValueNode.Type => _typeReference; + public XamlILNodeEmitResult Emit(XamlEmitContextWithLocals context, IXamlILEmitter codeGen) { - context.LdLocal(this, codeGen); - return XamlXNodeEmitResult.Type(0, Type); + var lcl = context.GetLocalForNode(this, codeGen, throwOnUninitialized: true); + codeGen.Ldloc(lcl); + return XamlILNodeEmitResult.Type(0, Type); } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXAstLocalInitializationNodeEmitter : XamlXValueWithSideEffectNodeBase, IXamlXAstEmitableNode + class XamlAstLocalInitializationNodeEmitter : XamlValueWithSideEffectNodeBase, IXamlAstLocalsEmitableNode { - public XamlXAstCompilerLocalNode Local { get; set; } + public XamlAstCompilerLocalNode Local { get; set; } - public XamlXAstLocalInitializationNodeEmitter(IXamlXLineInfo lineInfo, - IXamlXAstValueNode value, - XamlXAstCompilerLocalNode local) : base(lineInfo, value) + public XamlAstLocalInitializationNodeEmitter(IXamlLineInfo lineInfo, + IXamlAstValueNode value, + XamlAstCompilerLocalNode local) : base(lineInfo, value) { Value = value; Local = local; @@ -49,28 +53,29 @@ public XamlXAstLocalInitializationNodeEmitter(IXamlXLineInfo lineInfo, public override void VisitChildren(Visitor visitor) { base.VisitChildren(visitor); - Local = (XamlXAstCompilerLocalNode) Local.Visit(visitor); + Local = (XamlAstCompilerLocalNode) Local.Visit(visitor); } - public XamlXNodeEmitResult Emit(XamlXEmitContext context, IXamlXEmitter codeGen) + public XamlILNodeEmitResult Emit(XamlEmitContextWithLocals context, IXamlILEmitter codeGen) { var rv = context.Emit(Value, codeGen, Local.Type); codeGen.Emit(OpCodes.Dup); - context.StLocal(Local, codeGen); - return XamlXNodeEmitResult.Type(0, rv.ReturnType); + var lcl = context.GetLocalForNode(Local, codeGen, throwOnUninitialized: false); + codeGen.Stloc(lcl); + return XamlILNodeEmitResult.Type(0, rv.ReturnType); } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXValueNodeWithBeginInit : XamlXValueWithSideEffectNodeBase, IXamlXAstEmitableNode + class XamlValueNodeWithBeginInit : XamlValueWithSideEffectNodeBase, IXamlAstEmitableNode { - public XamlXValueNodeWithBeginInit(IXamlXAstValueNode value) : base(value, value) + public XamlValueNodeWithBeginInit(IXamlAstValueNode value) : base(value, value) { } - public XamlXNodeEmitResult Emit(XamlXEmitContext context, IXamlXEmitter codeGen) + public XamlILNodeEmitResult Emit(XamlEmitContext context, IXamlILEmitter codeGen) { var res = context.Emit(Value, codeGen, Value.Type.GetClrType()); var supportInitType = context.Configuration.TypeMappings.SupportInitialize; @@ -88,43 +93,43 @@ public XamlXNodeEmitResult Emit(XamlXEmitContext context, IXamlXEmitter codeGen) } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXAstManipulationImperativeNode : XamlXAstNode, IXamlXAstManipulationNode, IXamlXAstEmitableNode + class XamlAstManipulationImperativeNode : XamlAstNode, IXamlAstManipulationNode, IXamlAstEmitableNode { - public IXamlXAstImperativeNode Imperative { get; set; } + public IXamlAstImperativeNode Imperative { get; set; } - public XamlXAstManipulationImperativeNode(IXamlXLineInfo lineInfo, IXamlXAstImperativeNode imperative) + public XamlAstManipulationImperativeNode(IXamlLineInfo lineInfo, IXamlAstImperativeNode imperative) : base(lineInfo) { Imperative = imperative; } - public XamlXNodeEmitResult Emit(XamlXEmitContext context, IXamlXEmitter codeGen) + public XamlILNodeEmitResult Emit(XamlEmitContext context, IXamlILEmitter codeGen) { // Discard the stack value we are "supposed" to manipulate codeGen.Pop(); context.Emit(Imperative, codeGen, null); - return XamlXNodeEmitResult.Void(1); + return XamlILNodeEmitResult.Void(1); } public override void VisitChildren(Visitor visitor) { - Imperative = (IXamlXAstImperativeNode)Imperative.Visit(visitor); + Imperative = (IXamlAstImperativeNode)Imperative.Visit(visitor); } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXAstImperativeValueManipulation : XamlXAstNode, IXamlXAstImperativeNode, IXamlXAstEmitableNode + class XamlAstImperativeValueManipulation : XamlAstNode, IXamlAstImperativeNode, IXamlAstEmitableNode { - public IXamlXAstValueNode Value { get; set; } - public IXamlXAstManipulationNode Manipulation { get; set; } + public IXamlAstValueNode Value { get; set; } + public IXamlAstManipulationNode Manipulation { get; set; } - public XamlXAstImperativeValueManipulation(IXamlXLineInfo lineInfo, - IXamlXAstValueNode value, IXamlXAstManipulationNode manipulation) : base(lineInfo) + public XamlAstImperativeValueManipulation(IXamlLineInfo lineInfo, + IXamlAstValueNode value, IXamlAstManipulationNode manipulation) : base(lineInfo) { Value = value; Manipulation = manipulation; @@ -132,56 +137,56 @@ public XamlXAstImperativeValueManipulation(IXamlXLineInfo lineInfo, public override void VisitChildren(Visitor visitor) { - Value = (XamlXAstCompilerLocalNode) Value.Visit(visitor); - Manipulation = (IXamlXAstManipulationNode) Manipulation.Visit(visitor); + Value = (XamlAstCompilerLocalNode) Value.Visit(visitor); + Manipulation = (IXamlAstManipulationNode) Manipulation.Visit(visitor); } - public XamlXNodeEmitResult Emit(XamlXEmitContext context, IXamlXEmitter codeGen) + public XamlILNodeEmitResult Emit(XamlEmitContext context, IXamlILEmitter codeGen) { context.Emit(Value, codeGen, Value.Type.GetClrType()); context.Emit(Manipulation, codeGen, null); - return XamlXNodeEmitResult.Void(0); + return XamlILNodeEmitResult.Void(0); } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXAstContextLocalNode : XamlXAstNode, IXamlXAstValueNode, IXamlXAstEmitableNode + class XamlAstContextLocalNode : XamlAstNode, IXamlAstValueNode, IXamlAstEmitableNode { - public XamlXAstContextLocalNode(IXamlXLineInfo lineInfo, IXamlXType type) : base(lineInfo) + public XamlAstContextLocalNode(IXamlLineInfo lineInfo, IXamlType type) : base(lineInfo) { - Type = new XamlXAstClrTypeReference(this, type, false); + Type = new XamlAstClrTypeReference(this, type, false); } - public IXamlXAstTypeReference Type { get; } - public XamlXNodeEmitResult Emit(XamlXEmitContext context, IXamlXEmitter codeGen) + public IXamlAstTypeReference Type { get; } + public XamlILNodeEmitResult Emit(XamlEmitContext context, IXamlILEmitter codeGen) { codeGen.Ldloc(context.ContextLocal); - return XamlXNodeEmitResult.Type(0, Type.GetClrType()); + return XamlILNodeEmitResult.Type(0, Type.GetClrType()); } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXAstRuntimeCastNode : XamlXAstNode, IXamlXAstValueNode, IXamlXAstEmitableNode + class XamlAstRuntimeCastNode : XamlAstNode, IXamlAstValueNode, IXamlAstEmitableNode { - public XamlXAstRuntimeCastNode(IXamlXLineInfo lineInfo, IXamlXAstValueNode value, IXamlXAstTypeReference castTo) : base(lineInfo) + public XamlAstRuntimeCastNode(IXamlLineInfo lineInfo, IXamlAstValueNode value, IXamlAstTypeReference castTo) : base(lineInfo) { Value = value; Type = castTo; } - public IXamlXAstValueNode Value { get; set; } - public IXamlXAstTypeReference Type { get; set; } + public IXamlAstValueNode Value { get; set; } + public IXamlAstTypeReference Type { get; set; } public override void VisitChildren(Visitor visitor) { - Value = (IXamlXAstValueNode) Value.Visit(visitor); - Type = (IXamlXAstTypeReference) Type.Visit(visitor); + Value = (IXamlAstValueNode) Value.Visit(visitor); + Type = (IXamlAstTypeReference) Type.Visit(visitor); } - public XamlXNodeEmitResult Emit(XamlXEmitContext context, IXamlXEmitter codeGen) + public XamlILNodeEmitResult Emit(XamlEmitContext context, IXamlILEmitter codeGen) { context.Emit(Value, codeGen, context.Configuration.WellKnownTypes.Object); var t = Type.GetClrType(); @@ -189,24 +194,24 @@ public XamlXNodeEmitResult Emit(XamlXEmitContext context, IXamlXEmitter codeGen) codeGen.Unbox_Any(t); else codeGen.Castclass(t); - return XamlXNodeEmitResult.Type(0, t); + return XamlILNodeEmitResult.Type(0, t); } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXAstNeedsParentStackValueNode : XamlXValueWithSideEffectNodeBase, - IXamlXAstEmitableNode, - IXamlXAstNodeNeedsParentStack + class XamlAstNeedsParentStackValueNode : XamlValueWithSideEffectNodeBase, + IXamlAstEmitableNode, + IXamlAstNodeNeedsParentStack { - public XamlXAstNeedsParentStackValueNode(IXamlXLineInfo lineInfo, IXamlXAstValueNode value) : base(lineInfo, value) + public XamlAstNeedsParentStackValueNode(IXamlLineInfo lineInfo, IXamlAstValueNode value) : base(lineInfo, value) { } - public XamlXNodeEmitResult Emit(XamlXEmitContext context, IXamlXEmitter codeGen) + public XamlILNodeEmitResult Emit(XamlEmitContext context, IXamlILEmitter codeGen) { - XamlXNeedsParentStackCache.Verify(context, this); + XamlNeedsParentStackCache.Verify(context, this); return context.Emit(Value, codeGen, Value.Type.GetClrType()); } diff --git a/src/XamlX/Ast/Intrinsics.cs b/src/XamlX/Ast/Intrinsics.cs index 11e5a168..bf0336cf 100644 --- a/src/XamlX/Ast/Intrinsics.cs +++ b/src/XamlX/Ast/Intrinsics.cs @@ -2,53 +2,55 @@ using System.Linq; using System.Reflection.Emit; using System.Runtime.Serialization; +using XamlX.Emit; +using XamlX.IL; using XamlX.Transform; using XamlX.TypeSystem; -using Visitor = XamlX.Ast.IXamlXAstVisitor; +using Visitor = XamlX.Ast.IXamlAstVisitor; namespace XamlX.Ast { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXNullExtensionNode : XamlXAstNode, IXamlXAstValueNode, IXamlXAstEmitableNode + class XamlNullExtensionNode : XamlAstNode, IXamlAstValueNode, IXamlAstEmitableNode { - public XamlXNullExtensionNode(IXamlXLineInfo lineInfo) : base(lineInfo) + public XamlNullExtensionNode(IXamlLineInfo lineInfo) : base(lineInfo) { - Type = new XamlXAstClrTypeReference(lineInfo, XamlXPseudoType.Null, false); + Type = new XamlAstClrTypeReference(lineInfo, XamlPseudoType.Null, false); } - public IXamlXAstTypeReference Type { get; } - public XamlXNodeEmitResult Emit(XamlXEmitContext context, IXamlXEmitter codeGen) + public IXamlAstTypeReference Type { get; } + public XamlILNodeEmitResult Emit(XamlEmitContext context, IXamlILEmitter codeGen) { codeGen.Emit(OpCodes.Ldnull); - return XamlXNodeEmitResult.Type(0, XamlXPseudoType.Null); + return XamlILNodeEmitResult.Type(0, XamlPseudoType.Null); } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXTypeExtensionNode : XamlXAstNode, IXamlXAstValueNode, IXamlXAstEmitableNode + class XamlTypeExtensionNode : XamlAstNode, IXamlAstValueNode, IXamlAstEmitableNode { - private readonly IXamlXType _systemType; + private readonly IXamlType _systemType; - public XamlXTypeExtensionNode(IXamlXLineInfo lineInfo, IXamlXAstTypeReference value, - IXamlXType systemType) : base(lineInfo) + public XamlTypeExtensionNode(IXamlLineInfo lineInfo, IXamlAstTypeReference value, + IXamlType systemType) : base(lineInfo) { _systemType = systemType; - Type = new XamlXAstClrTypeReference(this, systemType, false); + Type = new XamlAstClrTypeReference(this, systemType, false); Value = value; } - public IXamlXAstTypeReference Type { get; } - public IXamlXAstTypeReference Value { get; set; } + public IXamlAstTypeReference Type { get; } + public IXamlAstTypeReference Value { get; set; } public override void VisitChildren(Visitor visitor) { - Value = Value.Visit(visitor) as IXamlXAstTypeReference; + Value = Value.Visit(visitor) as IXamlAstTypeReference; } - public XamlXNodeEmitResult Emit(XamlXEmitContext context, IXamlXEmitter codeGen) + public XamlILNodeEmitResult Emit(XamlEmitContext context, IXamlILEmitter codeGen) { var type = Value.GetClrType(); var method = _systemType.Methods.FirstOrDefault(m => @@ -56,195 +58,195 @@ public XamlXNodeEmitResult Emit(XamlXEmitContext context, IXamlXEmitter codeGen) m.Parameters[0].Name == "RuntimeTypeHandle"); if (method == null) - throw new XamlXTypeSystemException( + throw new XamlTypeSystemException( $"Unable to find GetTypeFromHandle(RuntimeTypeHandle) on {_systemType.GetFqn()}"); codeGen .Emit(OpCodes.Ldtoken, type) .EmitCall(method); - return XamlXNodeEmitResult.Type(0, _systemType); + return XamlILNodeEmitResult.Type(0, _systemType); } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXStaticExtensionNode : XamlXAstNode, IXamlXAstValueNode, IXamlXAstEmitableNode + class XamlStaticExtensionNode : XamlAstNode, IXamlAstValueNode, IXamlAstEmitableNode { - public XamlXStaticExtensionNode(XamlXAstObjectNode lineInfo, IXamlXAstTypeReference targetType, string member) : base(lineInfo) + public XamlStaticExtensionNode(XamlAstObjectNode lineInfo, IXamlAstTypeReference targetType, string member) : base(lineInfo) { TargetType = targetType; Member = member; } public string Member { get; set; } - public IXamlXAstTypeReference TargetType { get; set; } + public IXamlAstTypeReference TargetType { get; set; } public override void VisitChildren(Visitor visitor) { - TargetType = (IXamlXAstTypeReference) TargetType.Visit(visitor); + TargetType = (IXamlAstTypeReference) TargetType.Visit(visitor); } - IXamlXMember ResolveMember(IXamlXType type) + IXamlMember ResolveMember(IXamlType type) { var rv = type.Fields.FirstOrDefault(f => f.IsPublic && f.IsStatic && f.Name == Member) ?? - (IXamlXMember) type.GetAllProperties().FirstOrDefault(p => + (IXamlMember) type.GetAllProperties().FirstOrDefault(p => p.Name == Member && p.Getter != null && p.Getter.IsPublic && p.Getter.IsStatic); if (rv == null) - throw new XamlXParseException( + throw new XamlParseException( $"Unable to resolve {Member} as static field, property, constant or enum value", this); return rv; } - public XamlXNodeEmitResult Emit(XamlXEmitContext context, IXamlXEmitter codeGen) + public XamlILNodeEmitResult Emit(XamlEmitContext context, IXamlILEmitter codeGen) { var type = TargetType.GetClrType(); var member = ResolveMember(type); - if (member is IXamlXProperty prop) + if (member is IXamlProperty prop) { codeGen.Emit(OpCodes.Call, prop.Getter); - return XamlXNodeEmitResult.Type(0, prop.Getter.ReturnType); + return XamlILNodeEmitResult.Type(0, prop.Getter.ReturnType); } - else if (member is IXamlXField field) + else if (member is IXamlField field) { if (field.IsLiteral) { - TypeSystemHelpers.EmitFieldLiteral(field, codeGen); + ILEmitHelpers.EmitFieldLiteral(field, codeGen); } else codeGen.Emit(OpCodes.Ldsfld, field); - return XamlXNodeEmitResult.Type(0, field.FieldType); + return XamlILNodeEmitResult.Type(0, field.FieldType); } else - throw new XamlXLoadException( + throw new XamlLoadException( $"Unable to resolve {Member} as static field, property, constant or enum value", this); } - IXamlXType ResolveReturnType() + IXamlType ResolveReturnType() { - if (!(TargetType is XamlXAstClrTypeReference type)) - return XamlXPseudoType.Unknown; + if (!(TargetType is XamlAstClrTypeReference type)) + return XamlPseudoType.Unknown; var member = ResolveMember(type.Type); - if (member is IXamlXField field) + if (member is IXamlField field) return field.FieldType; - if (member is IXamlXProperty prop && prop.Getter != null) + if (member is IXamlProperty prop && prop.Getter != null) return prop.Getter.ReturnType; - throw new XamlXParseException($"Unable to resolve {Member} as static field, property, constant or enum value", this); + throw new XamlParseException($"Unable to resolve {Member} as static field, property, constant or enum value", this); } - public IXamlXAstTypeReference Type => new XamlXAstClrTypeReference(this, ResolveReturnType(), false); + public IXamlAstTypeReference Type => new XamlAstClrTypeReference(this, ResolveReturnType(), false); } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXConstantNode : XamlXAstNode, IXamlXAstValueNode, IXamlXAstEmitableNode + class XamlConstantNode : XamlAstNode, IXamlAstValueNode, IXamlAstEmitableNode { public object Constant { get; } - public XamlXConstantNode(IXamlXLineInfo lineInfo, IXamlXType type, object constant) : base(lineInfo) + public XamlConstantNode(IXamlLineInfo lineInfo, IXamlType type, object constant) : base(lineInfo) { if (!constant.GetType().IsPrimitive) throw new ArgumentException($"Don't know how to emit {constant.GetType()} constant"); Constant = constant; - Type = new XamlXAstClrTypeReference(lineInfo, type, false); + Type = new XamlAstClrTypeReference(lineInfo, type, false); } - public IXamlXAstTypeReference Type { get; } - public XamlXNodeEmitResult Emit(XamlXEmitContext context, IXamlXEmitter codeGen) + public IXamlAstTypeReference Type { get; } + public XamlILNodeEmitResult Emit(XamlEmitContext context, IXamlILEmitter codeGen) { if (Constant is string) codeGen.Emit(OpCodes.Ldstr, (string) Constant); else if (Constant is long || Constant is ulong) - codeGen.Emit(OpCodes.Ldc_I8, TypeSystemHelpers.ConvertLiteralToLong(Constant)); + codeGen.Emit(OpCodes.Ldc_I8, TypeSystem.TypeSystemHelpers.ConvertLiteralToLong(Constant)); else if (Constant is float f) codeGen.Emit(OpCodes.Ldc_R4, f); else if (Constant is double d) codeGen.Emit(OpCodes.Ldc_R8, d); else - codeGen.Emit(OpCodes.Ldc_I4, TypeSystemHelpers.ConvertLiteralToInt(Constant)); - return XamlXNodeEmitResult.Type(0, Type.GetClrType()); + codeGen.Emit(OpCodes.Ldc_I4, TypeSystem.TypeSystemHelpers.ConvertLiteralToInt(Constant)); + return XamlILNodeEmitResult.Type(0, Type.GetClrType()); } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXRootObjectNode : XamlXAstNode, IXamlXAstValueNode, IXamlXAstEmitableNode + class XamlRootObjectNode : XamlAstNode, IXamlAstValueNode, IXamlAstEmitableNode { - public XamlXRootObjectNode(XamlXAstObjectNode root) : base(root) + public XamlRootObjectNode(XamlAstObjectNode root) : base(root) { Type = root.Type; } - public IXamlXAstTypeReference Type { get; set; } + public IXamlAstTypeReference Type { get; set; } - public XamlXNodeEmitResult Emit(XamlXEmitContext context, IXamlXEmitter codeGen) + public XamlILNodeEmitResult Emit(XamlEmitContext context, IXamlILEmitter codeGen) { codeGen .Ldloc(context.ContextLocal) .Ldfld(context.RuntimeContext.RootObjectField); - return XamlXNodeEmitResult.Type(0, Type.GetClrType()); + return XamlILNodeEmitResult.Type(0, Type.GetClrType()); } public override void VisitChildren(Visitor visitor) { - Type = (IXamlXAstTypeReference) Type.Visit(visitor); + Type = (IXamlAstTypeReference) Type.Visit(visitor); } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXIntermediateRootObjectNode : XamlXAstNode, IXamlXAstValueNode, IXamlXAstEmitableNode + class XamlIntermediateRootObjectNode : XamlAstNode, IXamlAstValueNode, IXamlAstEmitableNode { - public XamlXIntermediateRootObjectNode(IXamlXLineInfo lineInfo, XamlXTypeWellKnownTypes types) : base(lineInfo) + public XamlIntermediateRootObjectNode(IXamlLineInfo lineInfo, XamlTypeWellKnownTypes types) : base(lineInfo) { - Type = new XamlXAstClrTypeReference(lineInfo, types.Object, false); + Type = new XamlAstClrTypeReference(lineInfo, types.Object, false); } - public IXamlXAstTypeReference Type { get; set; } + public IXamlAstTypeReference Type { get; set; } - public XamlXNodeEmitResult Emit(XamlXEmitContext context, IXamlXEmitter codeGen) + public XamlILNodeEmitResult Emit(XamlEmitContext context, IXamlILEmitter codeGen) { codeGen .Ldloc(context.ContextLocal) .Ldfld(context.RuntimeContext.IntermediateRootObjectField); - return XamlXNodeEmitResult.Type(0, Type.GetClrType()); + return XamlILNodeEmitResult.Type(0, Type.GetClrType()); } public override void VisitChildren(Visitor visitor) { - Type = (IXamlXAstTypeReference) Type.Visit(visitor); + Type = (IXamlAstTypeReference) Type.Visit(visitor); } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXLoadMethodDelegateNode : XamlXValueWithSideEffectNodeBase, - IXamlXAstEmitableNode + class XamlLoadMethodDelegateNode : XamlValueWithSideEffectNodeBase, + IXamlAstEmitableNode { - public IXamlXType DelegateType { get; } - public IXamlXMethod Method { get; } + public IXamlType DelegateType { get; } + public IXamlMethod Method { get; } - public XamlXLoadMethodDelegateNode(IXamlXLineInfo lineInfo, IXamlXAstValueNode value, - IXamlXType delegateType, IXamlXMethod method) : base(lineInfo, value) + public XamlLoadMethodDelegateNode(IXamlLineInfo lineInfo, IXamlAstValueNode value, + IXamlType delegateType, IXamlMethod method) : base(lineInfo, value) { DelegateType = delegateType; Method = method; - Type = new XamlXAstClrTypeReference(value, DelegateType, false); + Type = new XamlAstClrTypeReference(value, DelegateType, false); } - public override IXamlXAstTypeReference Type { get; } - public XamlXNodeEmitResult Emit(XamlXEmitContext context, IXamlXEmitter codeGen) + public override IXamlAstTypeReference Type { get; } + public XamlILNodeEmitResult Emit(XamlEmitContext context, IXamlILEmitter codeGen) { context.Emit(Value, codeGen, Method.DeclaringType); codeGen .Ldftn(Method) .Newobj(DelegateType.Constructors.FirstOrDefault(ct => ct.Parameters.Count == 2 && ct.Parameters[0].Equals(context.Configuration.WellKnownTypes.Object))); - return XamlXNodeEmitResult.Type(0, DelegateType); + return XamlILNodeEmitResult.Type(0, DelegateType); } } } diff --git a/src/XamlX/Ast/Xaml.cs b/src/XamlX/Ast/Xaml.cs index 0b0c64e7..5bb02f49 100644 --- a/src/XamlX/Ast/Xaml.cs +++ b/src/XamlX/Ast/Xaml.cs @@ -1,21 +1,21 @@ using System.Collections.Generic; using System.Linq; using XamlX.TypeSystem; -using Visitor = XamlX.Ast.IXamlXAstVisitor; +using Visitor = XamlX.Ast.IXamlAstVisitor; namespace XamlX.Ast { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXAstXmlDirective : XamlXAstNode, IXamlXAstManipulationNode + class XamlAstXmlDirective : XamlAstNode, IXamlAstManipulationNode { public string Namespace { get; set; } public string Name { get; set; } - public List Values { get; set; } + public List Values { get; set; } - public XamlXAstXmlDirective(IXamlXLineInfo lineInfo, - string ns, string name, IEnumerable values) : base(lineInfo) + public XamlAstXmlDirective(IXamlLineInfo lineInfo, + string ns, string name, IEnumerable values) : base(lineInfo) { Namespace = ns; Name = name; @@ -28,23 +28,23 @@ public override void VisitChildren(Visitor visitor) } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXAstXamlPropertyValueNode : XamlXAstNode, IXamlXAstManipulationNode + class XamlAstXamlPropertyValueNode : XamlAstNode, IXamlAstManipulationNode { - public IXamlXAstPropertyReference Property { get; set; } - public List Values { get; set; } + public IXamlAstPropertyReference Property { get; set; } + public List Values { get; set; } - public XamlXAstXamlPropertyValueNode(IXamlXLineInfo lineInfo, - IXamlXAstPropertyReference property, IXamlXAstValueNode value) : base(lineInfo) + public XamlAstXamlPropertyValueNode(IXamlLineInfo lineInfo, + IXamlAstPropertyReference property, IXamlAstValueNode value) : base(lineInfo) { Property = property; - Values = new List {value}; + Values = new List {value}; } - public XamlXAstXamlPropertyValueNode(IXamlXLineInfo lineInfo, - IXamlXAstPropertyReference property, IEnumerable values) : base(lineInfo) + public XamlAstXamlPropertyValueNode(IXamlLineInfo lineInfo, + IXamlAstPropertyReference property, IEnumerable values) : base(lineInfo) { Property = property; Values = values.ToList(); @@ -52,28 +52,28 @@ public XamlXAstXamlPropertyValueNode(IXamlXLineInfo lineInfo, public override void VisitChildren(Visitor visitor) { - Property = (IXamlXAstPropertyReference) Property.Visit(visitor); + Property = (IXamlAstPropertyReference) Property.Visit(visitor); VisitList(Values, visitor); } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXAstObjectNode : XamlXAstNode, IXamlXAstValueNode + class XamlAstObjectNode : XamlAstNode, IXamlAstValueNode { - public XamlXAstObjectNode(IXamlXLineInfo lineInfo, IXamlXAstTypeReference type) : base(lineInfo) + public XamlAstObjectNode(IXamlLineInfo lineInfo, IXamlAstTypeReference type) : base(lineInfo) { Type = type; } - public IXamlXAstTypeReference Type { get; set; } - public List Children { get; set; } = new List(); - public List Arguments { get; set; } = new List(); + public IXamlAstTypeReference Type { get; set; } + public List Children { get; set; } = new List(); + public List Arguments { get; set; } = new List(); public override void VisitChildren(Visitor visitor) { - Type = (IXamlXAstTypeReference) Type.Visit(visitor); + Type = (IXamlAstTypeReference) Type.Visit(visitor); VisitList(Arguments, visitor); VisitList(Children, visitor); } @@ -81,41 +81,41 @@ public override void VisitChildren(Visitor visitor) -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXAstTextNode : XamlXAstNode, IXamlXAstValueNode + class XamlAstTextNode : XamlAstNode, IXamlAstValueNode { public string Text { get; set; } - public XamlXAstTextNode(IXamlXLineInfo lineInfo, string text, IXamlXType type = null) : base(lineInfo) + public XamlAstTextNode(IXamlLineInfo lineInfo, string text, IXamlType type = null) : base(lineInfo) { Text = text; if (type != null) - Type = new XamlXAstClrTypeReference(lineInfo, type, false); + Type = new XamlAstClrTypeReference(lineInfo, type, false); else - Type = new XamlXAstXmlTypeReference(lineInfo, XamlNamespaces.Xaml2006, "String"); + Type = new XamlAstXmlTypeReference(lineInfo, XamlNamespaces.Xaml2006, "String"); } public override void VisitChildren(Visitor visitor) { - Type = (IXamlXAstTypeReference) Type.Visit(visitor); + Type = (IXamlAstTypeReference) Type.Visit(visitor); } - public IXamlXAstTypeReference Type { get; set; } + public IXamlAstTypeReference Type { get; set; } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXAstNamePropertyReference : XamlXAstNode, IXamlXAstPropertyReference + class XamlAstNamePropertyReference : XamlAstNode, IXamlAstPropertyReference { - public IXamlXAstTypeReference DeclaringType { get; set; } + public IXamlAstTypeReference DeclaringType { get; set; } public string Name { get; set; } - public IXamlXAstTypeReference TargetType { get; set; } + public IXamlAstTypeReference TargetType { get; set; } - public XamlXAstNamePropertyReference(IXamlXLineInfo lineInfo, - IXamlXAstTypeReference declaringType, string name, IXamlXAstTypeReference targetType) : base(lineInfo) + public XamlAstNamePropertyReference(IXamlLineInfo lineInfo, + IXamlAstTypeReference declaringType, string name, IXamlAstTypeReference targetType) : base(lineInfo) { DeclaringType = declaringType; Name = name; @@ -124,8 +124,8 @@ public XamlXAstNamePropertyReference(IXamlXLineInfo lineInfo, public override void VisitChildren(Visitor visitor) { - DeclaringType = (IXamlXAstTypeReference) DeclaringType.Visit(visitor); - TargetType = (IXamlXAstTypeReference) TargetType.Visit(visitor); + DeclaringType = (IXamlAstTypeReference) DeclaringType.Visit(visitor); + TargetType = (IXamlAstTypeReference) TargetType.Visit(visitor); } } } diff --git a/src/XamlX/Ast/XamlXDocument.cs b/src/XamlX/Ast/XamlDocument.cs similarity index 68% rename from src/XamlX/Ast/XamlXDocument.cs rename to src/XamlX/Ast/XamlDocument.cs index ef7c4e40..39216ffe 100644 --- a/src/XamlX/Ast/XamlXDocument.cs +++ b/src/XamlX/Ast/XamlDocument.cs @@ -2,12 +2,12 @@ namespace XamlX.Ast { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXDocument + class XamlDocument { - public IXamlXAstNode Root { get; set; } + public IXamlAstNode Root { get; set; } public Dictionary NamespaceAliases { get; set; } = new Dictionary(); } } diff --git a/src/XamlX/Ast/Xml.cs b/src/XamlX/Ast/Xml.cs index a8891905..624d347d 100644 --- a/src/XamlX/Ast/Xml.cs +++ b/src/XamlX/Ast/Xml.cs @@ -1,26 +1,26 @@ using System.Collections.Generic; using System.Linq; -using Visitor = XamlX.Ast.IXamlXAstVisitor; +using Visitor = XamlX.Ast.IXamlAstVisitor; namespace XamlX.Ast { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXAstXmlTypeReference : XamlXAstNode, IXamlXAstTypeReference + class XamlAstXmlTypeReference : XamlAstNode, IXamlAstTypeReference { public string XmlNamespace { get; set; } public string Name { get; set; } public bool IsMarkupExtension { get; set; } - public bool Equals(IXamlXAstTypeReference other) => - other is XamlXAstXmlTypeReference xml + public bool Equals(IXamlAstTypeReference other) => + other is XamlAstXmlTypeReference xml && xml.Name == Name && xml.XmlNamespace == XmlNamespace && xml.IsMarkupExtension == IsMarkupExtension; - public List GenericArguments { get; set; } = new List(); + public List GenericArguments { get; set; } = new List(); - public XamlXAstXmlTypeReference(IXamlXLineInfo lineInfo, string xmlNamespace, string name, - IEnumerable genericArguments = null) : base(lineInfo) + public XamlAstXmlTypeReference(IXamlLineInfo lineInfo, string xmlNamespace, string name, + IEnumerable genericArguments = null) : base(lineInfo) { XmlNamespace = xmlNamespace; Name = name; diff --git a/src/XamlX/Compiler/XamlCompiler.cs b/src/XamlX/Compiler/XamlCompiler.cs new file mode 100644 index 00000000..3f4ca1d9 --- /dev/null +++ b/src/XamlX/Compiler/XamlCompiler.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; +using System.Reflection.Emit; +using XamlX.Ast; +using XamlX.Emit; +using XamlX.Transform; +using XamlX.Transform.Transformers; +using XamlX.TypeSystem; + +namespace XamlX.Compiler +{ +#if !XAMLX_INTERNAL + public +#endif + abstract class XamlCompiler + where TEmitResult : IXamlEmitResult + { + protected readonly TransformerConfiguration _configuration; + protected readonly XamlLanguageEmitMappings _emitMappings; + + public List Transformers { get; } = new List(); + public List SimplificationTransformers { get; } = new List(); + + public List Emitters { get; } = new List(); + + public XamlCompiler(TransformerConfiguration configuration, + XamlLanguageEmitMappings emitMappings, + bool fillWithDefaults) + { + _configuration = configuration; + _emitMappings = emitMappings; + if (fillWithDefaults) + { + Transformers = new List + { + new KnownDirectivesTransformer(), + new XamlIntrinsicsTransformer(), + new XArgumentsTransformer(), + new TypeReferenceResolver(), + new MarkupExtensionTransformer(), + new PropertyReferenceResolver(), + new ContentConvertTransformer(), + new ResolveContentPropertyTransformer(), + new ResolvePropertyValueAddersTransformer(), + new ConvertPropertyValuesToAssignmentsTransformer(), + new ConstructableObjectTransformer() + }; + SimplificationTransformers = new List + { + new FlattenAstTransformer() + }; + } + } + + public AstTransformationContext CreateTransformationContext(XamlDocument doc, bool strict) + => new AstTransformationContext(_configuration, doc.NamespaceAliases, strict); + + public void Transform(XamlDocument doc, bool strict = true) + { + var ctx = CreateTransformationContext(doc, strict); + + var root = doc.Root; + ctx.RootObject = new XamlRootObjectNode((XamlAstObjectNode)root); + foreach (var transformer in Transformers) + { + ctx.VisitChildren(ctx.RootObject, transformer); + root = ctx.Visit(root, transformer); + } + + foreach (var simplifier in SimplificationTransformers) + root = ctx.Visit(root, simplifier); + + doc.Root = root; + } + + protected abstract XamlEmitContext InitCodeGen( + IFileSource file, + Func> createSubType, + TBackendEmitter codeGen, XamlRuntimeContext context, bool needContextLocal); + } +} diff --git a/src/XamlX/Compiler/XamlImperativeCompiler.cs b/src/XamlX/Compiler/XamlImperativeCompiler.cs new file mode 100644 index 00000000..c42e4f42 --- /dev/null +++ b/src/XamlX/Compiler/XamlImperativeCompiler.cs @@ -0,0 +1,110 @@ +using System; +using System.Collections.Generic; +using System.Text; +using XamlX.Ast; +using XamlX.Emit; +using XamlX.Transform; +using XamlX.Transform.Transformers; +using XamlX.TypeSystem; + +namespace XamlX.Compiler +{ +#if !XAMLX_INTERNAL + public +#endif + abstract class XamlImperativeCompiler : XamlCompiler + where TEmitResult : IXamlEmitResult + { + public XamlImperativeCompiler(TransformerConfiguration configuration, + XamlLanguageEmitMappings emitMappings, bool fillWithDefaults) + : base(configuration, emitMappings, fillWithDefaults) + { + if (fillWithDefaults) + { + Transformers.AddRange(new IXamlAstTransformer[] + { + new NewObjectTransformer(), + new DeferredContentTransformer(), + new TopDownInitializationTransformer(), + }); + } + } + + /// + /// void Populate(IServiceProvider sp, T target); + /// + public IXamlMethodBuilder DefinePopulateMethod(IXamlTypeBuilder typeBuilder, + XamlDocument doc, + string name, bool isPublic) + { + var rootGrp = (XamlValueWithManipulationNode)doc.Root; + return typeBuilder.DefineMethod(_configuration.WellKnownTypes.Void, + new[] { _configuration.TypeMappings.ServiceProvider, rootGrp.Type.GetClrType() }, + name, isPublic, true, false); + } + + /// + /// T Build(IServiceProvider sp); + /// + public IXamlMethodBuilder DefineBuildMethod(IXamlTypeBuilder typeBuilder, + XamlDocument doc, + string name, bool isPublic) + { + var rootGrp = (XamlValueWithManipulationNode)doc.Root; + return typeBuilder.DefineMethod(rootGrp.Type.GetClrType(), + new[] { _configuration.TypeMappings.ServiceProvider }, name, isPublic, true, false); + } + + public void Compile(XamlDocument doc, IXamlTypeBuilder typeBuilder, IXamlType contextType, + string populateMethodName, string createMethodName, string namespaceInfoClassName, + string baseUri, IFileSource fileSource) + { + var rootGrp = (XamlValueWithManipulationNode)doc.Root; + Compile(doc, contextType, + DefinePopulateMethod(typeBuilder, doc, populateMethodName, true), + createMethodName == null ? + null : + DefineBuildMethod(typeBuilder, doc, createMethodName, true), + _configuration.TypeMappings.XmlNamespaceInfoProvider == null ? + null : + typeBuilder.DefineSubType(_configuration.WellKnownTypes.Object, + namespaceInfoClassName, false), + (name, bt) => typeBuilder.DefineSubType(bt, name, false), + baseUri, fileSource); + } + + public void Compile(XamlDocument doc, IXamlType contextType, + IXamlMethodBuilder populateMethod, IXamlMethodBuilder buildMethod, + IXamlTypeBuilder namespaceInfoBuilder, + Func> createClosure, + string baseUri, IFileSource fileSource) + { + var rootGrp = (XamlValueWithManipulationNode)doc.Root; + var rootType = rootGrp.Type.GetClrType(); + var context = CreateRuntimeContext(doc, contextType, namespaceInfoBuilder, baseUri, rootType); + + CompilePopulate(fileSource, rootGrp.Manipulation, createClosure, populateMethod.Generator, context); + + if (buildMethod != null) + { + CompileBuild(fileSource, rootGrp.Value, null, buildMethod.Generator, context, populateMethod); + } + + namespaceInfoBuilder?.CreateType(); + } + + protected abstract void CompilePopulate(IFileSource fileSource, IXamlAstManipulationNode manipulation, + Func> createSubType, + TBackendEmitter codeGen, XamlRuntimeContext context); + + protected abstract void CompileBuild( + IFileSource fileSource, + IXamlAstValueNode rootInstance, Func> createSubType, + TBackendEmitter codeGen, XamlRuntimeContext context, + IXamlMethod compiledPopulate); + + protected abstract XamlRuntimeContext CreateRuntimeContext( + XamlDocument doc, IXamlType contextType, + IXamlTypeBuilder namespaceInfoBuilder, string baseUri, IXamlType rootType); + } +} diff --git a/src/XamlX/Emit/XamlEmitContext.cs b/src/XamlX/Emit/XamlEmitContext.cs new file mode 100644 index 00000000..f90c7679 --- /dev/null +++ b/src/XamlX/Emit/XamlEmitContext.cs @@ -0,0 +1,285 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Xml; +using XamlX.Ast; +using XamlX.Transform; +using XamlX.TypeSystem; + +namespace XamlX.Emit +{ +#if !XAMLX_INTERNAL + public +#endif + abstract class XamlEmitContext : XamlContextBase + where TEmitResult : IXamlEmitResult + { + public IFileSource File { get; } + public List Emitters { get; } + + private IXamlAstNode _currentNode; + + public TransformerConfiguration Configuration { get; } + public XamlLanguageEmitMappings EmitMappings { get; } + public XamlRuntimeContext RuntimeContext { get; } + public IXamlLocal ContextLocal { get; } + public Func> CreateSubType { get; } + public TBackendEmitter Emitter { get; } + + public XamlEmitContext(TBackendEmitter emitter, TransformerConfiguration configuration, + XamlLanguageEmitMappings emitMappings, + XamlRuntimeContext runtimeContext, + IXamlLocal contextLocal, + Func> createSubType, IFileSource file, + IEnumerable emitters) + { + File = file; + Emitter = emitter; + Emitters = emitters.ToList(); + Configuration = configuration; + RuntimeContext = runtimeContext; + ContextLocal = contextLocal; + CreateSubType = createSubType; + EmitMappings = emitMappings; + } + + public TEmitResult Emit(IXamlAstNode value, TBackendEmitter codeGen, IXamlType expectedType) + { + TEmitResult res; + if (_currentNode != null) + { + PushParent(_currentNode); + _currentNode = value; + res = EmitCore(value, codeGen, expectedType); + _currentNode = PopParent(); + } + else + { + _currentNode = value; + res = EmitCore(value, codeGen, expectedType); + _currentNode = null; + } + + return res; + } + + public void Emit(IXamlPropertySetter setter, TBackendEmitter codeGen) + { + bool foundEmitter = EmitCore(setter, codeGen); + + if (!foundEmitter) + { + throw new InvalidOperationException("Unable to find emitter for property setter type: " + setter.GetType().ToString()); + } + } + + protected virtual bool EmitCore(IXamlPropertySetter setter, TBackendEmitter codeGen) + { + bool foundEmitter = false; + foreach (var e in Emitters) + { + if (e is IXamlPropertySetterEmitter pse) + { + foundEmitter = pse.EmitCall(setter, codeGen); + if (foundEmitter) + { + break; + } + } + } + + if (!foundEmitter) + { + if (setter is IXamlEmitablePropertySetter eps) + { + foundEmitter = true; + eps.Emit(codeGen); + } + } + + return foundEmitter; + } + + public void Emit(IXamlWrappedMethod wrapped, TBackendEmitter codeGen, bool swallowResult) + { + bool foundEmitter = EmitCore(wrapped, codeGen, swallowResult); + + if (!foundEmitter) + { + throw new InvalidOperationException("Unable to find emitter for wrapped method type: " + wrapped.GetType().ToString()); + } + } + + protected virtual bool EmitCore(IXamlWrappedMethod wrapped, TBackendEmitter codeGen, bool swallowResult) + { + bool foundEmitter = false; + foreach (var e in Emitters) + { + if (e is IXamlWrappedMethodEmitter wme) + { + foundEmitter = wme.EmitCall(this, wrapped, codeGen, swallowResult); + if (foundEmitter) + { + break; + } + } + } + + if (!foundEmitter) + { + if (wrapped is IXamlEmitableWrappedMethod ewm) + { + foundEmitter = true; + ewm.Emit(this, codeGen, swallowResult); + } + } + + return foundEmitter; + } + + private TEmitResult EmitCore(IXamlAstNode value, TBackendEmitter codeGen, IXamlType expectedType) + { + TEmitResult res = EmitNode(value, codeGen); + IXamlType returnedType = res.ReturnType; + + if (returnedType != null || expectedType != null) + { + if (returnedType != null && expectedType == null) + throw new XamlLoadException( + $"Emit of node {value} resulted in {returnedType.GetFqn()} while caller expected void", value); + + if (expectedType != null && returnedType == null) + throw new XamlLoadException( + $"Emit of node {value} resulted in void while caller expected {expectedType.GetFqn()}", value); + + if (!returnedType.Equals(expectedType)) + { + EmitConvert(value, codeGen, expectedType, returnedType); + } + } + + return res; + } + + protected virtual TEmitResult EmitNode(IXamlAstNode value, TBackendEmitter codeGen) + { +#if XAMLX_DEBUG + var res = EmitNodeCore(value, codeGen); +#else + TEmitResult res; + try + { + res = EmitNodeCore(value, codeGen, out var foundEmitter); + + if (!foundEmitter) + { + throw new XamlLoadException("Unable to find emitter for node type: " + value.GetType().FullName, value); + } + } + catch (Exception e) when (!(e is XmlException)) + { + throw new XamlLoadException( + "Internal compiler error while emitting node " + value + ":\n" + e, value); + } +#endif + return res; + } + + protected abstract void EmitConvert(IXamlAstNode value, TBackendEmitter codeGen, IXamlType expectedType, IXamlType returnedType); + + protected virtual TEmitResult EmitNodeCore(IXamlAstNode value, TBackendEmitter codeGen, out bool foundEmitter) + { + TEmitResult res = default; + foreach (var e in Emitters) + { + if (e is IXamlAstNodeEmitter ve) + { + res = ve.Emit(value, this, codeGen); + if (res != default) + { + foundEmitter = true; + return res; + } + } + } + + if (value is IXamlAstEmitableNode en) + { + foundEmitter = true; + return en.Emit(this, codeGen); + } + + foundEmitter = false; + return res; + } + } + +#if !XAMLX_INTERNAL + public +#endif + interface IXamlEmitResult + { + IXamlType ReturnType { get; } + } + +#if !XAMLX_INTERNAL + public +#endif + interface IXamlAstNodeEmitter + where TEmitResult : IXamlEmitResult + { + TEmitResult Emit(IXamlAstNode node, XamlEmitContext context, TBackendEmitter codeGen); + } + +#if !XAMLX_INTERNAL + public +#endif + interface IXamlAstEmitableNode + where TEmitResult : IXamlEmitResult + { + TEmitResult Emit(XamlEmitContext context, TBackendEmitter codeGen); + } +#if !XAMLX_INTERNAL + public +#endif + interface IXamlCustomEmitMethod : IXamlMethod + { + void EmitCall(TBackendEmitter emitter); + } + +#if !XAMLX_INTERNAL + public +#endif + interface IXamlPropertySetterEmitter + { + bool EmitCall(IXamlPropertySetter setter, TBackendEmitter emitter); + } + +#if !XAMLX_INTERNAL + public +#endif + interface IXamlEmitablePropertySetter : IXamlPropertySetter + { + void Emit(TBackendEmitter emitter); + } + +#if !XAMLX_INTERNAL + public +#endif + interface IXamlWrappedMethodEmitter + where TEmitResult : IXamlEmitResult + { + bool EmitCall(XamlEmitContext context, IXamlWrappedMethod method, TBackendEmitter emitter, bool swallowResult); + } + + +#if !XAMLX_INTERNAL + public +#endif + interface IXamlEmitableWrappedMethod : IXamlWrappedMethod + where TEmitResult: IXamlEmitResult + { + void Emit(XamlEmitContext context, TBackendEmitter emitter, bool swallowResult); + } +} diff --git a/src/XamlX/Emit/XamlEmitContextWithLocals.cs b/src/XamlX/Emit/XamlEmitContextWithLocals.cs new file mode 100644 index 00000000..4cf3ce65 --- /dev/null +++ b/src/XamlX/Emit/XamlEmitContextWithLocals.cs @@ -0,0 +1,166 @@ +using System; +using System.Collections.Generic; +using System.Text; +using XamlX.Ast; +using XamlX.Transform; +using XamlX.TypeSystem; + +namespace XamlX.Emit +{ +#if !XAMLX_INTERNAL + public +#endif + abstract class XamlEmitContextWithLocals : XamlEmitContext + where TBackendEmitter : IHasLocalsPool + where TEmitResult : IXamlEmitResult + { + private readonly Dictionary + _locals = new Dictionary(); + + public XamlEmitContextWithLocals(TBackendEmitter emitter, + TransformerConfiguration configuration, + XamlLanguageEmitMappings emitMappings, + XamlRuntimeContext runtimeContext, + IXamlLocal contextLocal, + Func> createSubType, + IFileSource file, + IEnumerable emitters) + : base(emitter, configuration, emitMappings, runtimeContext, contextLocal, createSubType, file, emitters) + { + } + + public IXamlLocal GetLocalForNode(XamlAstCompilerLocalNode node, TBackendEmitter codeGen, bool throwOnUninitialized) + { + if (!_locals.TryGetValue(node, out var local)) + { + if (throwOnUninitialized) + { + throw new XamlLoadException("Attempt to read uninitialized local variable", node); + } + _locals[node] = local = codeGen.DefineLocal(node.Type); + } + return local; + } + + public abstract void LoadLocalValue(XamlAstCompilerLocalNode node, TBackendEmitter codeGen); + + public XamlLocalsPool.PooledLocal GetLocalOfType(IXamlType type) + { + return Emitter.LocalsPool.GetLocal(type); + } + + protected override TEmitResult EmitNodeCore(IXamlAstNode value, TBackendEmitter codeGen, out bool foundEmitter) + { + var result = base.EmitNodeCore(value, codeGen, out foundEmitter); + + if (result != default) + { + return result; + } + + foreach (var e in Emitters) + { + if (e is IXamlAstLocalsNodeEmitter ve) + { + result = ve.Emit(value, this, codeGen); + if (result != default) + { + foundEmitter = true; + return result; + } + } + } + + if (!foundEmitter) + { + if (value is IXamlAstLocalsEmitableNode emittable) + { + foundEmitter = true; + return emittable.Emit(this, codeGen); + } + } + + return result; + } + protected override bool EmitCore(IXamlWrappedMethod wrapped, TBackendEmitter codeGen, bool swallowResult) + { + bool foundEmitter = base.EmitCore(wrapped, codeGen, swallowResult); + + if (foundEmitter) + { + return true; + } + + foreach (var e in Emitters) + { + if (e is IXamlWrappedMethodEmitterWithLocals wme) + { + foundEmitter = wme.EmitCall(this, wrapped, codeGen, swallowResult); + if (foundEmitter) + { + break; + } + } + } + + if (!foundEmitter) + { + if (wrapped is IXamlEmitableWrappedMethodWithLocals ewm) + { + ewm.Emit(this, codeGen, swallowResult); + } + } + + return foundEmitter; + } + } + +#if !XAMLX_INTERNAL + public +#endif + interface IHasLocalsPool + { + XamlLocalsPool LocalsPool { get; } + IXamlLocal DefineLocal(IXamlType type); + } + +#if !XAMLX_INTERNAL + public +#endif + interface IXamlAstLocalsNodeEmitter + where TBackendEmitter : IHasLocalsPool + where TEmitResult : IXamlEmitResult + { + TEmitResult Emit(IXamlAstNode node, XamlEmitContextWithLocals context, TBackendEmitter codeGen); + } + +#if !XAMLX_INTERNAL + public +#endif + interface IXamlAstLocalsEmitableNode + where TBackendEmitter : IHasLocalsPool + where TEmitResult : IXamlEmitResult + { + TEmitResult Emit(XamlEmitContextWithLocals context, TBackendEmitter codeGen); + } + +#if !XAMLX_INTERNAL + public +#endif + interface IXamlWrappedMethodEmitterWithLocals + where TBackendEmitter : IHasLocalsPool + where TEmitResult : IXamlEmitResult + { + bool EmitCall(XamlEmitContextWithLocals context, IXamlWrappedMethod method, TBackendEmitter emitter, bool swallowResult); + } + +#if !XAMLX_INTERNAL + public +#endif + interface IXamlEmitableWrappedMethodWithLocals : IXamlWrappedMethod + where TBackendEmitter : IHasLocalsPool + where TEmitResult : IXamlEmitResult + { + void Emit(XamlEmitContextWithLocals context, TBackendEmitter emitter, bool swallowResult); + } +} diff --git a/src/XamlX/Emit/XamlLanguageEmitMappings.cs b/src/XamlX/Emit/XamlLanguageEmitMappings.cs new file mode 100644 index 00000000..2618b7cb --- /dev/null +++ b/src/XamlX/Emit/XamlLanguageEmitMappings.cs @@ -0,0 +1,28 @@ +using System; +using XamlX.Ast; +using XamlX.TypeSystem; + +namespace XamlX.Emit +{ +#if !XAMLX_INTERNAL + public +#endif + class XamlLanguageEmitMappings + where TEmitResult : IXamlEmitResult + { + public Func, TBackendEmitter, XamlAstClrProperty, bool> ProvideValueTargetPropertyEmitter { get; set; } + public XamlContextTypeBuilderCallback ContextTypeBuilderCallback { get; set; } + public XamlContextFactoryCallback ContextFactoryCallback { get; set; } + } + +#if !XAMLX_INTERNAL + public +#endif + delegate void XamlContextTypeBuilderCallback(IXamlTypeBuilder typeBuilder, TBackendEmitter constructor); + +#if !XAMLX_INTERNAL + public +#endif + delegate void XamlContextFactoryCallback(XamlRuntimeContext context, TBackendEmitter emitter) + where TEmitResult : IXamlEmitResult; +} diff --git a/src/XamlX/Emit/XamlRuntimeContext.cs b/src/XamlX/Emit/XamlRuntimeContext.cs new file mode 100644 index 00000000..c4e2590c --- /dev/null +++ b/src/XamlX/Emit/XamlRuntimeContext.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using XamlX.TypeSystem; + +namespace XamlX.Emit +{ +#if !XAMLX_INTERNAL + public +#endif + class XamlRuntimeContext + where TEmitResult : IXamlEmitResult + { + public IXamlField RootObjectField { get; set; } + public IXamlField IntermediateRootObjectField { get; set; } + public IXamlField ParentListField { get; set; } + public IXamlType ContextType { get; set; } + public IXamlField PropertyTargetObject { get; set; } + public IXamlField PropertyTargetProperty { get; set; } + public IXamlConstructor Constructor { get; set; } + public Action Factory { get; set; } + public IXamlMethod PushParentMethod { get; set; } + public IXamlMethod PopParentMethod { get; set; } + + public XamlRuntimeContext(IXamlType definition, IXamlType constructedType, + XamlLanguageEmitMappings mappings, + Action, TBackendEmitter> factory) + { + ContextType = definition.MakeGenericType(constructedType); + + IXamlField Get(string s) => + ContextType.Fields.FirstOrDefault(f => f.Name == s); + + IXamlMethod GetMethod(string s) => + ContextType.Methods.FirstOrDefault(f => f.Name == s); + + RootObjectField = Get(XamlRuntimeContextDefintion.RootObjectFieldName); + IntermediateRootObjectField = Get(XamlRuntimeContextDefintion.IntermediateRootObjectFieldName); + ParentListField = Get(XamlRuntimeContextDefintion.ParentListFieldName); + PropertyTargetObject = Get(XamlRuntimeContextDefintion.ProvideTargetObjectName); + PropertyTargetProperty = Get(XamlRuntimeContextDefintion.ProvideTargetPropertyName); + PushParentMethod = GetMethod(XamlRuntimeContextDefintion.PushParentMethodName); + PopParentMethod = GetMethod(XamlRuntimeContextDefintion.PopParentMethodName); + Constructor = ContextType.Constructors.First(); + Factory = il => factory(this, il); + if (mappings.ContextFactoryCallback != null) + Factory = il => + { + factory(this, il); + mappings.ContextFactoryCallback(this, il); + }; + } + } + + static class XamlRuntimeContextDefintion + { + public const string RootObjectFieldName = "RootObject"; + public const string IntermediateRootObjectFieldName = "IntermediateRoot"; + public const string ParentListFieldName = "ParentsStack"; + public const string ProvideTargetObjectName = "ProvideTargetObject"; + public const string ProvideTargetPropertyName = "ProvideTargetProperty"; + public const string PushParentMethodName = "PushParent"; + public const string PopParentMethodName = "PopParent"; + } +} diff --git a/src/XamlX/Exceptions.cs b/src/XamlX/Exceptions.cs index 855c3ed1..dc1e8711 100644 --- a/src/XamlX/Exceptions.cs +++ b/src/XamlX/Exceptions.cs @@ -4,51 +4,51 @@ namespace XamlX { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXParseException : XmlException + class XamlParseException : XmlException { - public XamlXParseException(string message, int line, int position) : base( + public XamlParseException(string message, int line, int position) : base( $"{message} (line {line} position {position})", null, line, position) { } - public XamlXParseException(string message, IXamlXLineInfo lineInfo) : this(message, lineInfo.Line, lineInfo.Position) + public XamlParseException(string message, IXamlLineInfo lineInfo) : this(message, lineInfo.Line, lineInfo.Position) { } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXTransformException : XamlXParseException + class XamlTransformException : XamlParseException { - public XamlXTransformException(string message, IXamlXLineInfo lineInfo) : base(message, lineInfo) + public XamlTransformException(string message, IXamlLineInfo lineInfo) : base(message, lineInfo) { } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXLoadException : XamlXParseException + class XamlLoadException : XamlParseException { - public XamlXLoadException(string message, IXamlXLineInfo lineInfo) : base(message, lineInfo) + public XamlLoadException(string message, IXamlLineInfo lineInfo) : base(message, lineInfo) { } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXTypeSystemException : Exception + class XamlTypeSystemException : Exception { - public XamlXTypeSystemException(string message) : base(message) + public XamlTypeSystemException(string message) : base(message) { } diff --git a/src/XamlX/Transform/CheckingIlEmitter.cs b/src/XamlX/IL/CheckingILEmitter.cs similarity index 86% rename from src/XamlX/Transform/CheckingIlEmitter.cs rename to src/XamlX/IL/CheckingILEmitter.cs index 04f3fc18..3e7fed0b 100644 --- a/src/XamlX/Transform/CheckingIlEmitter.cs +++ b/src/XamlX/IL/CheckingILEmitter.cs @@ -5,28 +5,27 @@ using System.Reflection.Emit; using XamlX.TypeSystem; -namespace XamlX.Transform +namespace XamlX.IL { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class CheckingIlEmitter : IXamlXEmitter + class CheckingILEmitter : IXamlILEmitter { - private readonly IXamlXEmitter _inner; + private readonly IXamlILEmitter _inner; - private Dictionary _unmarkedLabels = - new Dictionary(); + private Dictionary _unmarkedLabels = + new Dictionary(); - private Dictionary _labels = - new Dictionary(); + private Dictionary _labels = + new Dictionary(); - private List _labelsToMarkOnNextInstruction = new List(); + private List _labelsToMarkOnNextInstruction = new List(); private bool _paused; - public CheckingIlEmitter(IXamlXEmitter inner) + public CheckingILEmitter(IXamlILEmitter inner) { _inner = inner; - } class Instruction @@ -35,7 +34,7 @@ class Instruction public OpCode Opcode { get; set; } public object Operand { get; } public int BalanceChange { get; set; } - public IXamlXLabel JumpToLabel { get; set; } + public IXamlLabel JumpToLabel { get; set; } public Instruction JumpToInstruction { get; set; } public int? ExpectedBalance { get; set; } public bool IsExplicit { get; set; } @@ -46,7 +45,7 @@ public Instruction(int offset, OpCode opcode, object operand) Opcode = opcode; Operand = operand; BalanceChange = GetInstructionBalance(opcode, operand); - JumpToLabel = operand as IXamlXLabel; + JumpToLabel = operand as IXamlLabel; } public Instruction(int offset, int balanceChange) @@ -63,7 +62,7 @@ public override string ToString() => private List _instructions = new List(); - public IXamlXTypeSystem TypeSystem => _inner.TypeSystem; + public IXamlTypeSystem TypeSystem => _inner.TypeSystem; private static readonly Dictionary s_balance = new Dictionary @@ -112,8 +111,8 @@ static int Balance(StackBehaviour op) static int GetInstructionPopBalance(OpCode code, object operand) { - var method = operand as IXamlXMethod; - var ctor = operand as IXamlXConstructor; + var method = operand as IXamlMethod; + var ctor = operand as IXamlConstructor; var stackBalance = 0; if (method != null && (code == OpCodes.Call || code == OpCodes.Callvirt)) { @@ -139,8 +138,8 @@ static int GetInstructionPopBalance(OpCode code, object operand) static int GetInstructionPushBalance(OpCode code, object operand) { - var method = operand as IXamlXMethod; - var ctor = operand as IXamlXConstructor; + var method = operand as IXamlMethod; + var ctor = operand as IXamlConstructor; var stackBalance = 0; if (method != null && (code == OpCodes.Call || code == OpCodes.Callvirt)) { @@ -176,7 +175,7 @@ public void ExplicitStack(int change) if (_paused) return; _instructions.Add(new Instruction(_instructions.Count, change)); - (_inner as CheckingIlEmitter)?.ExplicitStack(change); + (_inner as CheckingILEmitter)?.ExplicitStack(change); } void Track(OpCode code, object operand) @@ -190,89 +189,89 @@ void Track(OpCode code, object operand) _labelsToMarkOnNextInstruction.Clear(); } - public IXamlXEmitter Emit(OpCode code) + public IXamlILEmitter Emit(OpCode code) { Track(code, null); _inner.Emit(code); return this; } - public IXamlXEmitter Emit(OpCode code, IXamlXField field) + public IXamlILEmitter Emit(OpCode code, IXamlField field) { Track(code, field); _inner.Emit(code, field); return this; } - public IXamlXEmitter Emit(OpCode code, IXamlXMethod method) + public IXamlILEmitter Emit(OpCode code, IXamlMethod method) { Track(code, method); _inner.Emit(code, method); return this; } - public IXamlXEmitter Emit(OpCode code, IXamlXConstructor ctor) + public IXamlILEmitter Emit(OpCode code, IXamlConstructor ctor) { Track(code, ctor); _inner.Emit(code, ctor); return this; } - public IXamlXEmitter Emit(OpCode code, string arg) + public IXamlILEmitter Emit(OpCode code, string arg) { Track(code, arg); _inner.Emit(code, arg); return this; } - public IXamlXEmitter Emit(OpCode code, int arg) + public IXamlILEmitter Emit(OpCode code, int arg) { Track(code, arg); _inner.Emit(code, arg); return this; } - public IXamlXEmitter Emit(OpCode code, long arg) + public IXamlILEmitter Emit(OpCode code, long arg) { Track(code, arg); _inner.Emit(code, arg); return this; } - public IXamlXEmitter Emit(OpCode code, IXamlXType type) + public IXamlILEmitter Emit(OpCode code, IXamlType type) { Track(code, type); _inner.Emit(code, type); return this; } - public IXamlXEmitter Emit(OpCode code, float arg) + public IXamlILEmitter Emit(OpCode code, float arg) { Track(code, arg); _inner.Emit(code, arg); return this; } - public IXamlXEmitter Emit(OpCode code, double arg) + public IXamlILEmitter Emit(OpCode code, double arg) { Track(code, arg); _inner.Emit(code, arg); return this; } - public IXamlXLocal DefineLocal(IXamlXType type) + public IXamlLocal DefineLocal(IXamlType type) { return _inner.DefineLocal(type); } - public IXamlXLabel DefineLabel() + public IXamlLabel DefineLabel() { var label = _inner.DefineLabel(); _unmarkedLabels.Add(label, null);//, Environment.StackTrace); return label; } - public IXamlXEmitter MarkLabel(IXamlXLabel label) + public IXamlILEmitter MarkLabel(IXamlLabel label) { if (!_unmarkedLabels.Remove(label)) throw new InvalidOperationException("Attempt to mark undeclared label"); @@ -281,14 +280,14 @@ public IXamlXEmitter MarkLabel(IXamlXLabel label) return this; } - public IXamlXEmitter Emit(OpCode code, IXamlXLabel label) + public IXamlILEmitter Emit(OpCode code, IXamlLabel label) { Track(code, label); _inner.Emit(code, label); return this; } - public IXamlXEmitter Emit(OpCode code, IXamlXLocal local) + public IXamlILEmitter Emit(OpCode code, IXamlLocal local) { Track(code, local); _inner.Emit(code, local); @@ -300,7 +299,7 @@ public void InsertSequencePoint(IFileSource file, int line, int position) _inner.InsertSequencePoint(file, line, position); } - public XamlXLocalsPool LocalsPool => _inner.LocalsPool; + public XamlLocalsPool LocalsPool => _inner.LocalsPool; string VerifyAndGetBalanceAtExit(int expectedBalance, bool expectReturn) { diff --git a/src/XamlX/Transform/Emitters/ManipulationGroupEmitter.cs b/src/XamlX/IL/Emitters/ManipulationGroupEmitter.cs similarity index 55% rename from src/XamlX/Transform/Emitters/ManipulationGroupEmitter.cs rename to src/XamlX/IL/Emitters/ManipulationGroupEmitter.cs index 774e6ac1..8ede328f 100644 --- a/src/XamlX/Transform/Emitters/ManipulationGroupEmitter.cs +++ b/src/XamlX/IL/Emitters/ManipulationGroupEmitter.cs @@ -1,17 +1,19 @@ using System.Reflection.Emit; using XamlX.Ast; +using XamlX.Emit; +using XamlX.Transform; using XamlX.TypeSystem; -namespace XamlX.Transform.Emitters +namespace XamlX.IL.Emitters { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class ManipulationGroupEmitter : IXamlXAstNodeEmitter + class ManipulationGroupEmitter : IXamlAstNodeEmitter { - public XamlXNodeEmitResult Emit(IXamlXAstNode node, XamlXEmitContext context, IXamlXEmitter codeGen) + public XamlILNodeEmitResult Emit(IXamlAstNode node, XamlEmitContext context, IXamlILEmitter codeGen) { - if (!(node is XamlXManipulationGroupNode group)) + if (!(node is XamlManipulationGroupNode group)) return null; if (group.Children.Count == 0) codeGen.Pop(); @@ -25,7 +27,7 @@ public XamlXNodeEmitResult Emit(IXamlXAstNode node, XamlXEmitContext context, IX } } - return XamlXNodeEmitResult.Void(1); + return XamlILNodeEmitResult.Void(1); } } } diff --git a/src/XamlX/Transform/Emitters/MarkupExtensionEmitter.cs b/src/XamlX/IL/Emitters/MarkupExtensionEmitter.cs similarity index 66% rename from src/XamlX/Transform/Emitters/MarkupExtensionEmitter.cs rename to src/XamlX/IL/Emitters/MarkupExtensionEmitter.cs index 1bcd9083..c28123cb 100644 --- a/src/XamlX/Transform/Emitters/MarkupExtensionEmitter.cs +++ b/src/XamlX/IL/Emitters/MarkupExtensionEmitter.cs @@ -1,24 +1,24 @@ using System.Linq; using System.Reflection.Emit; using XamlX.Ast; -using XamlX.Transform.Transformers; -using XamlX.TypeSystem; +using XamlX.Emit; +using XamlX.Transform; -namespace XamlX.Transform.Emitters +namespace XamlX.IL.Emitters { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class MarkupExtensionEmitter : IXamlXAstNodeEmitter + class MarkupExtensionEmitter : IXamlAstNodeEmitter { - public XamlXNodeEmitResult Emit(IXamlXAstNode node, XamlXEmitContext context, IXamlXEmitter ilgen) + public XamlILNodeEmitResult Emit(IXamlAstNode node, XamlEmitContext context, IXamlILEmitter ilgen) { - if (!(node is XamlXMarkupExtensionNode me)) + if (!(node is XamlMarkupExtensionNode me)) return null; - XamlXNeedsParentStackCache.Verify(context, node); + XamlNeedsParentStackCache.Verify(context, node); - var prop = context.ParentNodes().OfType().FirstOrDefault(); + var prop = context.ParentNodes().OfType().FirstOrDefault(); var needProvideValueTarget = me.ProvideValue.Parameters.Count != 0 && context.RuntimeContext.PropertyTargetObject != null @@ -26,7 +26,7 @@ public XamlXNodeEmitResult Emit(IXamlXAstNode node, XamlXEmitContext context, IX void EmitPropertyDescriptor() { - if (context.Configuration.TypeMappings.ProvideValueTargetPropertyEmitter + if (context.EmitMappings.ProvideValueTargetPropertyEmitter ?.Invoke(context, ilgen, prop.Property) == true) return; ilgen.Ldstr(prop.Property.Name); @@ -57,9 +57,7 @@ void EmitPropertyDescriptor() .Stfld(context.RuntimeContext.PropertyTargetProperty); } - - - return XamlXNodeEmitResult.Type(0, me.ProvideValue.ReturnType); + return XamlILNodeEmitResult.Type(0, me.ProvideValue.ReturnType); } } } diff --git a/src/XamlX/IL/Emitters/MethodCallEmitter.cs b/src/XamlX/IL/Emitters/MethodCallEmitter.cs new file mode 100644 index 00000000..85fc17e4 --- /dev/null +++ b/src/XamlX/IL/Emitters/MethodCallEmitter.cs @@ -0,0 +1,43 @@ +using System.Reflection.Emit; +using XamlX.Ast; +using XamlX.Emit; +using XamlX.Transform; +using XamlX.TypeSystem; + +namespace XamlX.IL.Emitters +{ +#if !XAMLX_INTERNAL + public +#endif + class MethodCallEmitter : IXamlAstNodeEmitter + { + public XamlILNodeEmitResult Emit(IXamlAstNode node, XamlEmitContext context, IXamlILEmitter codeGen) + { + if (!(node is XamlMethodCallBaseNode mc)) + return null; + + bool thisArgFromArgs = node is XamlStaticOrTargetedReturnMethodCallNode; + bool expectsVoid = node is XamlNoReturnMethodCallNode; + + + for (var c = 0; c < mc.Arguments.Count; c++) + { + var off = thisArgFromArgs ? 0 : 1; + var expectedType = mc.Method.ParametersWithThis[c + off]; + context.Emit(mc.Arguments[c], codeGen, expectedType); + } + + context.Emit(mc.Method, codeGen, expectsVoid); + + var isVoid = mc.Method.ReturnType.Equals(context.Configuration.WellKnownTypes.Void); + if (!expectsVoid && isVoid) + throw new XamlLoadException( + $"XamlStaticReturnMethodCallNode expects a value while {mc.Method.Name} returns void", node); + + var consumed = thisArgFromArgs ? 0 : 1; + return isVoid || expectsVoid + ? XamlILNodeEmitResult.Void(consumed) + : XamlILNodeEmitResult.Type(consumed, mc.Method.ReturnType); + } + } +} diff --git a/src/XamlX/Transform/Emitters/NewObjectEmitter.cs b/src/XamlX/IL/Emitters/NewObjectEmitter.cs similarity index 50% rename from src/XamlX/Transform/Emitters/NewObjectEmitter.cs rename to src/XamlX/IL/Emitters/NewObjectEmitter.cs index eaaa0ece..2d10374a 100644 --- a/src/XamlX/Transform/Emitters/NewObjectEmitter.cs +++ b/src/XamlX/IL/Emitters/NewObjectEmitter.cs @@ -1,24 +1,27 @@ using System.Linq; using System.Reflection.Emit; using XamlX.Ast; +using XamlX.Emit; +using XamlX.IL; +using XamlX.Transform; using XamlX.TypeSystem; -namespace XamlX.Transform.Emitters +namespace XamlX.IL.Emitters { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class NewObjectEmitter : IXamlXAstNodeEmitter + class NewObjectEmitter : IXamlAstNodeEmitter { - public XamlXNodeEmitResult Emit(IXamlXAstNode node, XamlXEmitContext context, IXamlXEmitter codeGen) + public XamlILNodeEmitResult Emit(IXamlAstNode node, XamlEmitContext context, IXamlILEmitter codeGen) { - if (!(node is XamlXAstNewClrObjectNode n)) + if (!(node is XamlAstNewClrObjectNode n)) return null; var type = n.Type.GetClrType(); var ctor = n.Constructor ?? type.FindConstructor(); if (ctor == null) - throw new XamlXLoadException("Unable to find default constructor and no non-default one is specified", + throw new XamlLoadException("Unable to find default constructor and no non-default one is specified", n); for (var c = 0; c < n.Arguments.Count; c++) @@ -30,7 +33,7 @@ public XamlXNodeEmitResult Emit(IXamlXAstNode node, XamlXEmitContext context, IX .Emit(OpCodes.Newobj, ctor); - return XamlXNodeEmitResult.Type(0, type); + return XamlILNodeEmitResult.Type(0, type); } } } diff --git a/src/XamlX/Transform/Emitters/ObjectInitializationNodeEmitter.cs b/src/XamlX/IL/Emitters/ObjectInitializationNodeEmitter.cs similarity index 66% rename from src/XamlX/Transform/Emitters/ObjectInitializationNodeEmitter.cs rename to src/XamlX/IL/Emitters/ObjectInitializationNodeEmitter.cs index 3003ef99..004e913a 100644 --- a/src/XamlX/Transform/Emitters/ObjectInitializationNodeEmitter.cs +++ b/src/XamlX/IL/Emitters/ObjectInitializationNodeEmitter.cs @@ -1,18 +1,20 @@ using System.Collections.Generic; using System.Reflection.Emit; using XamlX.Ast; +using XamlX.Emit; +using XamlX.Transform; using XamlX.TypeSystem; -namespace XamlX.Transform.Emitters +namespace XamlX.IL.Emitters { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class ObjectInitializationNodeEmitter : IXamlXAstNodeEmitter + class ObjectInitializationNodeEmitter : IXamlAstLocalsNodeEmitter { - public XamlXNodeEmitResult Emit(IXamlXAstNode node, XamlXEmitContext context, IXamlXEmitter codeGen) + public XamlILNodeEmitResult Emit(IXamlAstNode node, XamlEmitContextWithLocals context, IXamlILEmitter codeGen) { - if (!(node is XamlXObjectInitializationNode init)) + if (!(node is XamlObjectInitializationNode init)) return null; var supportInitType = context.Configuration.TypeMappings.SupportInitialize; var supportsInitialize = supportInitType != null @@ -34,10 +36,10 @@ public XamlXNodeEmitResult Emit(IXamlXAstNode node, XamlXEmitContext context, IX var addToParentStack = context.RuntimeContext.ParentListField != null && !init.Type.IsValueType - && context.GetOrCreateItem().NeedsParentStack(node); + && context.GetOrCreateItem().NeedsParentStack(node); if(addToParentStack) { - using (var local = context.GetLocal(init.Type)) + using (var local = context.GetLocalOfType(init.Type)) codeGen .Stloc(local.Local) .Ldloc(context.ContextLocal) @@ -60,35 +62,35 @@ public XamlXNodeEmitResult Emit(IXamlXAstNode node, XamlXEmitContext context, IX .EmitCall(supportInitType.FindMethod(m => m.Name == "EndInit")); - return XamlXNodeEmitResult.Void(1); + return XamlILNodeEmitResult.Void(1); } } - class XamlXNeedsParentStackCache : Dictionary + class XamlNeedsParentStackCache : Dictionary { - public static void Verify(XamlXContextBase ctx, IXamlXAstNode node) + public static void Verify(XamlContextBase ctx, IXamlAstNode node) { - var cache = ctx.GetItem(); + var cache = ctx.GetItem(); // There is no parent stack if (cache == null) return; if (!cache.ContainsKey(node)) - throw new XamlXLoadException("Node needs parent stack, but one doesn't seem to be provided", node); + throw new XamlLoadException("Node needs parent stack, but one doesn't seem to be provided", node); } - class ParentStackVisitor : IXamlXAstVisitor + class ParentStackVisitor : IXamlAstVisitor { - private readonly XamlXNeedsParentStackCache _cache; + private readonly XamlNeedsParentStackCache _cache; - public ParentStackVisitor(XamlXNeedsParentStackCache cache) + public ParentStackVisitor(XamlNeedsParentStackCache cache) { _cache = cache; } - Stack _parents = new Stack(); - public IXamlXAstNode Visit(IXamlXAstNode node) + Stack _parents = new Stack(); + public IXamlAstNode Visit(IXamlAstNode node) { if (_cache.ContainsKey(node)) return node; - if (node is IXamlXAstNodeNeedsParentStack nps && nps.NeedsParentStack) + if (node is IXamlAstNodeNeedsParentStack nps && nps.NeedsParentStack) { _cache[node] = true; foreach (var parent in _parents) @@ -100,12 +102,12 @@ public IXamlXAstNode Visit(IXamlXAstNode node) return node; } - public void Push(IXamlXAstNode node) => _parents.Push(node); + public void Push(IXamlAstNode node) => _parents.Push(node); public void Pop() => _parents.Pop(); } - public bool NeedsParentStack(IXamlXAstNode node) + public bool NeedsParentStack(IXamlAstNode node) { if (TryGetValue(node, out var rv)) return rv; diff --git a/src/XamlX/Transform/Emitters/PropertyAssignmentEmitter.cs b/src/XamlX/IL/Emitters/PropertyAssignmentEmitter.cs similarity index 79% rename from src/XamlX/Transform/Emitters/PropertyAssignmentEmitter.cs rename to src/XamlX/IL/Emitters/PropertyAssignmentEmitter.cs index 6f918117..a45a1469 100644 --- a/src/XamlX/Transform/Emitters/PropertyAssignmentEmitter.cs +++ b/src/XamlX/IL/Emitters/PropertyAssignmentEmitter.cs @@ -2,16 +2,18 @@ using System.Linq; using System.Reflection.Emit; using XamlX.Ast; +using XamlX.Emit; +using XamlX.Transform; using XamlX.TypeSystem; -namespace XamlX.Transform.Emitters +namespace XamlX.IL.Emitters { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class PropertyAssignmentEmitter : IXamlXAstNodeEmitter + class PropertyAssignmentEmitter : IXamlAstLocalsNodeEmitter { - List ValidateAndGetSetters(XamlXPropertyAssignmentNode an) + List ValidateAndGetSetters(XamlPropertyAssignmentNode an) { var lst = an.PossibleSetters.Where(x => x.Parameters.Count == an.Values.Count).ToList(); if(an.Values.Count>1 && lst.Count>1) @@ -21,20 +23,20 @@ List ValidateAndGetSetters(XamlXPropertyAssignmentNode an) !x.Parameters[c].IsDirectlyAssignableFrom(an.Values[c].Type.GetClrType())); if (failed != null) { - throw new XamlXLoadException( + throw new XamlLoadException( $"Can not statically cast {an.Values[c].Type.GetClrType().GetFqn()} to {failed.Parameters[c].GetFqn()} and runtime type checking is only supported for the last setter argument", an); } } if (lst.Count == 0) - throw new XamlXLoadException("No setters found for property assignment", an); + throw new XamlLoadException("No setters found for property assignment", an); return lst; } - public XamlXNodeEmitResult Emit(IXamlXAstNode node, XamlXEmitContext context, IXamlXEmitter codeGen) + public XamlILNodeEmitResult Emit(IXamlAstNode node, XamlEmitContextWithLocals context, IXamlILEmitter codeGen) { - if (!(node is XamlXPropertyAssignmentNode an)) + if (!(node is XamlPropertyAssignmentNode an)) return null; var setters = ValidateAndGetSetters(an); @@ -51,13 +53,13 @@ public XamlXNodeEmitResult Emit(IXamlXAstNode node, XamlXEmitContext context, IX { var setter = an.PossibleSetters.First(); context.Emit(value, codeGen, setter.Parameters.Last()); - setter.Emit(codeGen); + context.Emit(setter, codeGen); } else { - var checkedTypes = new List(); - IXamlXLabel exit = codeGen.DefineLabel(); - IXamlXLabel next = null; + var checkedTypes = new List(); + IXamlLabel exit = codeGen.DefineLabel(); + IXamlLabel next = null; var hadJumps = false; context.Emit(value, codeGen, value.Type.GetClrType()); @@ -75,7 +77,7 @@ public XamlXNodeEmitResult Emit(IXamlXAstNode node, XamlXEmitContext context, IX next = null; } - IXamlXLabel Next() => next ?? (next = codeGen.DefineLabel()); + IXamlLabel Next() => next ?? (next = codeGen.DefineLabel()); var checkNext = false; if (setter.BinderParameters.AllowRuntimeNull) @@ -102,8 +104,8 @@ public XamlXNodeEmitResult Emit(IXamlXAstNode node, XamlXEmitContext context, IX if (checkNext) hadJumps = true; - TypeSystemHelpers.EmitConvert(context, codeGen, value, value.Type.GetClrType(), type); - setter.Emit(codeGen); + ILEmitHelpers.EmitConvert(context, codeGen, value, value.Type.GetClrType(), type); + context.Emit(setter, codeGen); if (hadJumps) { codeGen.Br(exit); @@ -138,7 +140,7 @@ public XamlXNodeEmitResult Emit(IXamlXAstNode node, XamlXEmitContext context, IX codeGen.MarkLabel(exit); } - return XamlXNodeEmitResult.Void(1); + return XamlILNodeEmitResult.Void(1); } } } diff --git a/src/XamlX/IL/Emitters/PropertyValueManipulationEmitter.cs b/src/XamlX/IL/Emitters/PropertyValueManipulationEmitter.cs new file mode 100644 index 00000000..2de60cc4 --- /dev/null +++ b/src/XamlX/IL/Emitters/PropertyValueManipulationEmitter.cs @@ -0,0 +1,24 @@ +using System.Reflection.Emit; +using XamlX.Ast; +using XamlX.Emit; +using XamlX.Transform; +using XamlX.TypeSystem; + +namespace XamlX.IL.Emitters +{ +#if !XAMLX_INTERNAL + public +#endif + class PropertyValueManipulationEmitter : IXamlAstNodeEmitter + { + public XamlILNodeEmitResult Emit(IXamlAstNode node, XamlEmitContext context, IXamlILEmitter codeGen) + { + if (!(node is XamlPropertyValueManipulationNode pvm)) + return null; + codeGen.EmitCall(pvm.Property.Getter); + context.Emit(pvm.Manipulation, codeGen, null); + + return XamlILNodeEmitResult.Void(1); + } + } +} diff --git a/src/XamlX/IL/Emitters/TextNodeEmitter.cs b/src/XamlX/IL/Emitters/TextNodeEmitter.cs new file mode 100644 index 00000000..579530c4 --- /dev/null +++ b/src/XamlX/IL/Emitters/TextNodeEmitter.cs @@ -0,0 +1,24 @@ +using System.Reflection.Emit; +using XamlX.Ast; +using XamlX.Emit; +using XamlX.Transform; +using XamlX.TypeSystem; + +namespace XamlX.IL.Emitters +{ +#if !XAMLX_INTERNAL + public +#endif + class TextNodeEmitter : IXamlAstNodeEmitter + { + public XamlILNodeEmitResult Emit(IXamlAstNode node, XamlEmitContext context, IXamlILEmitter codeGen) + { + if (!(node is XamlAstTextNode text)) + return null; + if (!text.Type.GetClrType().Equals(context.Configuration.WellKnownTypes.String)) + throw new XamlLoadException("Text node type wasn't resolved to well-known System.String", node); + codeGen.Emit(OpCodes.Ldstr, text.Text); + return XamlILNodeEmitResult.Type(0, text.Type.GetClrType()); + } + } +} diff --git a/src/XamlX/IL/Emitters/ValueWithManipulationsEmitter.cs b/src/XamlX/IL/Emitters/ValueWithManipulationsEmitter.cs new file mode 100644 index 00000000..861037ed --- /dev/null +++ b/src/XamlX/IL/Emitters/ValueWithManipulationsEmitter.cs @@ -0,0 +1,29 @@ +using System.Reflection.Emit; +using XamlX.Ast; +using XamlX.Emit; +using XamlX.Transform; +using XamlX.TypeSystem; + +namespace XamlX.IL.Emitters +{ +#if !XAMLX_INTERNAL + public +#endif + class ValueWithManipulationsEmitter : IXamlAstNodeEmitter + { + public XamlILNodeEmitResult Emit(IXamlAstNode node, XamlEmitContext context, IXamlILEmitter codeGen) + { + if (!(node is XamlValueWithManipulationNode vwm)) + return null; + var created = context.Emit(vwm.Value, codeGen, vwm.Type.GetClrType()); + + if (vwm.Manipulation != null && + !(vwm.Manipulation is XamlManipulationGroupNode grp && grp.Children.Count == 0)) + { + codeGen.Emit(OpCodes.Dup); + context.Emit(vwm.Manipulation, codeGen, null); + } + return XamlILNodeEmitResult.Type(0, created.ReturnType); + } + } +} diff --git a/src/XamlX/IL/ILEmitContext.cs b/src/XamlX/IL/ILEmitContext.cs new file mode 100644 index 00000000..33762e8b --- /dev/null +++ b/src/XamlX/IL/ILEmitContext.cs @@ -0,0 +1,102 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection.Emit; +using System.Xml; +using XamlX.Ast; +using XamlX.Emit; +using XamlX.Transform; +using XamlX.TypeSystem; + +namespace XamlX.IL +{ +#if !XAMLX_INTERNAL + public +#endif + class ILEmitContext : XamlEmitContextWithLocals + { + public bool EnableIlVerification { get; } + + public ILEmitContext(IXamlILEmitter emitter, TransformerConfiguration configuration, + XamlLanguageEmitMappings emitMappings, + XamlRuntimeContext runtimeContext, + IXamlLocal contextLocal, + Func> createSubType, IFileSource file, IEnumerable emitters) + : base(emitter, configuration, emitMappings, runtimeContext, + contextLocal, createSubType, file, emitters) + { + EnableIlVerification = configuration.GetOrCreateExtra().EnableILVerification; + } + + protected override XamlILNodeEmitResult EmitNode(IXamlAstNode value, IXamlILEmitter codeGen) + { + CheckingILEmitter parent = null; + CheckingILEmitter checkedEmitter = null; + if (EnableIlVerification) + { + parent = codeGen as CheckingILEmitter; + + parent?.Pause(); + checkedEmitter = new CheckingILEmitter(codeGen); + } +#if XAMLX_DEBUG + var res = base.EmitNode(value, checkedEmitter); +#else + var res = base.EmitNode(value, checkedEmitter ?? codeGen); +#endif + if (EnableIlVerification) + { + var expectedBalance = res.ProducedItems - res.ConsumedItems; + var checkResult = + checkedEmitter.Check(res.ProducedItems - res.ConsumedItems, false); + if (checkResult != null) + throw new XamlLoadException($"Error during IL verification: {checkResult}\n{checkedEmitter}\n", + value); + parent?.Resume(); + parent?.ExplicitStack(expectedBalance); + } + + return res; + } + + protected override XamlILNodeEmitResult EmitNodeCore(IXamlAstNode value, IXamlILEmitter codeGen, out bool foundEmitter) + { + if(File!=null) + codeGen.InsertSequencePoint(File, value.Line, value.Position); + + return base.EmitNodeCore(value, codeGen, out foundEmitter); + } + + protected override void EmitConvert(IXamlAstNode value, IXamlILEmitter codeGen, IXamlType expectedType, IXamlType returnedType) + { + XamlLocalsPool.PooledLocal local = null; + // ReSharper disable once ExpressionIsAlwaysNull + // Value is assigned inside the closure in certain conditions + + ILEmitHelpers.EmitConvert(this, value, returnedType, expectedType, ldaddr => + { + if (ldaddr && returnedType.IsValueType) + { + // We need to store the value to a temporary variable, since *address* + // is required (probably for method call on the value type) + local = GetLocalOfType(returnedType); + codeGen + .Stloc(local.Local) + .Ldloca(local.Local); + + } + // Otherwise do nothing, value is already at the top of the stack + return codeGen; + }); + local?.Dispose(); + } + } + +#if !XAMLX_INTERNAL + public +#endif + class ILEmitContextSettings + { + public bool EnableILVerification { get; set; } + } +} diff --git a/src/XamlX/IL/ILEmitHelpers.cs b/src/XamlX/IL/ILEmitHelpers.cs new file mode 100644 index 00000000..812bee9d --- /dev/null +++ b/src/XamlX/IL/ILEmitHelpers.cs @@ -0,0 +1,135 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Reflection.Emit; +using XamlX.Ast; +using XamlX.Emit; +using XamlX.Transform; +using XamlX.TypeSystem; + +namespace XamlX.IL +{ +#if !XAMLX_INTERNAL + public +#endif + class ILEmitHelpers + { + public static void EmitFieldLiteral(IXamlField field, IXamlILEmitter codeGen) + { + var ftype = field.FieldType.IsEnum ? field.FieldType.GetEnumUnderlyingType() : field.FieldType; + + if (ftype.Name == "UInt64" || ftype.Name == "Int64") + codeGen.Emit(OpCodes.Ldc_I8, + TypeSystemHelpers.ConvertLiteralToLong(field.GetLiteralValue())); + else if (ftype.Name == "Double") + codeGen.Emit(OpCodes.Ldc_R8, (double)field.GetLiteralValue()); + else if (ftype.Name == "Single") + codeGen.Emit(OpCodes.Ldc_R4, (float)field.GetLiteralValue()); + else if (ftype.Name == "String") + codeGen.Emit(OpCodes.Ldstr, (string)field.GetLiteralValue()); + else + codeGen.Emit(OpCodes.Ldc_I4, + TypeSystemHelpers.ConvertLiteralToInt(field.GetLiteralValue())); + } + + public static void EmitConvert(XamlEmitContextWithLocals context, IXamlILEmitter ilgen, IXamlLineInfo node, IXamlType what, + IXamlType to, IXamlLocal local) + { + EmitConvert(context, node, what, to, lda => ilgen.Emit(lda ? OpCodes.Ldloca : OpCodes.Ldloc, local)); + } + + public static void EmitConvert(XamlEmitContextWithLocals context, IXamlILEmitter ilgen, IXamlLineInfo node, + IXamlType what, + IXamlType to) + { + XamlLocalsPool.PooledLocal local = null; + + EmitConvert(context, node, what, to, lda => + { + if (!lda) + return ilgen; + local = ilgen.LocalsPool.GetLocal(what); + ilgen + .Stloc(local.Local) + .Ldloca(local.Local); + return ilgen; + }); + local?.Dispose(); + } + + public static void EmitConvert(XamlEmitContextWithLocals context, IXamlLineInfo node, IXamlType what, + IXamlType to, Func ld) + { + if (what.Equals(to)) + ld(false); + else if (what == XamlPseudoType.Null) + { + + if (to.IsValueType) + { + if (to.GenericTypeDefinition?.Equals(context.Configuration.WellKnownTypes.NullableT) == true) + { + using (var loc = context.GetLocalOfType(to)) + ld(false) + .Pop() + .Ldloca(loc.Local) + .Emit(OpCodes.Initobj, to) + .Ldloc(loc.Local); + + } + else + throw new XamlLoadException("Unable to convert {x:Null} to " + to.GetFqn(), node); + } + else + ld(false); + } + else if (what.IsValueType && to.IsValueType) + { + if (to.IsNullableOf(what)) + { + ld(false).Emit(OpCodes.Newobj, + to.Constructors.First(c => + c.Parameters.Count == 1 && c.Parameters[0].Equals(what))); + } + else if (what.IsNullableOf(what)) + ld(true) + .EmitCall(what.FindMethod(m => m.Name == "get_Value")); + else + throw new XamlLoadException( + $"Don't know how to convert value type {what.GetFullName()} to value type {to.GetFullName()}", + node); + } + else if (!to.IsValueType && what.IsValueType) + { + if (!to.IsAssignableFrom(what)) + throw new XamlLoadException( + $"Don't know how to convert value type {what.GetFullName()} to reference type {to.GetFullName()}", + node); + ld(false).Box(what); + } + else if(to.IsValueType && !what.IsValueType) + { + if (!(what.Namespace == "System" && what.Name == "Object")) + throw new XamlLoadException( + $"Don't know how to convert reference type {what.GetFullName()} to value type {to.GetFullName()}", + node); + ld(false).Unbox_Any(to); + } + else + { + if (to.IsAssignableFrom(what)) + // Downcast, always safe + ld(false); + else if (what.IsInterface || what.IsAssignableFrom(to)) + // Upcast or cast from interface, might throw InvalidCastException + ld(false).Emit(OpCodes.Castclass, to); + else + // Types are completely unrelated, e. g. string to List conversion attempt + throw new XamlLoadException( + $"Don't know how to convert reference type {what.GetFullName()} to reference type {to.GetFullName()}", + node); + } + } + } +} diff --git a/src/XamlX/IL/IXamlILEmitter.cs b/src/XamlX/IL/IXamlILEmitter.cs new file mode 100644 index 00000000..4af8124d --- /dev/null +++ b/src/XamlX/IL/IXamlILEmitter.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Reflection.Emit; +using System.Text; +using XamlX.Emit; +using XamlX.Transform; +using XamlX.TypeSystem; + +namespace XamlX.IL +{ +#if !XAMLX_INTERNAL + public +#endif + interface IXamlILEmitter : IHasLocalsPool + { + IXamlTypeSystem TypeSystem { get; } + IXamlILEmitter Emit(OpCode code); + IXamlILEmitter Emit(OpCode code, IXamlField field); + IXamlILEmitter Emit(OpCode code, IXamlMethod method); + IXamlILEmitter Emit(OpCode code, IXamlConstructor ctor); + IXamlILEmitter Emit(OpCode code, string arg); + IXamlILEmitter Emit(OpCode code, int arg); + IXamlILEmitter Emit(OpCode code, long arg); + IXamlILEmitter Emit(OpCode code, IXamlType type); + IXamlILEmitter Emit(OpCode code, float arg); + IXamlILEmitter Emit(OpCode code, double arg); + IXamlLabel DefineLabel(); + IXamlILEmitter MarkLabel(IXamlLabel label); + IXamlILEmitter Emit(OpCode code, IXamlLabel label); + IXamlILEmitter Emit(OpCode code, IXamlLocal local); + void InsertSequencePoint(IFileSource file, int line, int position); + } +} diff --git a/src/XamlX/Transform/XamlXNamespaceInfoHelper.cs b/src/XamlX/IL/NamespaceInfoProvider.cs similarity index 67% rename from src/XamlX/Transform/XamlXNamespaceInfoHelper.cs rename to src/XamlX/IL/NamespaceInfoProvider.cs index 6d6267d5..1147507f 100644 --- a/src/XamlX/Transform/XamlXNamespaceInfoHelper.cs +++ b/src/XamlX/IL/NamespaceInfoProvider.cs @@ -3,62 +3,18 @@ using System.Linq; using System.Reflection.Emit; using XamlX.Ast; +using XamlX.Transform; using XamlX.TypeSystem; -namespace XamlX.Transform +namespace XamlX.IL { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXNamespaceInfoHelper + static class NamespaceInfoProvider { - - public class NamespaceResolveResult - { - public string ClrNamespace { get; set; } - public IXamlXAssembly Assembly { get; set; } - public string AssemblyName { get; set; } - } - - public static List TryResolve(XamlXTransformerConfiguration config, string xmlns) - { - if (config.XmlnsMappings.Namespaces.TryGetValue(xmlns, out var lst)) - { - return lst.Select(p => new NamespaceResolveResult - { - ClrNamespace = p.ns, - Assembly = p.asm - }).ToList(); - } - - const string clrNamespace = "clr-namespace:"; - const string assemblyNamePrefix = ";assembly="; - if (xmlns.StartsWith(clrNamespace)) - { - var ns = xmlns.Substring(clrNamespace.Length); - - var indexOfAssemblyPrefix = ns.IndexOf(assemblyNamePrefix, StringComparison.Ordinal); - string asm = config.DefaultAssembly?.Name; - if (indexOfAssemblyPrefix != -1) - { - asm = ns.Substring(indexOfAssemblyPrefix + assemblyNamePrefix.Length).Trim(); - ns = ns.Substring(0, indexOfAssemblyPrefix); - } - return new List - { - new NamespaceResolveResult - { - ClrNamespace = ns, - AssemblyName = asm - } - }; - } - - return null; - } - - public static IXamlXField EmitNamespaceInfoProvider(XamlXTransformerConfiguration configuration, - IXamlXTypeBuilder typeBuilder, XamlXDocument document) + public static IXamlField EmitNamespaceInfoProvider(TransformerConfiguration configuration, + IXamlTypeBuilder typeBuilder, XamlDocument document) { var iface = configuration.TypeMappings.XmlNamespaceInfoProvider; typeBuilder.AddInterfaceImplementation(iface); @@ -101,10 +57,10 @@ public static IXamlXField EmitNamespaceInfoProvider(XamlXTransformerConfiguratio foreach (var alias in document.NamespaceAliases) { ctor.Generator - .Newobj(listType.FindConstructor(new List())) + .Newobj(listType.FindConstructor(new List())) .Stloc(listLocal); - var resolved = TryResolve(configuration, alias.Value); + var resolved = Transform.NamespaceInfoHelper.TryResolve(configuration, alias.Value); if (resolved != null) { foreach (var rns in resolved) diff --git a/src/XamlX/Transform/RecordingIlEmitter.cs b/src/XamlX/IL/RecordingIlEmitter.cs similarity index 71% rename from src/XamlX/Transform/RecordingIlEmitter.cs rename to src/XamlX/IL/RecordingIlEmitter.cs index 5702bc02..50e470a0 100644 --- a/src/XamlX/Transform/RecordingIlEmitter.cs +++ b/src/XamlX/IL/RecordingIlEmitter.cs @@ -3,25 +3,25 @@ using System.Text; using XamlX.TypeSystem; -namespace XamlX.Transform +namespace XamlX.IL { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class RecordingIlEmitter : IXamlXEmitter + class RecordingIlEmitter : IXamlILEmitter { - private readonly IXamlXEmitter _inner; + private readonly IXamlILEmitter _inner; public List Instructions { get; } = new List(); - private readonly Dictionary _labels - = new Dictionary(); + private readonly Dictionary _labels + = new Dictionary(); - private readonly Dictionary _locals = new Dictionary(); + private readonly Dictionary _locals = new Dictionary(); public class LocalInfo { public int Number { get; set; } - public IXamlXType Type { get; set; } + public IXamlType Type { get; set; } public override string ToString() { @@ -44,97 +44,97 @@ public class RecordedInstruction public object Operand { get; set; } } - public RecordingIlEmitter(IXamlXEmitter inner) + public RecordingIlEmitter(IXamlILEmitter inner) { _inner = inner; } - public IXamlXTypeSystem TypeSystem => _inner.TypeSystem; - public IXamlXEmitter Emit(OpCode code) + public IXamlTypeSystem TypeSystem => _inner.TypeSystem; + public IXamlILEmitter Emit(OpCode code) { Record(code, null); _inner.Emit(code); return this; } - public IXamlXEmitter Emit(OpCode code, IXamlXField field) + public IXamlILEmitter Emit(OpCode code, IXamlField field) { Record(code, field); _inner.Emit(code, field); return this; } - public IXamlXEmitter Emit(OpCode code, IXamlXMethod method) + public IXamlILEmitter Emit(OpCode code, IXamlMethod method) { Record(code, method); _inner.Emit(code, method); return this; } - public IXamlXEmitter Emit(OpCode code, IXamlXConstructor ctor) + public IXamlILEmitter Emit(OpCode code, IXamlConstructor ctor) { Record(code, ctor); _inner.Emit(code, ctor); return this; } - public IXamlXEmitter Emit(OpCode code, string arg) + public IXamlILEmitter Emit(OpCode code, string arg) { Record(code, arg); _inner.Emit(code, arg); return this; } - public IXamlXEmitter Emit(OpCode code, int arg) + public IXamlILEmitter Emit(OpCode code, int arg) { Record(code, arg); _inner.Emit(code, arg); return this; } - public IXamlXEmitter Emit(OpCode code, long arg) + public IXamlILEmitter Emit(OpCode code, long arg) { Record(code, arg); _inner.Emit(code, arg); return this; } - public IXamlXEmitter Emit(OpCode code, IXamlXType type) + public IXamlILEmitter Emit(OpCode code, IXamlType type) { Record(code, type); _inner.Emit(code, type); return this; } - public IXamlXEmitter Emit(OpCode code, float arg) + public IXamlILEmitter Emit(OpCode code, float arg) { Record(code, arg); _inner.Emit(code, arg); return this; } - public IXamlXEmitter Emit(OpCode code, double arg) + public IXamlILEmitter Emit(OpCode code, double arg) { Record(code, arg); _inner.Emit(code, arg); return this; } - public IXamlXLocal DefineLocal(IXamlXType type) + public IXamlLocal DefineLocal(IXamlType type) { var rv= _inner.DefineLocal(type); _locals[rv] = new LocalInfo {Number = _locals.Count, Type = type}; return rv; } - public IXamlXLabel DefineLabel() + public IXamlLabel DefineLabel() { var label = _inner.DefineLabel(); _labels[label] = new LabelInfo(); return label; } - public IXamlXEmitter MarkLabel(IXamlXLabel label) + public IXamlILEmitter MarkLabel(IXamlLabel label) { if (_labels.TryGetValue(label, out var info)) info.Offset = Instructions.Count; @@ -142,14 +142,14 @@ public IXamlXEmitter MarkLabel(IXamlXLabel label) return this; } - public IXamlXEmitter Emit(OpCode code, IXamlXLabel label) + public IXamlILEmitter Emit(OpCode code, IXamlLabel label) { Record(code, label); _inner.Emit(code, label); return this; } - public IXamlXEmitter Emit(OpCode code, IXamlXLocal local) + public IXamlILEmitter Emit(OpCode code, IXamlLocal local) { Record(code, local); _inner.Emit(code, local); @@ -161,15 +161,15 @@ public void InsertSequencePoint(IFileSource file, int line, int position) _inner.InsertSequencePoint(file, line, position); } - public XamlXLocalsPool LocalsPool => _inner.LocalsPool; + public XamlLocalsPool LocalsPool => _inner.LocalsPool; void Record(OpCode code, object operand) { - if (operand is IXamlXLabel l + if (operand is IXamlLabel l && _labels.TryGetValue(l, out var labelInfo)) operand = labelInfo; - if (operand is IXamlXLocal loc + if (operand is IXamlLocal loc && _locals.TryGetValue(loc, out var localInfo)) operand = localInfo; diff --git a/src/XamlX/Transform/XamlXContext.cs b/src/XamlX/IL/RuntimeContext.cs similarity index 81% rename from src/XamlX/Transform/XamlXContext.cs rename to src/XamlX/IL/RuntimeContext.cs index bec01c84..86453224 100644 --- a/src/XamlX/Transform/XamlXContext.cs +++ b/src/XamlX/IL/RuntimeContext.cs @@ -2,58 +2,21 @@ using System.Collections.Generic; using System.Linq; using System.Reflection.Emit; +using XamlX.Emit; +using XamlX.Transform; using XamlX.TypeSystem; -namespace XamlX.Transform +namespace XamlX.IL { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXContext + class RuntimeContext : XamlRuntimeContext { - public IXamlXField RootObjectField { get; set; } - public IXamlXField IntermediateRootObjectField { get; set; } - public IXamlXField ParentListField { get; set; } - public IXamlXType ContextType { get; set; } - public IXamlXField PropertyTargetObject { get; set; } - public IXamlXField PropertyTargetProperty { get; set; } - public IXamlXConstructor Constructor { get; set; } - public Action Factory { get; set; } - public IXamlXMethod PushParentMethod { get; set; } - public IXamlXMethod PopParentMethod { get; set; } - - public XamlXContext(IXamlXType definition, IXamlXType constructedType, - XamlXLanguageTypeMappings mappings, - Action factory) - { - ContextType = definition.MakeGenericType(constructedType); - - IXamlXField Get(string s) => - ContextType.Fields.FirstOrDefault(f => f.Name == s); - - IXamlXMethod GetMethod(string s) => - ContextType.Methods.FirstOrDefault(f => f.Name == s); - - RootObjectField = Get(XamlXContextDefinition.RootObjectFieldName); - IntermediateRootObjectField = Get(XamlXContextDefinition.IntermediateRootObjectFieldName); - ParentListField = Get(XamlXContextDefinition.ParentListFieldName); - PropertyTargetObject = Get(XamlXContextDefinition.ProvideTargetObjectName); - PropertyTargetProperty = Get(XamlXContextDefinition.ProvideTargetPropertyName); - PushParentMethod = GetMethod(XamlXContextDefinition.PushParentMethodName); - PopParentMethod = GetMethod(XamlXContextDefinition.PopParentMethodName); - Constructor = ContextType.Constructors.First(); - Factory = il => factory(this, il); - if (mappings.ContextFactoryCallback != null) - Factory = il => - { - factory(this, il); - mappings.ContextFactoryCallback(this, il); - }; - } - - public XamlXContext(IXamlXType definition, IXamlXType constructedType, - XamlXLanguageTypeMappings mappings, - string baseUri, List staticProviders) : this(definition, constructedType, mappings, + public RuntimeContext(IXamlType definition, IXamlType constructedType, + XamlLanguageEmitMappings mappings, + string baseUri, List staticProviders) + : base(definition, constructedType, mappings, (context, codegen) => { if (staticProviders?.Count > 0) @@ -83,31 +46,24 @@ public XamlXContext(IXamlXType definition, IXamlXType constructedType, } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXContextDefinition + class XamlILContextDefinition { - public const string RootObjectFieldName = "RootObject"; - public const string IntermediateRootObjectFieldName = "IntermediateRoot"; - public const string ParentListFieldName = "ParentsStack"; - public const string ProvideTargetObjectName = "ProvideTargetObject"; - public const string ProvideTargetPropertyName = "ProvideTargetProperty"; - public const string PushParentMethodName = "PushParent"; - public const string PopParentMethodName = "PopParent"; - - private IXamlXField ParentListField; - private readonly IXamlXField _parentServiceProviderField; - private readonly IXamlXField _innerServiceProviderField; - private IXamlXField PropertyTargetObject; - private IXamlXField PropertyTargetProperty; - - private IXamlXConstructor Constructor { get; set; } - - public static IXamlXType GenerateContextClass(IXamlXTypeBuilder builder, - IXamlXTypeSystem typeSystem, XamlXLanguageTypeMappings mappings) + private readonly IXamlField ParentListField; + private readonly IXamlField _parentServiceProviderField; + private readonly IXamlField _innerServiceProviderField; + private readonly IXamlField PropertyTargetObject; + private readonly IXamlField PropertyTargetProperty; + + private IXamlConstructor Constructor { get; set; } + + public static IXamlType GenerateContextClass(IXamlTypeBuilder builder, + IXamlTypeSystem typeSystem, XamlLanguageTypeMappings mappings, + XamlLanguageEmitMappings emitMappings) { - return new XamlXContextDefinition(builder, typeSystem, mappings).ContextType; + return new XamlILContextDefinition(builder, typeSystem, mappings, emitMappings).ContextType; } @@ -115,24 +71,25 @@ public static IXamlXType GenerateContextClass(IXamlXTypeBuilder builder, public const int BaseUriArg = 0; public const int StaticProvidersArg = 1; - public IXamlXType ContextType; + public IXamlType ContextType; - private XamlXContextDefinition(IXamlXTypeBuilder parentBuilder, - IXamlXTypeSystem typeSystem, XamlXLanguageTypeMappings mappings) + private XamlILContextDefinition(IXamlTypeBuilder parentBuilder, + IXamlTypeSystem typeSystem, XamlLanguageTypeMappings mappings, + XamlLanguageEmitMappings emitMappings) { var so = typeSystem.GetType("System.Object"); var builder = parentBuilder.DefineSubType(so, "Context", true); builder.DefineGenericParameters(new[] { - new KeyValuePair("TTarget", - new XamlXGenericParameterConstraint + new KeyValuePair("TTarget", + new XamlGenericParameterConstraint { IsClass = true }) }); var rootObjectField = builder.DefineField(builder.GenericParameters[0], "RootObject", true, false); - var intermediateRootObjectField = builder.DefineField(so, IntermediateRootObjectFieldName, true, false); + var intermediateRootObjectField = builder.DefineField(so, XamlRuntimeContextDefintion.IntermediateRootObjectFieldName, true, false); _parentServiceProviderField = builder.DefineField(mappings.ServiceProvider, "_sp", false, false); if (mappings.InnerServiceProviderFactoryMethod != null) _innerServiceProviderField = builder.DefineField(mappings.ServiceProvider, "_innerSp", false, false); @@ -146,13 +103,13 @@ private XamlXContextDefinition(IXamlXTypeBuilder parentBuilder, var systemString = typeSystem.GetType("System.String"); var getServiceInterfaceMethod = mappings.ServiceProvider.FindMethod("GetService", so, false, systemType); - var ownServices = new List(); - var ctorCallbacks = new List>(); + var ownServices = new List(); + var ctorCallbacks = new List>(); if (mappings.RootObjectProvider != null) { builder.AddInterfaceImplementation(mappings.RootObjectProvider); - var rootGen = ImplementInterfacePropertyGetter(builder, mappings.RootObjectProvider, RootObjectFieldName) + var rootGen = ImplementInterfacePropertyGetter(builder, mappings.RootObjectProvider, XamlRuntimeContextDefintion.RootObjectFieldName) .Generator; var tryParent = rootGen.DefineLabel(); var fail = rootGen.DefineLabel(); @@ -201,7 +158,7 @@ private XamlXContextDefinition(IXamlXTypeBuilder parentBuilder, builder.AddInterfaceImplementation(mappings.ParentStackProvider); var objectListType = typeSystem.GetType("System.Collections.Generic.List`1") .MakeGenericType(new[] {typeSystem.GetType("System.Object")}); - ParentListField = builder.DefineField(objectListType, ParentListFieldName, true, false); + ParentListField = builder.DefineField(objectListType, XamlRuntimeContextDefintion.ParentListFieldName, true, false); var enumerator = EmitParentEnumerable(typeSystem, parentBuilder, mappings); CreateCallbacks.Add(enumerator.createCallback); @@ -214,7 +171,7 @@ private XamlXContextDefinition(IXamlXTypeBuilder parentBuilder, ctorCallbacks.Add(g => g .Emit(OpCodes.Ldarg_0) - .Emit(OpCodes.Newobj, objectListType.FindConstructor(new List())) + .Emit(OpCodes.Newobj, objectListType.FindConstructor(new List())) .Emit(OpCodes.Stfld, ParentListField) .Emit(OpCodes.Ldarg_0) .LdThisFld(ParentListField) @@ -229,8 +186,8 @@ private XamlXContextDefinition(IXamlXTypeBuilder parentBuilder, if (mappings.ProvideValueTarget != null) { builder.AddInterfaceImplementation(mappings.ProvideValueTarget); - PropertyTargetObject = builder.DefineField(so, ProvideTargetObjectName, true, false); - PropertyTargetProperty = builder.DefineField(so, ProvideTargetPropertyName, true, false); + PropertyTargetObject = builder.DefineField(so, XamlRuntimeContextDefintion.ProvideTargetObjectName, true, false); + PropertyTargetProperty = builder.DefineField(so, XamlRuntimeContextDefintion.ProvideTargetPropertyName, true, false); ImplementInterfacePropertyGetter(builder, mappings.ProvideValueTarget, "TargetObject") .Generator.LdThisFld(PropertyTargetObject).Ret(); ImplementInterfacePropertyGetter(builder, mappings.ProvideValueTarget, "TargetProperty") @@ -238,12 +195,12 @@ private XamlXContextDefinition(IXamlXTypeBuilder parentBuilder, ownServices.Add(mappings.ProvideValueTarget); } - IXamlXField baseUriField = null; + IXamlField baseUriField = null; if (mappings.UriContextProvider != null) { baseUriField = builder.DefineField(systemUri, "_baseUri", false, false); builder.AddInterfaceImplementation(mappings.UriContextProvider); - var getter = builder.DefineMethod(systemUri, new IXamlXType[0], "get_BaseUri", true, false, true); + var getter = builder.DefineMethod(systemUri, new IXamlType[0], "get_BaseUri", true, false, true); var setter = builder.DefineMethod(typeSystem.GetType("System.Void"), new[] {systemUri}, "set_BaseUri", true, false, true); @@ -394,7 +351,7 @@ private XamlXContextDefinition(IXamlXTypeBuilder parentBuilder, .Brfalse(noUri) .Emit(OpCodes.Ldarg_0) .Emit(OpCodes.Ldarg_3) - .Newobj(systemUri.FindConstructor(new List + .Newobj(systemUri.FindConstructor(new List { typeSystem.GetType("System.String") })) @@ -404,8 +361,8 @@ private XamlXContextDefinition(IXamlXTypeBuilder parentBuilder, foreach (var feature in ctorCallbacks) feature(ctor.Generator); - - mappings.ContextTypeBuilderCallback?.Invoke(builder, ctor.Generator); + + emitMappings.ContextTypeBuilderCallback?.Invoke(builder, ctor.Generator); // We are calling this last to ensure that our own services are ready if (_innerServiceProviderField != null) @@ -433,25 +390,31 @@ public void CreateAllTypes() cb(); } - private void EmitPushPopParent(IXamlXTypeBuilder builder, IXamlXTypeSystem ts) + private void EmitPushPopParent(IXamlTypeBuilder builder, IXamlTypeSystem ts) { var @void = ts.GetType("System.Void"); var so = ts.GetType("System.Object"); var objectListType = ts.GetType("System.Collections.Generic.List`1") .MakeGenericType(new[] {so}); - builder.DefineMethod(@void, new[] {so}, PushParentMethodName, true, false, false) - .Generator - .LdThisFld(ParentListField) + var pushParentGenerator = + builder.DefineMethod(@void, new[] {so}, XamlRuntimeContextDefintion.PushParentMethodName, true, false, false) + .Generator; + + pushParentGenerator.LdThisFld(ParentListField) .Ldarg(1) .EmitCall(objectListType.FindMethod("Add", @void, - false, so)) - .Ldarg_0() - .Ldarg(1) - .Stfld(PropertyTargetObject) - .Ret(); + false, so)); - var pop = builder.DefineMethod(@void, new IXamlXType[0], PopParentMethodName, true, false, false) + if (PropertyTargetObject != null) + { + pushParentGenerator.Ldarg_0() + .Ldarg(1) + .Stfld(PropertyTargetObject) + .Ret(); + } + + var pop = builder.DefineMethod(@void, new IXamlType[0], XamlRuntimeContextDefintion.PopParentMethodName, true, false, false) .Generator; var idx = pop.DefineLocal(ts.GetType("System.Int32")); @@ -459,34 +422,39 @@ private void EmitPushPopParent(IXamlXTypeBuilder builder, IXamlXTypeSystem ts) // var idx = _parents.Count - 1; .LdThisFld(ParentListField) .EmitCall(objectListType.FindMethod(m => m.Name == "get_Count")) - .Ldc_I4(1).Emit(OpCodes.Sub).Stloc(idx) + .Ldc_I4(1).Emit(OpCodes.Sub).Stloc(idx); // this.PropertyTargetObject = _parents[idx]; - .Ldarg_0() - .LdThisFld(ParentListField) - .Ldloc(idx) - .EmitCall(objectListType.FindMethod(m => m.Name == "get_Item")) - .Stfld(PropertyTargetObject) + if (PropertyTargetObject != null) + { + pop + .Ldarg_0() + .LdThisFld(ParentListField) + .Ldloc(idx) + .EmitCall(objectListType.FindMethod(m => m.Name == "get_Item")) + .Stfld(PropertyTargetObject); + } // _parents.RemoveAt(idx); + pop .LdThisFld(ParentListField) .Ldloc(idx).EmitCall(objectListType.FindMethod(m => m.Name == "RemoveAt")) .Ret(); } - private IXamlXMethodBuilder ImplementInterfacePropertyGetter(IXamlXTypeBuilder builder , - IXamlXType type, string name) + private IXamlMethodBuilder ImplementInterfacePropertyGetter(IXamlTypeBuilder builder , + IXamlType type, string name) { var prefix = type.Namespace + "." + type.Name + "."; var originalGetter = type.FindMethod(m => m.Name == "get_" + name); - var gen = builder.DefineMethod(originalGetter.ReturnType, new IXamlXType[0], + var gen = builder.DefineMethod(originalGetter.ReturnType, new IXamlType[0], prefix + "get_" + name, false, false, true, originalGetter); builder.DefineProperty(originalGetter.ReturnType,prefix+ name, null, gen); return gen; } - IXamlXType EmitTypeDescriptorContextStub(IXamlXTypeSystem typeSystem, IXamlXTypeBuilder builder, - XamlXLanguageTypeMappings mappings) + IXamlType EmitTypeDescriptorContextStub(IXamlTypeSystem typeSystem, IXamlTypeBuilder builder, + XamlLanguageTypeMappings mappings) { if (mappings.TypeDescriptorContext == null) return null; @@ -507,7 +475,7 @@ void MethodStub(string name) original) .Generator .Emit(OpCodes.Newobj, - typeSystem.FindType("System.NotSupportedException").FindConstructor(new List())) + typeSystem.FindType("System.NotSupportedException").FindConstructor(new List())) .Emit(OpCodes.Throw); } @@ -517,8 +485,8 @@ void MethodStub(string name) return mappings.TypeDescriptorContext; } - (IXamlXType type, IXamlXConstructor ctor, Action createCallback) EmitParentEnumerable(IXamlXTypeSystem typeSystem, IXamlXTypeBuilder parentBuilder, - XamlXLanguageTypeMappings mappings) + (IXamlType type, IXamlConstructor ctor, Action createCallback) EmitParentEnumerable(IXamlTypeSystem typeSystem, IXamlTypeBuilder parentBuilder, + XamlLanguageTypeMappings mappings) { var so = typeSystem.GetType("System.Object"); var enumerableBuilder = @@ -579,7 +547,7 @@ void MethodStub(string name) .Emit(OpCodes.Stfld, parentProvider) .Emit(OpCodes.Ret); - var currentGetter = enumeratorBuilder.DefineMethod(so, new IXamlXType[0], + var currentGetter = enumeratorBuilder.DefineMethod(so, new IXamlType[0], "get_Current", true, false, true); enumeratorBuilder.DefineProperty(so, "Current", null, currentGetter); currentGetter.Generator @@ -587,13 +555,13 @@ void MethodStub(string name) .Emit(OpCodes.Ldfld, current) .Emit(OpCodes.Ret); - enumeratorBuilder.DefineMethod(typeSystem.FindType("System.Void"), new IXamlXType[0], "Reset", true, false, + enumeratorBuilder.DefineMethod(typeSystem.FindType("System.Void"), new IXamlType[0], "Reset", true, false, true).Generator .Emit(OpCodes.Newobj, - typeSystem.FindType("System.NotSupportedException").FindConstructor(new List())) + typeSystem.FindType("System.NotSupportedException").FindConstructor(new List())) .Emit(OpCodes.Throw); - var disposeGen = enumeratorBuilder.DefineMethod(typeSystem.FindType("System.Void"), new IXamlXType[0], + var disposeGen = enumeratorBuilder.DefineMethod(typeSystem.FindType("System.Void"), new IXamlType[0], "Dispose", true, false, true ).Generator; var disposeRet = disposeGen.DefineLabel(); disposeGen @@ -607,7 +575,7 @@ void MethodStub(string name) .Emit(OpCodes.Ret); var boolType = typeSystem.GetType("System.Boolean"); - var moveNext = enumeratorBuilder.DefineMethod(boolType, new IXamlXType[0], + var moveNext = enumeratorBuilder.DefineMethod(boolType, new IXamlType[0], "MoveNext", true, false, true).Generator; @@ -681,7 +649,7 @@ void MethodStub(string name) .Ldarg_0().Ldc_I4(stateEof).Stfld(state) .Ldc_I4(0).Ret(); - var createEnumerator = enumerableBuilder.DefineMethod(enumeratorObjectType, new IXamlXType[0], "GetEnumerator", true, false, + var createEnumerator = enumerableBuilder.DefineMethod(enumeratorObjectType, new IXamlType[0], "GetEnumerator", true, false, true); createEnumerator.Generator .LdThisFld(enumerableParentList) @@ -689,7 +657,7 @@ void MethodStub(string name) .Emit(OpCodes.Newobj, enumeratorCtor) .Emit(OpCodes.Ret); - enumerableBuilder.DefineMethod(enumeratorType, new IXamlXType[0], + enumerableBuilder.DefineMethod(enumeratorType, new IXamlType[0], "System.Collections.IEnumerable.GetEnumerator", false, false, true, typeSystem.GetType("System.Collections.IEnumerable").FindMethod(m => m.Name == "GetEnumerator")) .Generator diff --git a/src/XamlX/TypeSystem/SreTypeSystem.cs b/src/XamlX/IL/SreTypeSystem.cs similarity index 70% rename from src/XamlX/TypeSystem/SreTypeSystem.cs rename to src/XamlX/IL/SreTypeSystem.cs index 3537452a..70404608 100644 --- a/src/XamlX/TypeSystem/SreTypeSystem.cs +++ b/src/XamlX/IL/SreTypeSystem.cs @@ -5,16 +5,17 @@ using System.Linq; using System.Reflection; using System.Reflection.Emit; -#if !XAMLIL_NO_SRE -namespace XamlX.TypeSystem +using XamlX.TypeSystem; +#if !XAMLX_NO_SRE +namespace XamlX.IL { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class SreTypeSystem : IXamlXTypeSystem + class SreTypeSystem : IXamlTypeSystem { - private List _assemblies = new List(); - public IReadOnlyList Assemblies => _assemblies; + private List _assemblies = new List(); + public IReadOnlyList Assemblies => _assemblies; private Dictionary _typeDic = new Dictionary(); @@ -34,7 +35,7 @@ public SreTypeSystem() } } - public IXamlXAssembly FindAssembly(string name) + public IXamlAssembly FindAssembly(string name) { return Assemblies.FirstOrDefault(a => a.Name.ToLowerInvariant() == name.ToLowerInvariant()); } @@ -60,7 +61,7 @@ SreType ResolveType(Type t) return rv; } - public IXamlXType FindType(string name, string asm) + public IXamlType FindType(string name, string asm) { if (asm != null) name += ", " + asm; @@ -69,7 +70,7 @@ public IXamlXType FindType(string name, string asm) return null; return ResolveType(found); } - public IXamlXType FindType(string name) + public IXamlType FindType(string name) { foreach (var asm in Assemblies) { @@ -81,10 +82,10 @@ public IXamlXType FindType(string name) return null; } - class SreAssembly : IXamlXAssembly + class SreAssembly : IXamlAssembly { private readonly SreTypeSystem _system; - private IReadOnlyList _customAttributes; + private IReadOnlyList _customAttributes; public Assembly Assembly { get; } public SreAssembly(SreTypeSystem system, Assembly asm) @@ -94,19 +95,19 @@ public SreAssembly(SreTypeSystem system, Assembly asm) } - public bool Equals(IXamlXAssembly other) => Assembly == ((SreAssembly) other)?.Assembly; + public bool Equals(IXamlAssembly other) => Assembly == ((SreAssembly) other)?.Assembly; public string Name => Assembly.GetName().Name; - public IReadOnlyList Types { get; private set; } + public IReadOnlyList Types { get; private set; } private Dictionary _typeDic = new Dictionary(); - public IReadOnlyList CustomAttributes + public IReadOnlyList CustomAttributes => _customAttributes ?? (_customAttributes = Assembly.GetCustomAttributesData().Select(a => new SreCustomAttribute( _system, a, _system.ResolveType(a.AttributeType))).ToList()); - public IXamlXType FindType(string fullName) + public IXamlType FindType(string fullName) { _typeDic.TryGetValue(fullName, out var rv); return rv; @@ -124,7 +125,7 @@ class SreMemberInfo { protected readonly SreTypeSystem System; private readonly MemberInfo _member; - private IReadOnlyList _customAttributes; + private IReadOnlyList _customAttributes; public string Name => _member.Name; public SreMemberInfo(SreTypeSystem system, MemberInfo member) { @@ -132,23 +133,23 @@ public SreMemberInfo(SreTypeSystem system, MemberInfo member) _member = member; } - public IReadOnlyList CustomAttributes + public IReadOnlyList CustomAttributes => _customAttributes ?? (_customAttributes = _member.GetCustomAttributesData().Select(a => new SreCustomAttribute(System, a, System.ResolveType(a.AttributeType))).ToList()); } [DebuggerDisplay("{" + nameof(Type) + "}")] - class SreType : SreMemberInfo, IXamlXType + class SreType : SreMemberInfo, IXamlType { - private IReadOnlyList _properties; - private IReadOnlyList _fields; - private IReadOnlyList _methods; - private IReadOnlyList _constructors; - private IReadOnlyList _genericArguments; - private IReadOnlyList _genericParameters; - private IReadOnlyList _interfaces; - private IReadOnlyList _events; + private IReadOnlyList _properties; + private IReadOnlyList _fields; + private IReadOnlyList _methods; + private IReadOnlyList _constructors; + private IReadOnlyList _genericArguments; + private IReadOnlyList _genericParameters; + private IReadOnlyList _interfaces; + private IReadOnlyList _events; public Type Type { get; } public SreType(SreTypeSystem system, SreAssembly asm, Type type): base(system, type) @@ -157,67 +158,67 @@ public SreType(SreTypeSystem system, SreAssembly asm, Type type): base(system, t Type = type; } - public bool Equals(IXamlXType other) => Type == (other as SreType)?.Type; + public bool Equals(IXamlType other) => Type == (other as SreType)?.Type; public override int GetHashCode() => Type.GetHashCode(); public object Id => Type; public string FullName => Type.FullName; public string Namespace => Type.Namespace; - public IXamlXAssembly Assembly { get; } + public IXamlAssembly Assembly { get; } - public IReadOnlyList Properties => + public IReadOnlyList Properties => _properties ?? (_properties = Type .GetProperties(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly) .Select(p => new SreProperty(System, p)).ToList()); - public IReadOnlyList Fields => + public IReadOnlyList Fields => _fields ?? (_fields = Type.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly) .Select(f => new SreField(System, f)).ToList()); - public IReadOnlyList Methods => + public IReadOnlyList Methods => _methods ?? (_methods = Type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly) .Select(m => new SreMethod(System, m)).ToList()); - public IReadOnlyList Constructors => + public IReadOnlyList Constructors => _constructors ?? (_constructors = Type.GetConstructors( BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static) .Select(c => new SreConstructor(System, c)).ToList()); - public IReadOnlyList Interfaces => + public IReadOnlyList Interfaces => _interfaces ?? (_interfaces = Type.GetInterfaces().Select(System.ResolveType).ToList()); - public IReadOnlyList Events => + public IReadOnlyList Events => _events ?? (_events = Type .GetEvents(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance) .Select(e => new SreEvent(System, e)).ToList()); public bool IsInterface => Type.IsInterface; - public IReadOnlyList GenericArguments + public IReadOnlyList GenericArguments { get { if (_genericArguments != null) return _genericArguments; if (GenericTypeDefinition == null) - return _genericArguments = new IXamlXType[0]; + return _genericArguments = new IXamlType[0]; return _genericArguments = Type.GetGenericArguments().Select(System.ResolveType).ToList(); } } - public IReadOnlyList GenericParameters => + public IReadOnlyList GenericParameters => _genericParameters ?? (_genericParameters = Type.GetTypeInfo().GenericTypeParameters.Select(System.ResolveType).ToList()); - public bool IsAssignableFrom(IXamlXType type) + public bool IsAssignableFrom(IXamlType type) { - if (type == XamlXPseudoType.Null) + if (type == XamlPseudoType.Null) { if (!Type.IsValueType) return true; @@ -231,37 +232,37 @@ public bool IsAssignableFrom(IXamlXType type) return false; } - public IXamlXType MakeGenericType(IReadOnlyList typeArguments) + public IXamlType MakeGenericType(IReadOnlyList typeArguments) { return System.ResolveType( Type.MakeGenericType(typeArguments.Select(t => ((SreType) t).Type).ToArray())); } - public IXamlXType GenericTypeDefinition => Type.IsConstructedGenericType + public IXamlType GenericTypeDefinition => Type.IsConstructedGenericType ? System.ResolveType(Type.GetGenericTypeDefinition()) : null; public bool IsArray => Type.IsArray; - public IXamlXType ArrayElementType => IsArray ? System.ResolveType(Type.GetElementType()) : null; + public IXamlType ArrayElementType => IsArray ? System.ResolveType(Type.GetElementType()) : null; - public IXamlXType MakeArrayType(int dimensions) => System.ResolveType( + public IXamlType MakeArrayType(int dimensions) => System.ResolveType( dimensions == 1 ? Type.MakeArrayType() : Type.MakeArrayType(dimensions)); - public IXamlXType BaseType => Type.BaseType == null ? null : System.ResolveType(Type.BaseType); + public IXamlType BaseType => Type.BaseType == null ? null : System.ResolveType(Type.BaseType); public bool IsValueType => Type.IsValueType; public bool IsEnum => Type.IsEnum; - public IXamlXType GetEnumUnderlyingType() + public IXamlType GetEnumUnderlyingType() { return System.ResolveType(Enum.GetUnderlyingType(Type)); } public override string ToString() => Type.ToString(); } - class SreCustomAttribute : IXamlXCustomAttribute + class SreCustomAttribute : IXamlCustomAttribute { private readonly CustomAttributeData _data; - public SreCustomAttribute(SreTypeSystem system, CustomAttributeData data, IXamlXType type) + public SreCustomAttribute(SreTypeSystem system, CustomAttributeData data, IXamlType type) { Type = type; _data = data; @@ -272,12 +273,12 @@ public SreCustomAttribute(SreTypeSystem system, CustomAttributeData data, IXamlX new Dictionary(); } - public bool Equals(IXamlXCustomAttribute other) + public bool Equals(IXamlCustomAttribute other) { return ((SreCustomAttribute) other)?._data.Equals(_data) == true; } - public IXamlXType Type { get; } + public IXamlType Type { get; } public List Parameters { get; } public Dictionary Properties { get; } } @@ -287,14 +288,14 @@ class SreMethodBase : SreMemberInfo { private readonly MethodBase _method; - protected IReadOnlyList _parameters; + protected IReadOnlyList _parameters; public SreMethodBase(SreTypeSystem system, MethodBase method) : base(system, method) { _method = method; } public bool IsPublic => _method.IsPublic; public bool IsStatic => _method.IsStatic; - public IReadOnlyList Parameters => + public IReadOnlyList Parameters => _parameters ?? (_parameters = _method.GetParameters() .Select(p => System.ResolveType(p.ParameterType)).ToList()); @@ -302,7 +303,7 @@ public SreMethodBase(SreTypeSystem system, MethodBase method) : base(system, met } [DebuggerDisplay("{Method}")] - class SreMethod : SreMethodBase, IXamlXMethod + class SreMethod : SreMethodBase, IXamlMethod { public MethodInfo Method { get; } private readonly SreTypeSystem _system; @@ -313,18 +314,18 @@ public SreMethod(SreTypeSystem system, MethodInfo method) : base(system, method) _system = system; } - public bool Equals(IXamlXMethod other) => ((SreMethod) other)?.Method.Equals(Method) == true; + public bool Equals(IXamlMethod other) => ((SreMethod) other)?.Method.Equals(Method) == true; - public IXamlXMethod MakeGenericMethod(IReadOnlyList typeArguments) + public IXamlMethod MakeGenericMethod(IReadOnlyList typeArguments) { return new SreMethod(System, Method.MakeGenericMethod(typeArguments.Select(t => ((SreType)t).Type).ToArray())); } - public IXamlXType ReturnType => _system.ResolveType(Method.ReturnType); - public IXamlXType DeclaringType => _system.ResolveType(Method.DeclaringType); + public IXamlType ReturnType => _system.ResolveType(Method.ReturnType); + public IXamlType DeclaringType => _system.ResolveType(Method.DeclaringType); } - class SreConstructor : SreMethodBase, IXamlXConstructor + class SreConstructor : SreMethodBase, IXamlConstructor { public ConstructorInfo Constuctor { get; } public SreConstructor(SreTypeSystem system, ConstructorInfo ctor) : base(system, ctor) @@ -332,13 +333,13 @@ public SreConstructor(SreTypeSystem system, ConstructorInfo ctor) : base(system, Constuctor = ctor; } - public bool Equals(IXamlXConstructor other) + public bool Equals(IXamlConstructor other) => ((SreConstructor) other)?.Constuctor.Equals(Constuctor) == true; } - class SreProperty : SreMemberInfo, IXamlXProperty + class SreProperty : SreMemberInfo, IXamlProperty { - private IReadOnlyList _parameters; + private IReadOnlyList _parameters; public PropertyInfo Member { get; } public SreProperty(SreTypeSystem system, PropertyInfo member) : base(system, member) @@ -348,7 +349,7 @@ public SreProperty(SreTypeSystem system, PropertyInfo member) : base(system, mem Getter = member.GetMethod == null ? null : new SreMethod(system, member.GetMethod); } - public bool Equals(IXamlXProperty other) + public bool Equals(IXamlProperty other) { var otherProp =((SreProperty) other)?.Member; if (otherProp == null) @@ -357,18 +358,18 @@ public bool Equals(IXamlXProperty other) && Member.Name == otherProp.Name; } - public IXamlXType PropertyType => System.ResolveType(Member.PropertyType); - public IXamlXMethod Setter { get; } - public IXamlXMethod Getter { get; } + public IXamlType PropertyType => System.ResolveType(Member.PropertyType); + public IXamlMethod Setter { get; } + public IXamlMethod Getter { get; } - public IReadOnlyList IndexerParameters => + public IReadOnlyList IndexerParameters => _parameters ?? (_parameters = Member.GetIndexParameters() .Select(p => System.ResolveType(p.ParameterType)).ToList()); public override string ToString() => Member.ToString(); } - class SreEvent : SreMemberInfo, IXamlXEventInfo + class SreEvent : SreMemberInfo, IXamlEventInfo { public EventInfo Event { get; } public SreEvent(SreTypeSystem system, EventInfo ev) : base(system, ev) @@ -376,12 +377,12 @@ public SreEvent(SreTypeSystem system, EventInfo ev) : base(system, ev) Event = ev; Add = new SreMethod(system, ev.AddMethod); } - public IXamlXMethod Add { get; } - public bool Equals(IXamlXEventInfo other) => (other as SreEvent)?.Event.Equals(Event) == true; + public IXamlMethod Add { get; } + public bool Equals(IXamlEventInfo other) => (other as SreEvent)?.Event.Equals(Event) == true; public override string ToString() => Event.ToString(); } - class SreField : SreMemberInfo, IXamlXField + class SreField : SreMemberInfo, IXamlField { public FieldInfo Field { get; } @@ -391,7 +392,7 @@ public SreField(SreTypeSystem system, FieldInfo field) : base(system, field) FieldType = system.ResolveType(field.FieldType); } - public IXamlXType FieldType { get; } + public IXamlType FieldType { get; } public bool IsPublic => Field.IsPublic; public bool IsStatic => Field.IsStatic; public bool IsLiteral => Field.IsLiteral; @@ -403,102 +404,102 @@ public object GetLiteralValue() } public override string ToString() => Field.DeclaringType?.FullName + " " + Field.Name; - public bool Equals(IXamlXField other) => ((SreField) other)?.Field.Equals(Field) == true; + public bool Equals(IXamlField other) => ((SreField) other)?.Field.Equals(Field) == true; } - public IXamlXEmitter CreateCodeGen(MethodBuilder mb) + public IXamlILEmitter CreateCodeGen(MethodBuilder mb) { return new IlGen(this, mb.GetILGenerator()); } - public Type GetType(IXamlXType t) => ((SreType) t).Type; - public IXamlXType GetType(Type t) => ResolveType(t); + public Type GetType(IXamlType t) => ((SreType) t).Type; + public IXamlType GetType(Type t) => ResolveType(t); - public IXamlXTypeBuilder CreateTypeBuilder(TypeBuilder builder) => new SreTypeBuilder(this, builder); + public IXamlTypeBuilder CreateTypeBuilder(TypeBuilder builder) => new SreTypeBuilder(this, builder); - class IlGen : IXamlXEmitter + class IlGen : IXamlILEmitter { private readonly ILGenerator _ilg; - public IXamlXTypeSystem TypeSystem { get; } + public IXamlTypeSystem TypeSystem { get; } public IlGen(SreTypeSystem system, ILGenerator ilg) { TypeSystem = system; _ilg = ilg; - LocalsPool = new XamlXLocalsPool(this); + LocalsPool = new XamlLocalsPool(t => this.DefineLocal(t)); } - public IXamlXEmitter Emit(OpCode code) + public IXamlILEmitter Emit(OpCode code) { _ilg.Emit(code); return this; } - public IXamlXEmitter Emit(OpCode code, IXamlXMethod method) + public IXamlILEmitter Emit(OpCode code, IXamlMethod method) { _ilg.Emit(code, ((SreMethod) method).Method); return this; } - public IXamlXEmitter Emit(OpCode code, IXamlXConstructor ctor) + public IXamlILEmitter Emit(OpCode code, IXamlConstructor ctor) { _ilg.Emit(code, ((SreConstructor) ctor).Constuctor); return this; } - public IXamlXEmitter Emit(OpCode code, string arg) + public IXamlILEmitter Emit(OpCode code, string arg) { _ilg.Emit(code, arg); return this; } - public IXamlXEmitter Emit(OpCode code, int arg) + public IXamlILEmitter Emit(OpCode code, int arg) { _ilg.Emit(code, arg); return this; } - public IXamlXEmitter Emit(OpCode code, long arg) + public IXamlILEmitter Emit(OpCode code, long arg) { _ilg.Emit(code, arg); return this; } - public IXamlXEmitter Emit(OpCode code, float arg) + public IXamlILEmitter Emit(OpCode code, float arg) { _ilg.Emit(code, arg); return this; } - public IXamlXEmitter Emit(OpCode code, double arg) + public IXamlILEmitter Emit(OpCode code, double arg) { _ilg.Emit(code, arg); return this; } - public IXamlXLocal DefineLocal(IXamlXType type) + public IXamlLocal DefineLocal(IXamlType type) { return new SreLocal(_ilg.DeclareLocal(((SreType) type).Type)); } - public IXamlXLabel DefineLabel() + public IXamlLabel DefineLabel() { return new SreLabel(_ilg.DefineLabel()); } - public IXamlXEmitter MarkLabel(IXamlXLabel label) + public IXamlILEmitter MarkLabel(IXamlLabel label) { _ilg.MarkLabel(((SreLabel) label).Label); return this; } - public IXamlXEmitter Emit(OpCode code, IXamlXLabel label) + public IXamlILEmitter Emit(OpCode code, IXamlLabel label) { _ilg.Emit(code, ((SreLabel)label).Label); return this; } - public IXamlXEmitter Emit(OpCode code, IXamlXLocal local) + public IXamlILEmitter Emit(OpCode code, IXamlLocal local) { _ilg.Emit(code, ((SreLocal) local).Local); return this; @@ -509,22 +510,22 @@ public void InsertSequencePoint(IFileSource file, int line, int position) { } - public XamlXLocalsPool LocalsPool { get; } + public XamlLocalsPool LocalsPool { get; } - public IXamlXEmitter Emit(OpCode code, IXamlXType type) + public IXamlILEmitter Emit(OpCode code, IXamlType type) { _ilg.Emit(code, ((SreType) type).Type); return this; } - public IXamlXEmitter Emit(OpCode code, IXamlXField field) + public IXamlILEmitter Emit(OpCode code, IXamlField field) { _ilg.Emit(code, ((SreField) field).Field); return this; } - class SreLabel : IXamlXLabel + class SreLabel : IXamlLabel { public Label Label { get; } @@ -534,7 +535,7 @@ public SreLabel(Label label) } } - class SreLocal : IXamlXLocal + class SreLocal : IXamlLocal { public LocalBuilder Local { get; } @@ -545,7 +546,7 @@ public SreLocal(LocalBuilder local) } } - class SreTypeBuilder : SreType, IXamlXTypeBuilder + class SreTypeBuilder : SreType, IXamlTypeBuilder { private readonly SreTypeSystem _system; private readonly TypeBuilder _tb; @@ -556,7 +557,7 @@ public SreTypeBuilder(SreTypeSystem system, TypeBuilder tb) : base(system,null, _tb = tb; } - public IXamlXField DefineField(IXamlXType type, string name, bool isPublic, bool isStatic) + public IXamlField DefineField(IXamlType type, string name, bool isPublic, bool isStatic) { var f = _tb.DefineField(name, ((SreType) type).Type, (isPublic ? FieldAttributes.Public : FieldAttributes.Private) @@ -564,37 +565,37 @@ public IXamlXField DefineField(IXamlXType type, string name, bool isPublic, bool return new SreField(_system, f); } - public void AddInterfaceImplementation(IXamlXType type) + public void AddInterfaceImplementation(IXamlType type) { _tb.AddInterfaceImplementation(((SreType)type).Type); } - class SreMethodBuilder : SreMethod, IXamlXMethodBuilder + class SreMethodBuilder : SreMethod, IXamlMethodBuilder { public MethodBuilder MethodBuilder { get; } public SreMethodBuilder(SreTypeSystem system, MethodBuilder methodBuilder, - IReadOnlyList parameters) : base(system, methodBuilder) + IReadOnlyList parameters) : base(system, methodBuilder) { MethodBuilder = methodBuilder; Generator = new IlGen(system, methodBuilder.GetILGenerator()); _parameters = parameters; } - public IXamlXEmitter Generator { get; } + public IXamlILEmitter Generator { get; } - public void EmitClosure(IEnumerable fields) + public void EmitClosure(IEnumerable fields) { throw new NotImplementedException(); } } - public IXamlXMethodBuilder DefineMethod(IXamlXType returnType, IEnumerable args, string name, + public IXamlMethodBuilder DefineMethod(IXamlType returnType, IEnumerable args, string name, bool isPublic, bool isStatic, - bool isInterfaceImpl, IXamlXMethod overrideMethod) + bool isInterfaceImpl, IXamlMethod overrideMethod) { var ret = ((SreType) returnType).Type; - var largs = (IReadOnlyList)(args?.ToList()) ?? Array.Empty(); + var largs = (IReadOnlyList)(args?.ToList()) ?? Array.Empty(); var argTypes = largs.Cast().Select(t => t.Type); var m = _tb.DefineMethod(name, (isPublic ? MethodAttributes.Public : MethodAttributes.Private) @@ -607,7 +608,7 @@ public IXamlXMethodBuilder DefineMethod(IXamlXType returnType, IEnumerable { public SreConstructorBuilder(SreTypeSystem system, ConstructorBuilder ctor) : base(system, ctor) { Generator = new IlGen(system, ctor.GetILGenerator()); } - public IXamlXEmitter Generator { get; } + public IXamlILEmitter Generator { get; } } - public IXamlXConstructorBuilder DefineConstructor(bool isStatic, params IXamlXType[] args) + public IXamlConstructorBuilder DefineConstructor(bool isStatic, params IXamlType[] args) { var attrs = MethodAttributes.Public; if (isStatic) @@ -639,8 +640,8 @@ public IXamlXConstructorBuilder DefineConstructor(bool isStatic, params IXamlXTy return new SreConstructorBuilder(_system, ctor); } - public IXamlXType CreateType() => new SreType(_system, null, _tb.CreateTypeInfo()); - public IXamlXTypeBuilder DefineSubType(IXamlXType baseType, string name, bool isPublic) + public IXamlType CreateType() => new SreType(_system, null, _tb.CreateTypeInfo()); + public IXamlTypeBuilder DefineSubType(IXamlType baseType, string name, bool isPublic) { var attrs = TypeAttributes.Class; if (isPublic) @@ -654,7 +655,7 @@ public IXamlXTypeBuilder DefineSubType(IXamlXType baseType, string name, bool is return new SreTypeBuilder(_system, builder); } - public void DefineGenericParameters(IReadOnlyList> args) + public void DefineGenericParameters(IReadOnlyList> args) { var builders = _tb.DefineGenericParameters(args.Select(x=>x.Key).ToArray()); for (var c = 0; c < args.Count; c++) @@ -665,7 +666,7 @@ public void DefineGenericParameters(IReadOnlyList ResolveAssembly(asm); + public IXamlAssembly GetAssembly(Assembly asm) => ResolveAssembly(asm); } } #endif diff --git a/src/XamlX/IL/XamlILCompiler.cs b/src/XamlX/IL/XamlILCompiler.cs new file mode 100644 index 00000000..6731d306 --- /dev/null +++ b/src/XamlX/IL/XamlILCompiler.cs @@ -0,0 +1,177 @@ +using System; +using System.Collections.Generic; +using System.Reflection.Emit; +using XamlX.Ast; +using XamlX.Transform; +using XamlX.IL.Emitters; +using XamlX.TypeSystem; +using XamlX.Emit; +using XamlX.Compiler; + +namespace XamlX.IL +{ +#if !XAMLX_INTERNAL + public +#endif + class XamlILCompiler : XamlImperativeCompiler + { + public bool EnableIlVerification + { + get => _configuration.GetOrCreateExtra().EnableILVerification; + set => _configuration.GetOrCreateExtra().EnableILVerification = value; + } + + public XamlILCompiler( + TransformerConfiguration configuration, + XamlLanguageEmitMappings emitMappings, + bool fillWithDefaults) + : base(configuration, emitMappings, fillWithDefaults) + { + if (fillWithDefaults) + { + Emitters.AddRange(new object[] + { + new NewObjectEmitter(), + new TextNodeEmitter(), + new MethodCallEmitter(), + new PropertyAssignmentEmitter(), + new PropertyValueManipulationEmitter(), + new ManipulationGroupEmitter(), + new ValueWithManipulationsEmitter(), + new MarkupExtensionEmitter(), + new ObjectInitializationNodeEmitter() + }); + } + } + + public IXamlType CreateContextType(IXamlTypeBuilder builder) + { + return XamlILContextDefinition.GenerateContextClass(builder, + _configuration.TypeSystem, + _configuration.TypeMappings, + _emitMappings); + } + + protected override XamlEmitContext InitCodeGen( + IFileSource file, + Func> createSubType, + IXamlILEmitter codeGen, XamlRuntimeContext context, + bool needContextLocal) + { + IXamlLocal contextLocal = null; + + if (needContextLocal) + { + contextLocal = codeGen.DefineLocal(context.ContextType); + // Pass IService provider as the first argument to context factory + codeGen + .Emit(OpCodes.Ldarg_0); + context.Factory(codeGen); + codeGen.Emit(OpCodes.Stloc, contextLocal); + } + + var emitContext = new ILEmitContext(codeGen, _configuration, + _emitMappings, context, contextLocal, createSubType, + file, Emitters); + return emitContext; + } + + protected override void CompileBuild( + IFileSource fileSource, + IXamlAstValueNode rootInstance, Func> createSubType, + IXamlILEmitter codeGen, XamlRuntimeContext context, + IXamlMethod compiledPopulate) + { + var needContextLocal = !(rootInstance is XamlAstNewClrObjectNode newObj && newObj.Arguments.Count == 0); + var emitContext = InitCodeGen(fileSource, createSubType, codeGen, context, needContextLocal); + + var rv = codeGen.DefineLocal(rootInstance.Type.GetClrType()); + emitContext.Emit(rootInstance, codeGen, rootInstance.Type.GetClrType()); + codeGen + .Emit(OpCodes.Stloc, rv) + .Emit(OpCodes.Ldarg_0) + .Emit(OpCodes.Ldloc, rv) + .EmitCall(compiledPopulate) + .Emit(OpCodes.Ldloc, rv) + .Emit(OpCodes.Ret); + } + + /// + /// void Populate(IServiceProvider sp, T target); + /// + protected override void CompilePopulate(IFileSource fileSource, IXamlAstManipulationNode manipulation, + Func> createSubType, + IXamlILEmitter codeGen, XamlRuntimeContext context) + { + // Uncomment to inspect generated IL in debugger + //codeGen = new RecordingIlEmitter(codeGen); + var emitContext = InitCodeGen(fileSource, createSubType, codeGen, context, true); + + codeGen + .Emit(OpCodes.Ldloc, emitContext.ContextLocal) + .Emit(OpCodes.Ldarg_1) + .Emit(OpCodes.Stfld, context.RootObjectField) + .Emit(OpCodes.Ldloc, emitContext.ContextLocal) + .Emit(OpCodes.Ldarg_1) + .Emit(OpCodes.Stfld, context.IntermediateRootObjectField) + .Emit(OpCodes.Ldarg_1); + emitContext.Emit(manipulation, codeGen, null); + codeGen.Emit(OpCodes.Ret); + } + + protected override XamlRuntimeContext CreateRuntimeContext( + XamlDocument doc, IXamlType contextType, + IXamlTypeBuilder namespaceInfoBuilder, + string baseUri, IXamlType rootType) + { + var staticProviders = new List(); + + if (namespaceInfoBuilder != null) + { + staticProviders.Add( + NamespaceInfoProvider.EmitNamespaceInfoProvider(_configuration, namespaceInfoBuilder, doc)); + } + + var context = new RuntimeContext(contextType, + rootType, _emitMappings, baseUri, staticProviders); + return context; + } + } + +#if !XAMLX_INTERNAL + public +#endif + class XamlILNodeEmitResult : IXamlEmitResult + { + public int ConsumedItems { get; } + public IXamlType ReturnType { get; set; } + public int ProducedItems => ReturnType == null ? 0 : 1; + public bool AllowCast { get; set; } + + public XamlILNodeEmitResult(int consumedItems, IXamlType returnType = null) + { + ConsumedItems = consumedItems; + ReturnType = returnType; + } + + public static XamlILNodeEmitResult Void(int consumedItems) => new XamlILNodeEmitResult(consumedItems); + + public static XamlILNodeEmitResult Type(int consumedItems, IXamlType type) => + new XamlILNodeEmitResult(consumedItems, type); + } + +#if !XAMLX_INTERNAL + public +#endif + interface IXamlILAstNodeEmitter : IXamlAstNodeEmitter + { + } + +#if !XAMLX_INTERNAL + public +#endif + interface IXamlAstILEmitableNode : IXamlAstEmitableNode + { + } + +} diff --git a/src/XamlX/IL/XamlILEmitterExtensions.cs b/src/XamlX/IL/XamlILEmitterExtensions.cs new file mode 100644 index 00000000..54bbfb45 --- /dev/null +++ b/src/XamlX/IL/XamlILEmitterExtensions.cs @@ -0,0 +1,168 @@ +using System; +using System.Collections.Generic; +using System.Reflection.Emit; +using System.Text; +using XamlX.Emit; +using XamlX.Transform; +using XamlX.TypeSystem; + +namespace XamlX.IL +{ +#if !XAMLX_INTERNAL + public +#endif + static class XamlIlEmitterExtensions + { + public static IXamlILEmitter EmitCall(this IXamlILEmitter emitter, IXamlMethod method, bool swallowResult = false) + { + if (method is IXamlCustomEmitMethod custom) + custom.EmitCall(emitter); + else + emitter.Emit(method.IsStatic ? OpCodes.Call : OpCodes.Callvirt, method); + + if (swallowResult && !(method.ReturnType.Namespace == "System" && method.ReturnType.Name == "Void")) + emitter.Pop(); + return emitter; + } + + public static IXamlILEmitter DebugHatch(this IXamlILEmitter emitter, string message) + { +#if DEBUG + var debug = emitter.TypeSystem.GetType("XamlX.XamlDebugHatch").FindMethod(m => m.Name == "Debug"); + emitter.Emit(OpCodes.Ldstr, message); + emitter.Emit(OpCodes.Call, debug); +#endif + return emitter; + } + + public static IXamlILEmitter Ldarg(this IXamlILEmitter emitter, int arg) + => emitter.Emit(OpCodes.Ldarg, arg); + + public static IXamlILEmitter Ldarg_0(this IXamlILEmitter emitter) + => emitter.Emit(OpCodes.Ldarg_0); + + public static IXamlILEmitter Ldfld(this IXamlILEmitter emitter, IXamlField field) + => emitter.Emit(OpCodes.Ldfld, field); + + public static IXamlILEmitter Ldsfld(this IXamlILEmitter emitter, IXamlField field) + => emitter.Emit(OpCodes.Ldsfld, field); + + public static IXamlILEmitter LdThisFld(this IXamlILEmitter emitter, IXamlField field) + => emitter.Ldarg_0().Emit(OpCodes.Ldfld, field); + + public static IXamlILEmitter Stfld(this IXamlILEmitter emitter, IXamlField field) + => emitter.Emit(OpCodes.Stfld, field); + + public static IXamlILEmitter Stsfld(this IXamlILEmitter emitter, IXamlField field) + => emitter.Emit(OpCodes.Stsfld, field); + + public static IXamlILEmitter Ldloc(this IXamlILEmitter emitter, IXamlLocal local) + => emitter.Emit(OpCodes.Ldloc, local); + + public static IXamlILEmitter Ldloca(this IXamlILEmitter emitter, IXamlLocal local) + => emitter.Emit(OpCodes.Ldloca, local); + + public static IXamlILEmitter Stloc(this IXamlILEmitter emitter, IXamlLocal local) + => emitter.Emit(OpCodes.Stloc, local); + + public static IXamlILEmitter Ldnull(this IXamlILEmitter emitter) => emitter.Emit(OpCodes.Ldnull); + + public static IXamlILEmitter Ldstr(this IXamlILEmitter emitter, string arg) + => arg == null ? emitter.Ldnull() : emitter.Emit(OpCodes.Ldstr, arg); + + public static IXamlILEmitter Throw(this IXamlILEmitter emitter) + => emitter.Emit(OpCodes.Throw); + + public static IXamlILEmitter Ldc_I4(this IXamlILEmitter emitter, int arg) + => arg == 0 + ? emitter.Emit(OpCodes.Ldc_I4_0) + : arg == 1 + ? emitter.Emit(OpCodes.Ldc_I4_1) + : emitter.Emit(OpCodes.Ldc_I4, arg); + + public static IXamlILEmitter Beq(this IXamlILEmitter emitter, IXamlLabel label) + => emitter.Emit(OpCodes.Beq, label); + + public static IXamlILEmitter Blt(this IXamlILEmitter emitter, IXamlLabel label) + => emitter.Emit(OpCodes.Blt, label); + + public static IXamlILEmitter Ble(this IXamlILEmitter emitter, IXamlLabel label) + => emitter.Emit(OpCodes.Ble, label); + + public static IXamlILEmitter Bgt(this IXamlILEmitter emitter, IXamlLabel label) + => emitter.Emit(OpCodes.Bgt, label); + + public static IXamlILEmitter Bge(this IXamlILEmitter emitter, IXamlLabel label) + => emitter.Emit(OpCodes.Bge, label); + + public static IXamlILEmitter Br(this IXamlILEmitter emitter, IXamlLabel label) + => emitter.Emit(OpCodes.Br, label); + + public static IXamlILEmitter Brfalse(this IXamlILEmitter emitter, IXamlLabel label) + => emitter.Emit(OpCodes.Brfalse, label); + + public static IXamlILEmitter Brtrue(this IXamlILEmitter emitter, IXamlLabel label) + => emitter.Emit(OpCodes.Brtrue, label); + + public static IXamlILEmitter Ret(this IXamlILEmitter emitter) + => emitter.Emit(OpCodes.Ret); + + public static IXamlILEmitter Dup(this IXamlILEmitter emitter) + => emitter.Emit(OpCodes.Dup); + + public static IXamlILEmitter Pop(this IXamlILEmitter emitter) + => emitter.Emit(OpCodes.Pop); + + public static IXamlILEmitter Ldtoken(this IXamlILEmitter emitter, IXamlType type) + => emitter.Emit(OpCodes.Ldtoken, type); + + public static IXamlILEmitter Ldtoken(this IXamlILEmitter emitter, IXamlMethod method) + => emitter.Emit(OpCodes.Ldtoken, method); + + public static IXamlILEmitter Ldtype(this IXamlILEmitter emitter, IXamlType type) + { + var conv = emitter.TypeSystem.GetType("System.Type") + .FindMethod(m => m.IsStatic && m.IsPublic && m.Name == "GetTypeFromHandle"); + return emitter.Ldtoken(type).EmitCall(conv); + } + + public static IXamlILEmitter LdMethodInfo(this IXamlILEmitter emitter, IXamlMethod method) + { + var conv = emitter.TypeSystem.GetType("System.Reflection.MethodInfo") + .FindMethod(m => m.IsStatic && m.IsPublic && m.Name == "GetMethodFromHandle"); + return emitter.Ldtoken(method).EmitCall(conv); + } + + public static IXamlILEmitter Ldftn(this IXamlILEmitter emitter, IXamlMethod method) + => emitter.Emit(OpCodes.Ldftn, method); + + public static IXamlILEmitter Isinst(this IXamlILEmitter emitter, IXamlType type) + => emitter.Emit(OpCodes.Isinst, type); + + public static IXamlILEmitter Castclass(this IXamlILEmitter emitter, IXamlType type) + => emitter.Emit(OpCodes.Castclass, type); + + public static IXamlILEmitter Box(this IXamlILEmitter emitter, IXamlType type) + => emitter.Emit(OpCodes.Box, type); + + public static IXamlILEmitter Unbox_Any(this IXamlILEmitter emitter, IXamlType type) + => emitter.Emit(OpCodes.Unbox_Any, type); + + + public static IXamlILEmitter Unbox(this IXamlILEmitter emitter, IXamlType type) + => emitter.Emit(OpCodes.Unbox, type); + + public static IXamlILEmitter Newobj(this IXamlILEmitter emitter, IXamlConstructor ctor) + => emitter.Emit(OpCodes.Newobj, ctor); + + public static IXamlILEmitter Newarr(this IXamlILEmitter emitter, IXamlType type) + => emitter.Emit(OpCodes.Newarr, type); + + public static IXamlILEmitter Ldelem_ref(this IXamlILEmitter emitter) => emitter.Emit(OpCodes.Ldelem_Ref); + public static IXamlILEmitter Stelem_ref(this IXamlILEmitter emitter) => emitter.Emit(OpCodes.Stelem_Ref); + public static IXamlILEmitter Ldlen(this IXamlILEmitter emitter) => emitter.Emit(OpCodes.Ldlen); + + public static IXamlILEmitter Add(this IXamlILEmitter emitter) => emitter.Emit(OpCodes.Add); + + } +} diff --git a/src/XamlX/Parsers/CommaSeparatedParenthesesTreeParser.cs b/src/XamlX/Parsers/CommaSeparatedParenthesesTreeParser.cs index e3063511..c167d843 100644 --- a/src/XamlX/Parsers/CommaSeparatedParenthesesTreeParser.cs +++ b/src/XamlX/Parsers/CommaSeparatedParenthesesTreeParser.cs @@ -3,7 +3,7 @@ namespace XamlX.Parsers { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif sealed class CommaSeparatedParenthesesTreeParser diff --git a/src/XamlX/Parsers/SystemXamlMarkupExtensionParser/MeScanner.Shims.cs b/src/XamlX/Parsers/SystemXamlMarkupExtensionParser/MeScanner.Shims.cs index af20b2cd..7c113824 100644 --- a/src/XamlX/Parsers/SystemXamlMarkupExtensionParser/MeScanner.Shims.cs +++ b/src/XamlX/Parsers/SystemXamlMarkupExtensionParser/MeScanner.Shims.cs @@ -6,14 +6,14 @@ namespace XamlX.Parsers.SystemXamlMarkupExtensionParser { class MeScannerContext { - private readonly Func _typeResolver; - private readonly IXamlXLineInfo _lineInfo; + private readonly Func _typeResolver; + private readonly IXamlLineInfo _lineInfo; - public MeScannerContext(Func typeResolver, IXamlXLineInfo lineInfo) + public MeScannerContext(Func typeResolver, IXamlLineInfo lineInfo) { _typeResolver = typeResolver; _lineInfo = lineInfo; - CurrentType = new MeScannerTypeName(new XamlXAstXmlTypeReference(lineInfo, "invalid", "invalid")); + CurrentType = new MeScannerTypeName(new XamlAstXmlTypeReference(lineInfo, "invalid", "invalid")); } public MeScannerBracketModeParseParameters CurrentBracketModeParseParameters { get; } @@ -22,19 +22,19 @@ public MeScannerContext(Func typeResolver, IXa public MeScannerTypeName CurrentType { get; set; } public MeScannerContext FindNamespaceByPrefix => this; - public Func TypeResolver => _typeResolver; + public Func TypeResolver => _typeResolver; - public XamlXAstNamePropertyReference ResolvePropertyName(string pname) + public XamlAstNamePropertyReference ResolvePropertyName(string pname) { if (pname.Contains(".")) { var parts = pname.Split(new[] { '.' }, 2); var decraringType = _typeResolver(parts[0]); - return new XamlXAstNamePropertyReference(_lineInfo, decraringType, parts[1], + return new XamlAstNamePropertyReference(_lineInfo, decraringType, parts[1], CurrentType.TypeReference); } else - return new XamlXAstNamePropertyReference(_lineInfo, CurrentType.TypeReference, pname, + return new XamlAstNamePropertyReference(_lineInfo, CurrentType.TypeReference, pname, CurrentType.TypeReference); } @@ -42,9 +42,9 @@ public XamlXAstNamePropertyReference ResolvePropertyName(string pname) class MeScannerTypeName { - public XamlXAstXmlTypeReference TypeReference { get; } + public XamlAstXmlTypeReference TypeReference { get; } - public MeScannerTypeName(XamlXAstXmlTypeReference typeReference) + public MeScannerTypeName(XamlAstXmlTypeReference typeReference) { TypeReference = typeReference; } diff --git a/src/XamlX/Parsers/SystemXamlMarkupExtensionParser/MeScanner.cs b/src/XamlX/Parsers/SystemXamlMarkupExtensionParser/MeScanner.cs index 08ead7b1..d1766d81 100644 --- a/src/XamlX/Parsers/SystemXamlMarkupExtensionParser/MeScanner.cs +++ b/src/XamlX/Parsers/SystemXamlMarkupExtensionParser/MeScanner.cs @@ -7,21 +7,23 @@ using System.Diagnostics; using System.Text; -// We are trying to keep the code as close to the original as possible -// so it would be easier to port future changes -// That's why those mappings to shims are here - -using XamlParserContext = XamlX.Parsers.SystemXamlMarkupExtensionParser.MeScannerContext; -using XamlType = XamlX.Parsers.SystemXamlMarkupExtensionParser.MeScannerTypeName; -using XamlMember = XamlX.Ast.XamlXAstNamePropertyReference; -using XamlTypeName = XamlX.Parsers.SystemXamlMarkupExtensionParser.MeScannerTypeName; -using SR = XamlX.Parsers.SystemXamlMarkupExtensionParser.MeScannerSr; -using SRID = XamlX.Parsers.SystemXamlMarkupExtensionParser.MeScannerSRID; -using XamlParseException = XamlX.Parsers.SystemXamlMarkupExtensionParser.MeScannerParseException; -using SpecialBracketCharacters = XamlX.Parsers.SystemXamlMarkupExtensionParser.MeScannerSpecialBracketCharacters; -using KnownStrings = XamlX.Parsers.SystemXamlMarkupExtensionParser.MeScannerKnownStrings; namespace XamlX.Parsers.SystemXamlMarkupExtensionParser { + + // We are trying to keep the code as close to the original as possible + // so it would be easier to port future changes + // That's why those mappings to shims are here + + using XamlParserContext = XamlX.Parsers.SystemXamlMarkupExtensionParser.MeScannerContext; + using XamlType = XamlX.Parsers.SystemXamlMarkupExtensionParser.MeScannerTypeName; + using XamlMember = XamlX.Ast.XamlAstNamePropertyReference; + using XamlTypeName = XamlX.Parsers.SystemXamlMarkupExtensionParser.MeScannerTypeName; + using SR = XamlX.Parsers.SystemXamlMarkupExtensionParser.MeScannerSr; + using SRID = XamlX.Parsers.SystemXamlMarkupExtensionParser.MeScannerSRID; + using XamlParseException = XamlX.Parsers.SystemXamlMarkupExtensionParser.MeScannerParseException; + using SpecialBracketCharacters = XamlX.Parsers.SystemXamlMarkupExtensionParser.MeScannerSpecialBracketCharacters; + using KnownStrings = XamlX.Parsers.SystemXamlMarkupExtensionParser.MeScannerKnownStrings; + // Markup Extension Tokenizer AKA Scanner. enum MeTokenType @@ -604,7 +606,7 @@ private void PushBack() private SpecialBracketCharacters GetBracketCharacterForProperty(string propertyName) { return null; - // XamlX resolves markup extension types after parsing the initial AST, + // Xaml resolves markup extension types after parsing the initial AST, // so custom brackets aren't supported /* SpecialBracketCharacters bracketCharacters = null; diff --git a/src/XamlX/Parsers/SystemXamlMarkupExtensionParser/SystemXamlMarkupExtensionParser.cs b/src/XamlX/Parsers/SystemXamlMarkupExtensionParser/SystemXamlMarkupExtensionParser.cs index d8bc079a..5956731c 100644 --- a/src/XamlX/Parsers/SystemXamlMarkupExtensionParser/SystemXamlMarkupExtensionParser.cs +++ b/src/XamlX/Parsers/SystemXamlMarkupExtensionParser/SystemXamlMarkupExtensionParser.cs @@ -4,23 +4,19 @@ namespace XamlX.Parsers.SystemXamlMarkupExtensionParser { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif class SystemXamlMarkupExtensionParser { - - - - - public static IXamlXAstValueNode Parse(IXamlXLineInfo li, string ext, - Func typeResolver) + public static IXamlAstValueNode Parse(IXamlLineInfo li, string ext, + Func typeResolver) { var ctx = new MeScannerContext(typeResolver, li); var scanner = new MeScanner(ctx, ext, li.Line, li.Position); var currentTypeStack = new Stack(); - IXamlXAstValueNode ReadExtension() + IXamlAstValueNode ReadExtension() { if (scanner.Token != MeTokenType.Open) throw new MeScannerParseException("Unexpected token " + scanner.Token); @@ -33,7 +29,7 @@ IXamlXAstValueNode ReadExtension() currentTypeStack.Push(ctx.CurrentType); ctx.CurrentType = extType; - var rv = new XamlXAstObjectNode(li, extType.TypeReference); + var rv = new XamlAstObjectNode(li, extType.TypeReference); while (true) @@ -48,7 +44,7 @@ IXamlXAstValueNode ReadExtension() if (scanner.Token != MeTokenType.EqualSign) throw new MeScannerParseException("Unexpected token " + scanner.Token); var propValue = Read(); - rv.Children.Add(new XamlXAstXamlPropertyValueNode(li, prop, propValue)); + rv.Children.Add(new XamlAstXamlPropertyValueNode(li, prop, propValue)); } else if (scanner.Token == MeTokenType.String || scanner.Token == MeTokenType.QuotedMarkupExtension || scanner.Token == MeTokenType.Open) @@ -69,17 +65,17 @@ IXamlXAstValueNode ReadExtension() return rv; } - IXamlXAstValueNode Read() + IXamlAstValueNode Read() { scanner.Read(); return ReadCurrent(); } - IXamlXAstValueNode ReadCurrent() + IXamlAstValueNode ReadCurrent() { if (scanner.Token == MeTokenType.String) - return new XamlXAstTextNode(li, scanner.TokenText); + return new XamlAstTextNode(li, scanner.TokenText); if (scanner.Token == MeTokenType.Open) return ReadExtension(); if (scanner.Token == MeTokenType.QuotedMarkupExtension) diff --git a/src/XamlX/Parsers/XDocumentXamlXParser.cs b/src/XamlX/Parsers/XDocumentXamlIlParser.cs similarity index 74% rename from src/XamlX/Parsers/XDocumentXamlXParser.cs rename to src/XamlX/Parsers/XDocumentXamlIlParser.cs index a1f367fd..4fba30d2 100644 --- a/src/XamlX/Parsers/XDocumentXamlXParser.cs +++ b/src/XamlX/Parsers/XDocumentXamlIlParser.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections; using System.Collections.Generic; using System.IO; @@ -10,26 +10,26 @@ namespace XamlX.Parsers { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XDocumentXamlXParserSettings + class XDocumentXamlParserSettings { public Dictionary CompatibleNamespaces { get; set; } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XDocumentXamlXParser + class XDocumentXamlParser { - public static XamlXDocument Parse(string s, Dictionary compatibilityMappings = null) + public static XamlDocument Parse(string s, Dictionary compatibilityMappings = null) { return Parse(new StringReader(s), compatibilityMappings); } - public static XamlXDocument Parse(TextReader reader, Dictionary compatibilityMappings = null) + public static XamlDocument Parse(TextReader reader, Dictionary compatibilityMappings = null) { var xr = XmlReader.Create(reader, new XmlReaderSettings { @@ -40,7 +40,7 @@ public static XamlXDocument Parse(TextReader reader, Dictionary var root = XDocument.Load(xr, LoadOptions.SetLineInfo).Root; - var doc = new XamlXDocument + var doc = new XamlDocument { Root = new ParserContext(root).Parse() }; @@ -67,17 +67,17 @@ public ParserContext(XElement root) } - XamlXAstXmlTypeReference GetTypeReference(XElement el) => - new XamlXAstXmlTypeReference(el.AsLi(), el.Name.NamespaceName, el.Name.LocalName); + XamlAstXmlTypeReference GetTypeReference(XElement el) => + new XamlAstXmlTypeReference(el.AsLi(), el.Name.NamespaceName, el.Name.LocalName); - static XamlXAstXmlTypeReference ParseTypeName(IXamlXLineInfo info, string typeName, XElement xel) + static XamlAstXmlTypeReference ParseTypeName(IXamlLineInfo info, string typeName, XElement xel) => ParseTypeName(info, typeName, ns => string.IsNullOrWhiteSpace(ns) ? xel.GetDefaultNamespace().NamespaceName : xel.GetNamespaceOfPrefix(ns)?.NamespaceName ?? ""); - static XamlXAstXmlTypeReference ParseTypeName(IXamlXLineInfo info, string typeName, Func prefixResolver) + static XamlAstXmlTypeReference ParseTypeName(IXamlLineInfo info, string typeName, Func prefixResolver) { var pair = typeName.Trim().Split(new[] {':'}, 2); string xmlns, name; @@ -90,17 +90,17 @@ static XamlXAstXmlTypeReference ParseTypeName(IXamlXLineInfo info, string typeNa { xmlns = prefixResolver(pair[0]); if (xmlns == null) - throw new XamlXParseException($"Namespace '{pair[0]}' is not recognized", info); + throw new XamlParseException($"Namespace '{pair[0]}' is not recognized", info); name = pair[1]; } - return new XamlXAstXmlTypeReference(info, xmlns, name); + return new XamlAstXmlTypeReference(info, xmlns, name); } - static List ParseTypeArguments(string args, XElement xel, IXamlXLineInfo info) + static List ParseTypeArguments(string args, XElement xel, IXamlLineInfo info) { try { - XamlXAstXmlTypeReference Parse(CommaSeparatedParenthesesTreeParser.Node node) + XamlAstXmlTypeReference Parse(CommaSeparatedParenthesesTreeParser.Node node) { var rv = ParseTypeName(info, node.Value, xel); @@ -113,11 +113,11 @@ XamlXAstXmlTypeReference Parse(CommaSeparatedParenthesesTreeParser.Node node) } catch (CommaSeparatedParenthesesTreeParser.ParseException e) { - throw new XamlXParseException(e.Message, info); + throw new XamlParseException(e.Message, info); } } - static IXamlXAstValueNode ParseTextValueOrMarkupExtension(string ext, XElement xel, IXamlXLineInfo info) + static IXamlAstValueNode ParseTextValueOrMarkupExtension(string ext, XElement xel, IXamlLineInfo info) { if (ext.StartsWith("{") || ext.StartsWith(@"\{")) { @@ -133,20 +133,20 @@ static IXamlXAstValueNode ParseTextValueOrMarkupExtension(string ext, XElement x } catch (MeScannerParseException parseEx) { - throw new XamlXParseException(parseEx.Message, info); + throw new XamlParseException(parseEx.Message, info); } } } - return new XamlXAstTextNode(info, ext); + return new XamlAstTextNode(info, ext); } - XamlXAstObjectNode ParseNewInstance(XElement el, bool root) + XamlAstObjectNode ParseNewInstance(XElement el, bool root) { if (el.Name.LocalName.Contains(".")) throw ParseError(el, "Dots aren't allowed in type names"); var type = GetTypeReference(el); - var i = new XamlXAstObjectNode(el.AsLi(), type); + var i = new XamlAstObjectNode(el.AsLi(), type); foreach (var attr in el.Attributes()) { if (attr.Name.NamespaceName == "http://www.w3.org/2000/xmlns/" || @@ -166,7 +166,7 @@ XamlXAstObjectNode ParseNewInstance(XElement el, bool root) type.GenericArguments = ParseTypeArguments(attr.Value, el, attr.AsLi()); // Parse as a directive else if (attr.Name.NamespaceName != "" && !attr.Name.LocalName.Contains(".")) - i.Children.Add(new XamlXAstXmlDirective(el.AsLi(), + i.Children.Add(new XamlAstXmlDirective(el.AsLi(), attr.Name.NamespaceName, attr.Name.LocalName, new[] { ParseTextValueOrMarkupExtension(attr.Value, el, attr.AsLi()) @@ -183,11 +183,11 @@ XamlXAstObjectNode ParseNewInstance(XElement el, bool root) var parts = pname.Split(new[] {'.'}, 2); pname = parts[1]; var ns = attr.Name.Namespace == "" ? el.GetDefaultNamespace().NamespaceName : attr.Name.NamespaceName; - ptype = new XamlXAstXmlTypeReference(el.AsLi(), ns, parts[0]); + ptype = new XamlAstXmlTypeReference(el.AsLi(), ns, parts[0]); } - i.Children.Add(new XamlXAstXamlPropertyValueNode(el.AsLi(), - new XamlXAstNamePropertyReference(el.AsLi(), ptype, pname, type), + i.Children.Add(new XamlAstXamlPropertyValueNode(el.AsLi(), + new XamlAstNamePropertyReference(el.AsLi(), ptype, pname, type), ParseTextValueOrMarkupExtension(attr.Value, el, attr.AsLi()))); } } @@ -200,10 +200,10 @@ XamlXAstObjectNode ParseNewInstance(XElement el, bool root) if (elementNode.HasAttributes) throw ParseError(node, "Attributes aren't allowed on element properties"); var pair = elementNode.Name.LocalName.Split(new[] {'.'}, 2); - i.Children.Add(new XamlXAstXamlPropertyValueNode(el.AsLi(), new XamlXAstNamePropertyReference + i.Children.Add(new XamlAstXamlPropertyValueNode(el.AsLi(), new XamlAstNamePropertyReference ( el.AsLi(), - new XamlXAstXmlTypeReference(el.AsLi(), elementNode.Name.NamespaceName, + new XamlAstXmlTypeReference(el.AsLi(), elementNode.Name.NamespaceName, pair[0]), pair[1], type ), ParseValueNodeChildren(elementNode) @@ -221,18 +221,18 @@ XamlXAstObjectNode ParseNewInstance(XElement el, bool root) return i; } - IXamlXAstValueNode ParseValueNode(XNode node) + IXamlAstValueNode ParseValueNode(XNode node) { if (node is XElement el) return ParseNewInstance(el, false); if (node is XText text) - return new XamlXAstTextNode(node.AsLi(), text.Value.Trim()); + return new XamlAstTextNode(node.AsLi(), text.Value.Trim()); return null; } - List ParseValueNodeChildren(XElement parent) + List ParseValueNodeChildren(XElement parent) { - var lst = new List(); + var lst = new List(); foreach (var n in parent.Nodes()) { var parsed = ParseValueNode(n); @@ -243,15 +243,15 @@ List ParseValueNodeChildren(XElement parent) } Exception ParseError(IXmlLineInfo line, string message) => - new XamlXParseException(message, line.LineNumber, line.LinePosition); + new XamlParseException(message, line.LineNumber, line.LinePosition); - public XamlXAstObjectNode Parse() => (XamlXAstObjectNode) ParseNewInstance(_root, true); + public XamlAstObjectNode Parse() => (XamlAstObjectNode) ParseNewInstance(_root, true); } } static class Extensions { - class WrappedLineInfo : IXamlXLineInfo + class WrappedLineInfo : IXamlLineInfo { public WrappedLineInfo(IXmlLineInfo info) { @@ -262,7 +262,7 @@ public WrappedLineInfo(IXmlLineInfo info) public int Position { get; set; } } - public static IXamlXLineInfo AsLi(this IXmlLineInfo info) + public static IXamlLineInfo AsLi(this IXmlLineInfo info) { if (!info.HasLineInfo()) throw new InvalidOperationException("XElement doesn't have line info"); diff --git a/src/XamlX/Parsers/XamlMarkupExtensionParser.cs b/src/XamlX/Parsers/XamlMarkupExtensionParser.cs index 5dc2ad29..0b4554a5 100644 --- a/src/XamlX/Parsers/XamlMarkupExtensionParser.cs +++ b/src/XamlX/Parsers/XamlMarkupExtensionParser.cs @@ -4,7 +4,7 @@ namespace XamlX.Parsers { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif sealed class XamlMarkupExtensionParser @@ -35,29 +35,29 @@ enum ParserState RootEnd } - public static XamlXAstObjectNode Parse(IXamlXLineInfo info, string ext, Func typeResolver) + public static XamlAstObjectNode Parse(IXamlLineInfo info, string ext, Func typeResolver) { var root = ParseNode(ext); - IXamlXAstValueNode Convert(object node) + IXamlAstValueNode Convert(object node) { if (node is string s) - return new XamlXAstTextNode(info, s); + return new XamlAstTextNode(info, s); var n = (Node) node; var type = typeResolver(n.Name); type.IsMarkupExtension = true; - var rv = new XamlXAstObjectNode(info, type); + var rv = new XamlAstObjectNode(info, type); foreach (var pa in n.PositionalArguments) rv.Arguments.Add(Convert(pa)); foreach (var arg in n.NamedArguments) - rv.Children.Add(new XamlXAstXamlPropertyValueNode(info, - new XamlXAstNamePropertyReference(info, rv.Type, arg.name, rv.Type), Convert(arg.value))); + rv.Children.Add(new XamlAstXamlPropertyValueNode(info, + new XamlAstNamePropertyReference(info, rv.Type, arg.name, rv.Type), Convert(arg.value))); return rv; } - return (XamlXAstObjectNode) Convert(root); + return (XamlAstObjectNode) Convert(root); } static Node ParseNode(string ext) diff --git a/src/XamlX/Transform/AstTransformationContext.cs b/src/XamlX/Transform/AstTransformationContext.cs new file mode 100644 index 00000000..6462a212 --- /dev/null +++ b/src/XamlX/Transform/AstTransformationContext.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Xml; +using XamlX.Ast; +using XamlX.TypeSystem; + +namespace XamlX.Transform +{ +#if !XAMLX_INTERNAL + public +#endif + class AstTransformationContext : XamlContextBase + { + public Dictionary NamespaceAliases { get; set; } = new Dictionary(); + public TransformerConfiguration Configuration { get; } + public IXamlAstValueNode RootObject { get; set; } + public bool StrictMode { get; } + + public IXamlAstNode Error(IXamlAstNode node, Exception e) + { + if (StrictMode) + throw e; + return node; + } + + public IXamlAstNode ParseError(string message, IXamlAstNode node) => + Error(node, new XamlParseException(message, node)); + + public IXamlAstNode ParseError(string message, IXamlAstNode offender, IXamlAstNode ret) => + Error(ret, new XamlParseException(message, offender)); + + public AstTransformationContext(TransformerConfiguration configuration, + Dictionary namespaceAliases, bool strictMode = true) + { + Configuration = configuration; + NamespaceAliases = namespaceAliases; + StrictMode = strictMode; + } + + class Visitor : IXamlAstVisitor + { + private readonly AstTransformationContext _context; + private readonly IXamlAstTransformer _transformer; + + public Visitor(AstTransformationContext context, IXamlAstTransformer transformer) + { + _context = context; + _transformer = transformer; + } + + public IXamlAstNode Visit(IXamlAstNode node) + { + #if Xaml_DEBUG + return _transformer.Transform(_context, node); + #else + try + { + return _transformer.Transform(_context, node); + } + catch (Exception e) when (!(e is XmlException)) + { + throw new XamlParseException( + "Internal compiler error while transforming node " + node + ":\n" + e, node); + } + #endif + } + + public void Push(IXamlAstNode node) => _context.PushParent(node); + + public void Pop() => _context.PopParent(); + } + + public IXamlAstNode Visit(IXamlAstNode root, IXamlAstTransformer transformer) + { + root = root.Visit(new Visitor(this, transformer)); + return root; + } + + public void VisitChildren(IXamlAstNode root, IXamlAstTransformer transformer) + { + root.VisitChildren(new Visitor(this, transformer)); + } + } +} diff --git a/src/XamlX/Transform/Emitters/MethodCallEmitter.cs b/src/XamlX/Transform/Emitters/MethodCallEmitter.cs deleted file mode 100644 index 6d4faf04..00000000 --- a/src/XamlX/Transform/Emitters/MethodCallEmitter.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System.Reflection.Emit; -using XamlX.Ast; -using XamlX.TypeSystem; - -namespace XamlX.Transform.Emitters -{ -#if !XAMLIL_INTERNAL - public -#endif - class MethodCallEmitter : IXamlXAstNodeEmitter - { - public XamlXNodeEmitResult Emit(IXamlXAstNode node, XamlXEmitContext context, IXamlXEmitter codeGen) - { - if (!(node is XamlXMethodCallBaseNode mc)) - return null; - - bool thisArgFromArgs = node is XamlXStaticOrTargetedReturnMethodCallNode; - bool expectsVoid = node is XamlXNoReturnMethodCallNode; - - - for (var c = 0; c < mc.Arguments.Count; c++) - { - var off = thisArgFromArgs ? 0 : 1; - var expectedType = mc.Method.ParametersWithThis[c + off]; - context.Emit(mc.Arguments[c], codeGen, expectedType); - } - - - - - mc.Method.Emit(context, codeGen, expectsVoid); - - var isVoid = mc.Method.ReturnType.Equals(context.Configuration.WellKnownTypes.Void); - if (!expectsVoid && isVoid) - throw new XamlXLoadException( - $"XamlXStaticReturnMethodCallNode expects a value while {mc.Method.Name} returns void", node); - - var consumed = thisArgFromArgs ? 0 : 1; - return isVoid || expectsVoid - ? XamlXNodeEmitResult.Void(consumed) - : XamlXNodeEmitResult.Type(consumed, mc.Method.ReturnType); - } - } -} diff --git a/src/XamlX/Transform/Emitters/PropertyValueManipulationEmitter.cs b/src/XamlX/Transform/Emitters/PropertyValueManipulationEmitter.cs deleted file mode 100644 index 978f6fc9..00000000 --- a/src/XamlX/Transform/Emitters/PropertyValueManipulationEmitter.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Reflection.Emit; -using XamlX.Ast; -using XamlX.TypeSystem; - -namespace XamlX.Transform.Emitters -{ -#if !XAMLIL_INTERNAL - public -#endif - class PropertyValueManipulationEmitter : IXamlXAstNodeEmitter - { - public XamlXNodeEmitResult Emit(IXamlXAstNode node, XamlXEmitContext context, IXamlXEmitter codeGen) - { - if (!(node is XamlXPropertyValueManipulationNode pvm)) - return null; - codeGen.EmitCall(pvm.Property.Getter); - context.Emit(pvm.Manipulation, codeGen, null); - - return XamlXNodeEmitResult.Void(1); - } - } -} diff --git a/src/XamlX/Transform/Emitters/TextNodeEmitter.cs b/src/XamlX/Transform/Emitters/TextNodeEmitter.cs deleted file mode 100644 index 1d0156f7..00000000 --- a/src/XamlX/Transform/Emitters/TextNodeEmitter.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Reflection.Emit; -using XamlX.Ast; -using XamlX.TypeSystem; - -namespace XamlX.Transform.Emitters -{ -#if !XAMLIL_INTERNAL - public -#endif - class TextNodeEmitter : IXamlXAstNodeEmitter - { - public XamlXNodeEmitResult Emit(IXamlXAstNode node, XamlXEmitContext context, IXamlXEmitter codeGen) - { - if (!(node is XamlXAstTextNode text)) - return null; - if (!text.Type.GetClrType().Equals(context.Configuration.WellKnownTypes.String)) - throw new XamlXLoadException("Text node type wasn't resolved to well-known System.String", node); - codeGen.Emit(OpCodes.Ldstr, text.Text); - return XamlXNodeEmitResult.Type(0, text.Type.GetClrType()); - } - } -} diff --git a/src/XamlX/Transform/Emitters/ValueWithManipulationsEmitter.cs b/src/XamlX/Transform/Emitters/ValueWithManipulationsEmitter.cs deleted file mode 100644 index cce2a34d..00000000 --- a/src/XamlX/Transform/Emitters/ValueWithManipulationsEmitter.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Reflection.Emit; -using XamlX.Ast; -using XamlX.TypeSystem; - -namespace XamlX.Transform.Emitters -{ -#if !XAMLIL_INTERNAL - public -#endif - class ValueWithManipulationsEmitter : IXamlXAstNodeEmitter - { - public XamlXNodeEmitResult Emit(IXamlXAstNode node, XamlXEmitContext context, IXamlXEmitter codeGen) - { - if (!(node is XamlXValueWithManipulationNode vwm)) - return null; - var created = context.Emit(vwm.Value, codeGen, vwm.Type.GetClrType()); - - if (vwm.Manipulation != null && - !(vwm.Manipulation is XamlXManipulationGroupNode grp && grp.Children.Count == 0)) - { - codeGen.Emit(OpCodes.Dup); - context.Emit(vwm.Manipulation, codeGen, null); - } - return XamlXNodeEmitResult.Type(0, created.ReturnType); - } - } -} diff --git a/src/XamlX/Transform/IXamlAstTransformer.cs b/src/XamlX/Transform/IXamlAstTransformer.cs new file mode 100644 index 00000000..68c5654b --- /dev/null +++ b/src/XamlX/Transform/IXamlAstTransformer.cs @@ -0,0 +1,13 @@ +using XamlX.Ast; +using XamlX.Transform; + +namespace XamlX.Transform +{ +#if !XAMLX_INTERNAL + public +#endif + interface IXamlAstTransformer + { + IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node); + } +} diff --git a/src/XamlX/Transform/NamespaceInfoHelper.cs b/src/XamlX/Transform/NamespaceInfoHelper.cs new file mode 100644 index 00000000..229d4b00 --- /dev/null +++ b/src/XamlX/Transform/NamespaceInfoHelper.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection.Emit; +using XamlX.Ast; +using XamlX.TypeSystem; + +namespace XamlX.Transform +{ +#if !XAMLX_INTERNAL + public +#endif + static class NamespaceInfoHelper + { + public class NamespaceResolveResult + { + public string ClrNamespace { get; set; } + public IXamlAssembly Assembly { get; set; } + public string AssemblyName { get; set; } + } + + public static List TryResolve(TransformerConfiguration config, string xmlns) + { + if (config.XmlnsMappings.Namespaces.TryGetValue(xmlns, out var lst)) + { + return lst.Select(p => new NamespaceResolveResult + { + ClrNamespace = p.ns, + Assembly = p.asm + }).ToList(); + } + + const string clrNamespace = "clr-namespace:"; + const string assemblyNamePrefix = ";assembly="; + if (xmlns.StartsWith(clrNamespace)) + { + var ns = xmlns.Substring(clrNamespace.Length); + + var indexOfAssemblyPrefix = ns.IndexOf(assemblyNamePrefix, StringComparison.Ordinal); + string asm = config.DefaultAssembly?.Name; + if (indexOfAssemblyPrefix != -1) + { + asm = ns.Substring(indexOfAssemblyPrefix + assemblyNamePrefix.Length).Trim(); + ns = ns.Substring(0, indexOfAssemblyPrefix); + } + return new List + { + new NamespaceResolveResult + { + ClrNamespace = ns, + AssemblyName = asm + } + }; + } + + return null; + } + } +} diff --git a/src/XamlX/Transform/XamlXTransformerConfiguration.cs b/src/XamlX/Transform/TransformerConfiguration.cs similarity index 59% rename from src/XamlX/Transform/XamlXTransformerConfiguration.cs rename to src/XamlX/Transform/TransformerConfiguration.cs index 26d98758..c6bcc648 100644 --- a/src/XamlX/Transform/XamlXTransformerConfiguration.cs +++ b/src/XamlX/Transform/TransformerConfiguration.cs @@ -8,10 +8,10 @@ namespace XamlX.Transform { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXTransformerConfiguration + class TransformerConfiguration { private Dictionary _extras = new Dictionary(); /// @@ -19,41 +19,51 @@ class XamlXTransformerConfiguration /// public T GetExtra() => (T) _extras[typeof(T)]; /// + /// Gets or create extension configuration section + /// + public T GetOrCreateExtra() + where T : new() + { + if (!_extras.TryGetValue(typeof(T), out var rv)) + _extras[typeof(T)] = rv = new T(); + return (T)rv; + } + /// /// Adds extension configuration section /// /// /// public void AddExtra(T extra) => _extras[typeof(T)] = extra; - public delegate bool XamlXValueConverter(XamlXAstTransformationContext context, - IXamlXAstValueNode node, IXamlXType type, out IXamlXAstValueNode result); + public delegate bool XamlValueConverter(AstTransformationContext context, + IXamlAstValueNode node, IXamlType type, out IXamlAstValueNode result); - public IXamlXTypeSystem TypeSystem { get; } - public IXamlXAssembly DefaultAssembly { get; } - public XamlXLanguageTypeMappings TypeMappings { get; } - public XamlXXmlnsMappings XmlnsMappings { get; } - public XamlXTypeWellKnownTypes WellKnownTypes { get; } - public XamlXValueConverter CustomValueConverter { get; } + public IXamlTypeSystem TypeSystem { get; } + public IXamlAssembly DefaultAssembly { get; } + public XamlLanguageTypeMappings TypeMappings { get; } + public XamlXmlnsMappings XmlnsMappings { get; } + public XamlTypeWellKnownTypes WellKnownTypes { get; } + public XamlValueConverter CustomValueConverter { get; } public List<(string ns, string name)> KnownDirectives { get; } = new List<(string, string)> { }; - public XamlXTransformerConfiguration(IXamlXTypeSystem typeSystem, IXamlXAssembly defaultAssembly, - XamlXLanguageTypeMappings typeMappings, XamlXXmlnsMappings xmlnsMappings = null, - XamlXValueConverter customValueConverter = null) + public TransformerConfiguration(IXamlTypeSystem typeSystem, IXamlAssembly defaultAssembly, + XamlLanguageTypeMappings typeMappings, XamlXmlnsMappings xmlnsMappings = null, + XamlValueConverter customValueConverter = null) { TypeSystem = typeSystem; DefaultAssembly = defaultAssembly; TypeMappings = typeMappings; - XmlnsMappings = xmlnsMappings ?? XamlXXmlnsMappings.Resolve(typeSystem, typeMappings); - WellKnownTypes = new XamlXTypeWellKnownTypes(typeSystem); + XmlnsMappings = xmlnsMappings ?? XamlXmlnsMappings.Resolve(typeSystem, typeMappings); + WellKnownTypes = new XamlTypeWellKnownTypes(typeSystem); CustomValueConverter = customValueConverter; } - IDictionary _contentPropertyCache = new Dictionary(); + IDictionary _contentPropertyCache = new Dictionary(); - public IXamlXProperty FindContentProperty(IXamlXType type) + public IXamlProperty FindContentProperty(IXamlType type) { if (TypeMappings.ContentAttributes.Count == 0) return null; @@ -69,7 +79,7 @@ public IXamlXProperty FindContentProperty(IXamlXType type) if (GetCustomAttribute(p, TypeMappings.ContentAttributes).Any()) { if (found != null && !p.Equals(found)) - throw new XamlXTypeSystemException( + throw new XamlTypeSystemException( "Content (or substitute) attribute is declared on multiple properties of " + type.GetFqn()); found = p; } @@ -79,7 +89,7 @@ public IXamlXProperty FindContentProperty(IXamlXType type) } - public IEnumerable GetCustomAttribute(IXamlXType type, IXamlXType attributeType) + public IEnumerable GetCustomAttribute(IXamlType type, IXamlType attributeType) { var custom = TypeMappings.CustomAttributeResolver?.GetCustomAttribute(type, attributeType); if (custom != null) @@ -89,7 +99,7 @@ public IEnumerable GetCustomAttribute(IXamlXType type, IX yield return attr; } - public IEnumerable GetCustomAttribute(IXamlXType type, IEnumerable types) + public IEnumerable GetCustomAttribute(IXamlType type, IEnumerable types) { foreach(var t in types) foreach (var a in GetCustomAttribute(type, t)) @@ -97,7 +107,7 @@ public IEnumerable GetCustomAttribute(IXamlXType type, IE } - public IEnumerable GetCustomAttribute(IXamlXProperty prop, IXamlXType attributeType) + public IEnumerable GetCustomAttribute(IXamlProperty prop, IXamlType attributeType) { var custom = TypeMappings.CustomAttributeResolver?.GetCustomAttribute(prop, attributeType); if (custom != null) @@ -107,7 +117,7 @@ public IEnumerable GetCustomAttribute(IXamlXProperty prop yield return attr; } - public IEnumerable GetCustomAttribute(IXamlXProperty prop, IEnumerable types) + public IEnumerable GetCustomAttribute(IXamlProperty prop, IEnumerable types) { foreach(var t in types) foreach (var a in GetCustomAttribute(prop, t)) @@ -115,26 +125,26 @@ public IEnumerable GetCustomAttribute(IXamlXProperty prop } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXTypeWellKnownTypes + class XamlTypeWellKnownTypes { - public IXamlXType IList { get; } - public IXamlXType IEnumerable { get; } - public IXamlXType IEnumerableT { get; } - public IXamlXType IListOfT { get; } - public IXamlXType Object { get; } - public IXamlXType String { get; } - public IXamlXType Void { get; } - public IXamlXType Boolean { get; } - public IXamlXType Double { get; } - public IXamlXType NullableT { get; } - public IXamlXType CultureInfo { get; } - public IXamlXType IFormatProvider { get; } - public IXamlXType Delegate { get; } + public IXamlType IList { get; } + public IXamlType IEnumerable { get; } + public IXamlType IEnumerableT { get; } + public IXamlType IListOfT { get; } + public IXamlType Object { get; } + public IXamlType String { get; } + public IXamlType Void { get; } + public IXamlType Boolean { get; } + public IXamlType Double { get; } + public IXamlType NullableT { get; } + public IXamlType CultureInfo { get; } + public IXamlType IFormatProvider { get; } + public IXamlType Delegate { get; } - public XamlXTypeWellKnownTypes(IXamlXTypeSystem typeSystem) + public XamlTypeWellKnownTypes(IXamlTypeSystem typeSystem) { Void = typeSystem.GetType("System.Void"); String = typeSystem.GetType("System.String"); diff --git a/src/XamlX/Transform/Transformers/XamlXNewObjectTransformer.cs b/src/XamlX/Transform/Transformers/ConstructableObjectTransformer.cs similarity index 54% rename from src/XamlX/Transform/Transformers/XamlXNewObjectTransformer.cs rename to src/XamlX/Transform/Transformers/ConstructableObjectTransformer.cs index 1f783f0a..40fa6959 100644 --- a/src/XamlX/Transform/Transformers/XamlXNewObjectTransformer.cs +++ b/src/XamlX/Transform/Transformers/ConstructableObjectTransformer.cs @@ -1,21 +1,23 @@ +using System; using System.Collections.Generic; using System.Linq; +using System.Text; using XamlX.Ast; -using XamlX.Transform.Emitters; using XamlX.TypeSystem; namespace XamlX.Transform.Transformers { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXNewObjectTransformer : IXamlXAstTransformer + class ConstructableObjectTransformer : IXamlAstTransformer { - IXamlXConstructor TransformArgumentsAndGetConstructor(XamlXAstTransformationContext context, - XamlXAstObjectNode n) + IXamlConstructor TransformArgumentsAndGetConstructor( + AstTransformationContext context, + XamlAstObjectNode n) { var type = n.Type.GetClrType(); - + var argTypes = n.Arguments.Select(a => a.Type.GetClrType()).ToList(); var ctor = type.FindConstructor(argTypes); if (ctor == null) @@ -24,19 +26,19 @@ IXamlXConstructor TransformArgumentsAndGetConstructor(XamlXAstTransformationCont { ctor = type.Constructors.FirstOrDefault(x => !x.IsStatic && x.IsPublic && x.Parameters.Count == argTypes.Count); - + } if (ctor == null) - throw new XamlXLoadException( + throw new XamlLoadException( $"Unable to find public constructor for type {type.GetFqn()}({string.Join(", ", argTypes.Select(at => at.GetFqn()))})", n); } for (var c = 0; c < n.Arguments.Count; c++) { - if (!XamlXTransformHelpers.TryGetCorrectlyTypedValue(context, n.Arguments[c], ctor.Parameters[c], out var arg)) - throw new XamlXLoadException( + if (!XamlTransformHelpers.TryGetCorrectlyTypedValue(context, n.Arguments[c], ctor.Parameters[c], out var arg)) + throw new XamlLoadException( $"Unable to convert {n.Arguments[c].Type.GetClrType().GetFqn()} to {ctor.Parameters[c].GetFqn()} for constructor of {n.Type.GetClrType().GetFqn()}", n.Arguments[c]); n.Arguments[c] = arg; @@ -44,25 +46,20 @@ IXamlXConstructor TransformArgumentsAndGetConstructor(XamlXAstTransformationCont return ctor; } - - public IXamlXAstNode Transform(XamlXAstTransformationContext context, IXamlXAstNode node) + + public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node) { - if (node is XamlXAstObjectNode ni) + if (node is XamlAstObjectNode ni) { var t = ni.Type.GetClrType(); if (t.IsValueType) - throw new XamlXLoadException( - "Value types can only be loaded via converters. We don't want to mess with ldloca.s, ldflda and other weird stuff", + throw new XamlLoadException( + "Value types can only be loaded via converters. We don't want to mess with indirect loads and other weird stuff", node); - var ctor = TransformArgumentsAndGetConstructor(context, ni); - return new XamlXValueWithManipulationNode(ni, - new XamlXAstNewClrObjectNode(ni, ni.Type.GetClrTypeReference(), ctor, ni.Arguments), - new XamlXObjectInitializationNode(ni, - new XamlXManipulationGroupNode(ni) - { - Children = ni.Children.Cast().ToList() - }, ni.Type.GetClrType())); + var ctor = TransformArgumentsAndGetConstructor(context, ni); + return new XamlAstConstructableObjectNode(ni, + ni.Type.GetClrTypeReference(), ctor, ni.Arguments, ni.Children); } return node; diff --git a/src/XamlX/Transform/Transformers/ContentConvertTransformer.cs b/src/XamlX/Transform/Transformers/ContentConvertTransformer.cs new file mode 100644 index 00000000..fc732c02 --- /dev/null +++ b/src/XamlX/Transform/Transformers/ContentConvertTransformer.cs @@ -0,0 +1,39 @@ +using System.Linq; +using XamlX.Ast; + +namespace XamlX.Transform.Transformers +{ +#if !XAMLX_INTERNAL + public +#endif + class ContentConvertTransformer : IXamlAstTransformer + { + public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node) + { + if (!(node is XamlAstObjectNode on)) + return node; + var nonDirectiveChildren = on.Children.Where(a => !(a is XamlAstXmlDirective)).ToList(); + + if (on.Arguments.Count != 0 + || nonDirectiveChildren.Count != 1 + || !(nonDirectiveChildren[0] is IXamlAstValueNode vn) + || !vn.Type.GetClrType().Equals(context.Configuration.WellKnownTypes.String)) + return node; + + if (XamlTransformHelpers.TryGetCorrectlyTypedValue(context, vn, on.Type.GetClrType(), out var rv)) + { + if (nonDirectiveChildren.Count != on.Children.Count) + rv = new XamlValueWithManipulationNode(rv, rv, + new XamlManipulationGroupNode(rv, on.Children.OfType())); + return rv; + } + + if (on.Type.GetClrType().IsValueType) + throw new XamlLoadException( + $"Unable to convert value {(vn as XamlAstTextNode)?.Text}) to {on.Type.GetClrType()}", vn); + + // Parser not found, isn't a value type, probably a regular object creation node with text content + return node; + } + } +} diff --git a/src/XamlX/Transform/Transformers/XamlXConvertPropertyValuesToAssignmentsTransformer.cs b/src/XamlX/Transform/Transformers/ConvertPropertyValuesToAssignmentsTransformer.cs similarity index 75% rename from src/XamlX/Transform/Transformers/XamlXConvertPropertyValuesToAssignmentsTransformer.cs rename to src/XamlX/Transform/Transformers/ConvertPropertyValuesToAssignmentsTransformer.cs index 20b5870b..006f5590 100644 --- a/src/XamlX/Transform/Transformers/XamlXConvertPropertyValuesToAssignmentsTransformer.cs +++ b/src/XamlX/Transform/Transformers/ConvertPropertyValuesToAssignmentsTransformer.cs @@ -7,21 +7,21 @@ namespace XamlX.Transform.Transformers { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXConvertPropertyValuesToAssignmentsTransformer : IXamlXAstTransformer + class ConvertPropertyValuesToAssignmentsTransformer : IXamlAstTransformer { - public IXamlXAstNode Transform(XamlXAstTransformationContext context, IXamlXAstNode node) + public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node) { - if (node is XamlXAstXamlPropertyValueNode valueNode) + if (node is XamlAstXamlPropertyValueNode valueNode) { var property = valueNode.Property.GetClrProperty(); - var assignments = new List(); + var assignments = new List(); foreach (var v in valueNode.Values) { var keyNode = FindAndRemoveKey(v); - var arguments = new List(); + var arguments = new List(); if (keyNode != null) arguments.Add(keyNode); @@ -36,13 +36,13 @@ public IXamlXAstNode Transform(XamlXAstTransformationContext context, IXamlXAstN { for (var c = 0; c < arguments.Count - 1; c++) { - IXamlXType convertedTo = null; + IXamlType convertedTo = null; for (var s = 0; s < filteredSetters.Count;) { var setter = filteredSetters[s]; if (convertedTo == null) { - if (!XamlXTransformHelpers.TryGetCorrectlyTypedValue(context, arguments[c], + if (!XamlTransformHelpers.TryGetCorrectlyTypedValue(context, arguments[c], setter.Parameters[c], out var converted)) { filteredSetters.RemoveAt(c); @@ -57,7 +57,7 @@ public IXamlXAstNode Transform(XamlXAstTransformationContext context, IXamlXAstN else { if (!setter.Parameters[c].IsAssignableFrom(convertedTo)) - throw new XamlXLoadException( + throw new XamlLoadException( $"Runtime setter selection is not supported for non-last setter arguments (e. g. x:Key) and can not downcast argument {c} of the setter from {convertedTo} to {setter.Parameters[c]}", arguments[c]); } @@ -66,16 +66,16 @@ public IXamlXAstNode Transform(XamlXAstTransformationContext context, IXamlXAstN } } - XamlXPropertyAssignmentNode CreateAssignment() + XamlPropertyAssignmentNode CreateAssignment() { - var matchedSetters = new List(); + var matchedSetters = new List(); foreach (var setter in filteredSetters) { - bool CanAssign(IXamlXAstValueNode value, IXamlXType type) + bool CanAssign(IXamlAstValueNode value, IXamlType type) { // Don't allow x:Null if (!setter.BinderParameters.AllowXNull - && XamlXPseudoType.Null.Equals(value.Type.GetClrType())) + && XamlPseudoType.Null.Equals(value.Type.GetClrType())) return false; // Direct cast @@ -96,20 +96,20 @@ bool CanAssign(IXamlXAstValueNode value, IXamlXType type) if(CanAssign(valueArg, setterType)) matchedSetters.Add(setter); // Converted value have more priority than custom setters, so we just create a setter without an alternative - else if (XamlXTransformHelpers.TryConvertValue(context, valueArg, setterType, property, + else if (XamlTransformHelpers.TryConvertValue(context, valueArg, setterType, property, out var converted)) { arguments[valueArgIndex] = converted; - return new XamlXPropertyAssignmentNode(valueNode, + return new XamlPropertyAssignmentNode(valueNode, property, new[] {setter}, arguments); } } if (matchedSetters.Count > 0) - return new XamlXPropertyAssignmentNode(v, property, matchedSetters, arguments); + return new XamlPropertyAssignmentNode(v, property, matchedSetters, arguments); - throw new XamlXLoadException( + throw new XamlLoadException( $"Unable to find suitable setter or adder for property {property.Name} of type {property.DeclaringType.GetFqn()} for argument {v.Type.GetClrType().GetFqn()}" + (keyNode != null ? $" and x:Key of type {keyNode.Type.GetClrType()}" : null) + ", available setter parameter lists are:\n" + string.Join("\n", @@ -137,31 +137,31 @@ bool CanAssign(IXamlXAstValueNode value, IXamlXType type) { ass.PossibleSetters = ass.PossibleSetters.Where(s => s.BinderParameters.AllowMultiple).ToList(); if (ass.PossibleSetters.Count == 0) - throw new XamlXLoadException( + throw new XamlLoadException( $"Unable to find a setter that allows multiple assignments to the property {ass.Property.Name} of type {ass.Property.DeclaringType.GetFqn()}", node); } } - return new XamlXManipulationGroupNode(valueNode, assignments); + return new XamlManipulationGroupNode(valueNode, assignments); } return node; } - static IXamlXAstValueNode FindAndRemoveKey(IXamlXAstValueNode value) + static IXamlAstValueNode FindAndRemoveKey(IXamlAstValueNode value) { - IXamlXAstValueNode keyNode = null; + IXamlAstValueNode keyNode = null; - bool IsKeyDirective(object node) => node is XamlXAstXmlDirective d + bool IsKeyDirective(object node) => node is XamlAstXmlDirective d && d.Namespace == XamlNamespaces.Xaml2006 && d.Name == "Key"; void ProcessDirective(object d) { - var directive = (XamlXAstXmlDirective) d; + var directive = (XamlAstXmlDirective) d; if (directive.Values.Count != 1) - throw new XamlXParseException("Invalid number of arguments for x:Key directive", + throw new XamlParseException("Invalid number of arguments for x:Key directive", directive); keyNode = directive.Values[0]; } @@ -177,25 +177,25 @@ void ProcessDirectiveCandidateList(IList nodes) } } - IXamlXAstManipulationNode VisitManipulationNode(IXamlXAstManipulationNode man) + IXamlAstManipulationNode VisitManipulationNode(IXamlAstManipulationNode man) { if (IsKeyDirective(man)) { ProcessDirective(man); - return new XamlXManipulationGroupNode(man); + return new XamlManipulationGroupNode(man); } - if(man is XamlXManipulationGroupNode grp) + if(man is XamlManipulationGroupNode grp) ProcessDirectiveCandidateList(grp.Children); - if (man is XamlXObjectInitializationNode init) + if (man is XamlObjectInitializationNode init) init.Manipulation = VisitManipulationNode(init.Manipulation); return man; } - var probe = (value is XamlXValueWithSideEffectNodeBase side) ? side.Value : value; - - if (probe is XamlXAstObjectNode astObject) + var probe = (value is XamlValueWithSideEffectNodeBase side) ? side.Value : value; + + if (probe is XamlAstObjectNode astObject) ProcessDirectiveCandidateList(astObject.Children); - else if (value is XamlXValueWithManipulationNode vman) + else if (value is XamlValueWithManipulationNode vman) { vman.Manipulation = VisitManipulationNode(vman.Manipulation); } diff --git a/src/XamlX/Transform/Transformers/DeferredContentTransformer.cs b/src/XamlX/Transform/Transformers/DeferredContentTransformer.cs new file mode 100644 index 00000000..4db12db2 --- /dev/null +++ b/src/XamlX/Transform/Transformers/DeferredContentTransformer.cs @@ -0,0 +1,39 @@ +using System.Linq; +using XamlX.Ast; + +namespace XamlX.Transform.Transformers +{ +#if !XAMLX_INTERNAL + public +#endif + class DeferredContentTransformer : IXamlAstTransformer + { + public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node) + { + if (!(node is XamlPropertyAssignmentNode pa)) + return node; + var deferredAttrs = context.Configuration.TypeMappings.DeferredContentPropertyAttributes; + if (deferredAttrs.Count == 0) + return node; + if (!pa.Property.CustomAttributes.Any(ca => deferredAttrs.Any(da => da.Equals(ca.Type)))) + return node; + + if (pa.Values.Count != 1) + throw new XamlParseException("Property with deferred content can have only one value", node); + var contentNode = pa.Values[0]; + + if (! + (contentNode is XamlValueWithManipulationNode manipulation + && manipulation.Manipulation is XamlObjectInitializationNode)) + throw new XamlParseException( + "Unable to find the object initialization node inside deferred content, " + + "this shouldn't happen in default Xaml configuration, probably some AST transformer have broken the structure", + node); + manipulation.Value = new XamlDeferredContentInitializeIntermediateRootNode(manipulation.Value); + + pa.Values[0] = + new XamlDeferredContentNode(pa.Values[0], context.Configuration); + return node; + } + } +} diff --git a/src/XamlX/Transform/Transformers/FlattenAstTransformer.cs b/src/XamlX/Transform/Transformers/FlattenAstTransformer.cs new file mode 100644 index 00000000..209914ce --- /dev/null +++ b/src/XamlX/Transform/Transformers/FlattenAstTransformer.cs @@ -0,0 +1,17 @@ +using XamlX.Ast; + +namespace XamlX.Transform.Transformers +{ +#if !XAMLX_INTERNAL + public +#endif + class FlattenAstTransformer : IXamlAstTransformer + { + public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node) + { + if (node is XamlManipulationGroupNode group && group.Children.Count == 1) + return group.Children[0]; + return node; + } + } +} diff --git a/src/XamlX/Transform/Transformers/XamlXKnownDirectivesTransformer.cs b/src/XamlX/Transform/Transformers/KnownDirectivesTransformer.cs similarity index 57% rename from src/XamlX/Transform/Transformers/XamlXKnownDirectivesTransformer.cs rename to src/XamlX/Transform/Transformers/KnownDirectivesTransformer.cs index d879d2c1..2f5feed4 100644 --- a/src/XamlX/Transform/Transformers/XamlXKnownDirectivesTransformer.cs +++ b/src/XamlX/Transform/Transformers/KnownDirectivesTransformer.cs @@ -4,30 +4,30 @@ namespace XamlX.Transform.Transformers { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXKnownDirectivesTransformer : IXamlXAstTransformer + class KnownDirectivesTransformer : IXamlAstTransformer { - public IXamlXAstNode Transform(XamlXAstTransformationContext context, IXamlXAstNode node) + public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node) { - if (node is XamlXAstObjectNode ni && ni.Type is XamlXAstXmlTypeReference type) + if (node is XamlAstObjectNode ni && ni.Type is XamlAstXmlTypeReference type) { foreach (var d in context.Configuration.KnownDirectives) if (type.XmlNamespace == d.ns && type.Name == d.name) { - var vnodes = new List(); + var vnodes = new List(); foreach (var ch in ni.Children) { - if(ch is IXamlXAstValueNode vn) + if(ch is IXamlAstValueNode vn) vnodes.Add(vn); if (context.StrictMode) - throw new XamlXParseException( + throw new XamlParseException( "Only value nodes are allowed as directive children elements", ch); } - return new XamlXAstXmlDirective(ni, type.XmlNamespace, type.Name, vnodes); + return new XamlAstXmlDirective(ni, type.XmlNamespace, type.Name, vnodes); } } diff --git a/src/XamlX/Transform/Transformers/MarkupExtensionTransformer.cs b/src/XamlX/Transform/Transformers/MarkupExtensionTransformer.cs new file mode 100644 index 00000000..d6efcd8f --- /dev/null +++ b/src/XamlX/Transform/Transformers/MarkupExtensionTransformer.cs @@ -0,0 +1,25 @@ +using System.Linq; +using XamlX.Ast; + +namespace XamlX.Transform.Transformers +{ +#if !XAMLX_INTERNAL + public +#endif + class MarkupExtensionTransformer : IXamlAstTransformer + { + public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node) + { + if (node is IXamlAstValueNode vn) + { + if (context.ParentNodes().FirstOrDefault() is XamlMarkupExtensionNode) + return node; + + if (XamlTransformHelpers.TryConvertMarkupExtension(context, vn, out var rv)) + return rv; + } + + return node; + } + } +} diff --git a/src/XamlX/Transform/Transformers/NewObjectTransformer.cs b/src/XamlX/Transform/Transformers/NewObjectTransformer.cs new file mode 100644 index 00000000..f662c8a7 --- /dev/null +++ b/src/XamlX/Transform/Transformers/NewObjectTransformer.cs @@ -0,0 +1,30 @@ +using System.Collections.Generic; +using System.Linq; +using XamlX.Ast; +using XamlX.IL.Emitters; +using XamlX.TypeSystem; + +namespace XamlX.Transform.Transformers +{ +#if !XAMLX_INTERNAL + public +#endif + class NewObjectTransformer : IXamlAstTransformer + { + public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node) + { + if (node is XamlAstConstructableObjectNode obj) + { + return new XamlValueWithManipulationNode(obj, + new XamlAstNewClrObjectNode(obj, obj.Type.GetClrTypeReference(), obj.Constructor, obj.Arguments), + new XamlObjectInitializationNode(obj, + new XamlManipulationGroupNode(obj) + { + Children = obj.Children.Cast().ToList() + }, obj.Type.GetClrType())); + } + + return node; + } + } +} diff --git a/src/XamlX/Transform/Transformers/XamlXPropertyReferenceResolver.cs b/src/XamlX/Transform/Transformers/PropertyReferenceResolver.cs similarity index 73% rename from src/XamlX/Transform/Transformers/XamlXPropertyReferenceResolver.cs rename to src/XamlX/Transform/Transformers/PropertyReferenceResolver.cs index cdd8554a..dde1fc9d 100644 --- a/src/XamlX/Transform/Transformers/XamlXPropertyReferenceResolver.cs +++ b/src/XamlX/Transform/Transformers/PropertyReferenceResolver.cs @@ -5,28 +5,28 @@ namespace XamlX.Transform.Transformers { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXPropertyReferenceResolver : IXamlXAstTransformer + class PropertyReferenceResolver : IXamlAstTransformer { - public IXamlXAstNode Transform(XamlXAstTransformationContext context, IXamlXAstNode node) + public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node) { - if (node is XamlXAstNamePropertyReference prop) + if (node is XamlAstNamePropertyReference prop) { - if (!(prop.DeclaringType is XamlXAstClrTypeReference declaringRef)) + if (!(prop.DeclaringType is XamlAstClrTypeReference declaringRef)) { if (context.StrictMode) - throw new XamlXParseException( + throw new XamlParseException( $"Unable to resolve property {prop.Name} on {prop.DeclaringType}", node); else return node; } - if (!(prop.TargetType is XamlXAstClrTypeReference targetRef)) + if (!(prop.TargetType is XamlAstClrTypeReference targetRef)) { if (context.StrictMode) - throw new XamlXParseException($"Unable to resolve property on {prop.DeclaringType}", node); + throw new XamlParseException($"Unable to resolve property on {prop.DeclaringType}", node); else return node; } @@ -42,16 +42,16 @@ public IXamlXAstNode Transform(XamlXAstTransformationContext context, IXamlXAstN && ((p.Getter != null && !p.Getter.IsStatic && p.Getter.Parameters.Count == 0) || p.Setter != null && !p.Setter.IsStatic && p.Setter.Parameters.Count == 1)); if (found != null) - return new XamlXAstClrProperty(prop, found, context.Configuration); + return new XamlAstClrProperty(prop, found, context.Configuration); var clrEvent = declaringType.GetAllEvents().FirstOrDefault(p => p.Name == prop.Name && p.Add != null); if (clrEvent != null) - return new XamlXAstClrProperty(prop, + return new XamlAstClrProperty(prop, prop.Name, declaringType, null, clrEvent.Add); } // Look for attached properties on declaring type - IXamlXMethod setter = null, getter = null, adder = null; + IXamlMethod setter = null, getter = null, adder = null; var setterName = "Set" + prop.Name; var getterName = "Get" + prop.Name; var adderName = "Add" + prop.Name + "Handler"; @@ -75,13 +75,13 @@ public IXamlXAstNode Transform(XamlXAstTransformationContext context, IXamlXAstN } if (setter != null || getter != null) - return new XamlXAstClrProperty(prop, prop.Name, declaringType, getter, setter); + return new XamlAstClrProperty(prop, prop.Name, declaringType, getter, setter); if (adder != null) - return new XamlXAstClrProperty(prop, prop.Name, declaringType, null, adder); + return new XamlAstClrProperty(prop, prop.Name, declaringType, null, adder); if (context.StrictMode) - throw new XamlXParseException( + throw new XamlParseException( $"Unable to resolve suitable regular or attached property {prop.Name} on type {declaringType.GetFqn()}", node); return null; diff --git a/src/XamlX/Transform/Transformers/XamlXResolveContentPropertyTransformer.cs b/src/XamlX/Transform/Transformers/ResolveContentPropertyTransformer.cs similarity index 61% rename from src/XamlX/Transform/Transformers/XamlXResolveContentPropertyTransformer.cs rename to src/XamlX/Transform/Transformers/ResolveContentPropertyTransformer.cs index 75142e36..6cb1710f 100644 --- a/src/XamlX/Transform/Transformers/XamlXResolveContentPropertyTransformer.cs +++ b/src/XamlX/Transform/Transformers/ResolveContentPropertyTransformer.cs @@ -5,43 +5,43 @@ namespace XamlX.Transform.Transformers { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXResolveContentPropertyTransformer : IXamlXAstTransformer + class ResolveContentPropertyTransformer : IXamlAstTransformer { - public IXamlXAstNode Transform(XamlXAstTransformationContext context, IXamlXAstNode node) + public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node) { - if (node is XamlXAstObjectNode ni) + if (node is XamlAstObjectNode ni) { - XamlXAstXamlPropertyValueNode propertyNode = null; + XamlAstXamlPropertyValueNode propertyNode = null; for (var c = ni.Children.Count - 1; c >= 0; c--) { var child = ni.Children[c]; - if (child is IXamlXAstValueNode valueNode) + if (child is IXamlAstValueNode valueNode) { if (propertyNode == null) { var contentProperty = context.Configuration.FindContentProperty(ni.Type.GetClrType()); if (contentProperty != null) - propertyNode = new XamlXAstXamlPropertyValueNode(ni, - new XamlXAstClrProperty(ni, contentProperty, context.Configuration), - Array.Empty()); + propertyNode = new XamlAstXamlPropertyValueNode(ni, + new XamlAstClrProperty(ni, contentProperty, context.Configuration), + Array.Empty()); else { - var adders = XamlXTransformHelpers.FindPossibleAdders(context, ni.Type.GetClrType()); + var adders = XamlTransformHelpers.FindPossibleAdders(context, ni.Type.GetClrType()); if (adders.Count == 0) - throw new XamlXParseException( + throw new XamlParseException( $"No Content property or any Add methods found for type {ni.Type.GetClrType().GetFqn()}", child); - propertyNode = new XamlXAstXamlPropertyValueNode(ni, new XamlXAstClrProperty(ni, + propertyNode = new XamlAstXamlPropertyValueNode(ni, new XamlAstClrProperty(ni, "Content", ni.Type.GetClrType(), null, - adders.Select(a => new XamlXDirectCallPropertySetter(a) + adders.Select(a => new XamlDirectCallPropertySetter(a) { BinderParameters = {AllowMultiple = true} })), - Array.Empty()); + Array.Empty()); } } // We are going in reverse order, so insert at the beginning diff --git a/src/XamlX/Transform/Transformers/XamlXResolvePropertyValueAddersTransformer.cs b/src/XamlX/Transform/Transformers/ResolvePropertyValueAddersTransformer.cs similarity index 59% rename from src/XamlX/Transform/Transformers/XamlXResolvePropertyValueAddersTransformer.cs rename to src/XamlX/Transform/Transformers/ResolvePropertyValueAddersTransformer.cs index a1dc67f1..43841b49 100644 --- a/src/XamlX/Transform/Transformers/XamlXResolvePropertyValueAddersTransformer.cs +++ b/src/XamlX/Transform/Transformers/ResolvePropertyValueAddersTransformer.cs @@ -1,32 +1,34 @@ using System.Collections.Generic; using System.Linq; using XamlX.Ast; +using XamlX.Emit; +using XamlX.IL; using XamlX.TypeSystem; namespace XamlX.Transform.Transformers { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXResolvePropertyValueAddersTransformer : IXamlXAstTransformer + class ResolvePropertyValueAddersTransformer : IXamlAstTransformer { - public IXamlXAstNode Transform(XamlXAstTransformationContext context, IXamlXAstNode node) + public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node) { - if (node is XamlXAstClrProperty prop && prop.Getter != null) + if (node is XamlAstClrProperty prop && prop.Getter != null) { - foreach(var adder in XamlXTransformHelpers.FindPossibleAdders(context, prop.Getter.ReturnType)) + foreach(var adder in XamlTransformHelpers.FindPossibleAdders(context, prop.Getter.ReturnType)) prop.Setters.Add(new AdderSetter(prop.Getter, adder)); } return node; } - class AdderSetter : IXamlXPropertySetter + class AdderSetter : IXamlPropertySetter, IXamlEmitablePropertySetter { - private readonly IXamlXMethod _getter; - private readonly IXamlXMethod _adder; + private readonly IXamlMethod _getter; + private readonly IXamlMethod _adder; - public AdderSetter(IXamlXMethod getter, IXamlXMethod adder) + public AdderSetter(IXamlMethod getter, IXamlMethod adder) { _getter = getter; _adder = adder; @@ -34,17 +36,17 @@ public AdderSetter(IXamlXMethod getter, IXamlXMethod adder) Parameters = adder.ParametersWithThis().Skip(1).ToList(); } - public IXamlXType TargetType { get; } + public IXamlType TargetType { get; } public PropertySetterBinderParameters BinderParameters { get; } = new PropertySetterBinderParameters { AllowMultiple = true }; - public IReadOnlyList Parameters { get; } - public void Emit(IXamlXEmitter emitter) + public IReadOnlyList Parameters { get; } + public void Emit(IXamlILEmitter emitter) { - var locals = new Stack(); + var locals = new Stack(); // Save all "setter" parameters for (var c = Parameters.Count - 1; c >= 0; c--) { diff --git a/src/XamlX/Transform/Transformers/XamlXTopDownInitializationTransformer.cs b/src/XamlX/Transform/Transformers/TopDownInitializationTransformer.cs similarity index 63% rename from src/XamlX/Transform/Transformers/XamlXTopDownInitializationTransformer.cs rename to src/XamlX/Transform/Transformers/TopDownInitializationTransformer.cs index 0278c5e8..9cf4cd3d 100644 --- a/src/XamlX/Transform/Transformers/XamlXTopDownInitializationTransformer.cs +++ b/src/XamlX/Transform/Transformers/TopDownInitializationTransformer.cs @@ -5,17 +5,17 @@ namespace XamlX.Transform.Transformers { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXTopDownInitializationTransformer : IXamlXAstTransformer + class TopDownInitializationTransformer : IXamlAstTransformer { - public IXamlXAstNode Transform(XamlXAstTransformationContext context, IXamlXAstNode node) + public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node) { var usableAttrs = context.Configuration.TypeMappings.UsableDuringInitializationAttributes; if (!(usableAttrs?.Count > 0)) return node; - bool UsableDuringInitialization(IXamlXType type) + bool UsableDuringInitialization(IXamlType type) { foreach (var attr in type.CustomAttributes) { @@ -32,29 +32,29 @@ bool UsableDuringInitialization(IXamlXType type) } bool TryConvert( - IXamlXAstValueNode checkedNode, out IXamlXAstValueNode value, out IXamlXAstManipulationNode deferred) + IXamlAstValueNode checkedNode, out IXamlAstValueNode value, out IXamlAstManipulationNode deferred) { value = null; deferred = null; - if (!(checkedNode is XamlXValueWithManipulationNode manipulation - && manipulation.Manipulation is XamlXObjectInitializationNode initializer + if (!(checkedNode is XamlValueWithManipulationNode manipulation + && manipulation.Manipulation is XamlObjectInitializationNode initializer && UsableDuringInitialization(manipulation.Value.Type.GetClrType()))) return false; initializer.SkipBeginInit = true; - var local = new XamlXAstCompilerLocalNode(manipulation.Value, manipulation.Value.Type.GetClrTypeReference()); - value = new XamlXValueNodeWithBeginInit(new XamlXAstLocalInitializationNodeEmitter(local, manipulation.Value, local)); - deferred = new XamlXAstManipulationImperativeNode(initializer, - new XamlXAstImperativeValueManipulation(initializer, local, initializer)); + var local = new XamlAstCompilerLocalNode(manipulation.Value, manipulation.Value.Type.GetClrTypeReference()); + value = new XamlValueNodeWithBeginInit(new XamlAstLocalInitializationNodeEmitter(local, manipulation.Value, local)); + deferred = new XamlAstManipulationImperativeNode(initializer, + new XamlAstImperativeValueManipulation(initializer, local, initializer)); return true; } - if (node is XamlXPropertyAssignmentNode assignment) + if (node is XamlPropertyAssignmentNode assignment) { if (!TryConvert(assignment.Values.Last(), out var nvalue, out var deferred)) return node; assignment.Values[assignment.Values.Count - 1] = nvalue; - return new XamlXManipulationGroupNode(assignment) + return new XamlManipulationGroupNode(assignment) { Children = { @@ -63,9 +63,9 @@ bool TryConvert( } }; } - else if (node is XamlXNoReturnMethodCallNode call) + else if (node is XamlNoReturnMethodCallNode call) { - var deferredNodes = new List(); + var deferredNodes = new List(); for (var c = 0; c < call.Arguments.Count; c++) { var arg = call.Arguments[c]; @@ -78,7 +78,7 @@ bool TryConvert( if (deferredNodes.Count != 0) { - var grp = new XamlXManipulationGroupNode(call); + var grp = new XamlManipulationGroupNode(call); grp.Children.Add(call); grp.Children.AddRange(deferredNodes); return grp; diff --git a/src/XamlX/Transform/Transformers/XamlXTypeReferenceResolver.cs b/src/XamlX/Transform/Transformers/TypeReferenceResolver.cs similarity index 70% rename from src/XamlX/Transform/Transformers/XamlXTypeReferenceResolver.cs rename to src/XamlX/Transform/Transformers/TypeReferenceResolver.cs index cd7880ad..7f3d0689 100644 --- a/src/XamlX/Transform/Transformers/XamlXTypeReferenceResolver.cs +++ b/src/XamlX/Transform/Transformers/TypeReferenceResolver.cs @@ -5,20 +5,20 @@ using XamlX.TypeSystem; namespace XamlX.Transform.Transformers { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXTypeReferenceResolver : IXamlXAstTransformer + class TypeReferenceResolver : IXamlAstTransformer { class TypeResolverCache { - public Dictionary<(string, string, bool), IXamlXType> CacheDictionary = - new Dictionary<(string, string, bool), IXamlXType>(); + public Dictionary<(string, string, bool), IXamlType> CacheDictionary = + new Dictionary<(string, string, bool), IXamlType>(); } - public static XamlXAstClrTypeReference ResolveType(XamlXAstTransformationContext context, - string xmlns, string name, bool isMarkupExtension, List typeArguments, - IXamlXLineInfo lineInfo, + public static XamlAstClrTypeReference ResolveType(AstTransformationContext context, + string xmlns, string name, bool isMarkupExtension, List typeArguments, + IXamlLineInfo lineInfo, bool strict) { if (typeArguments == null || typeArguments.Count == 0) @@ -29,7 +29,7 @@ public static XamlXAstClrTypeReference ResolveType(XamlXAstTransformationContext { if (type == null) return null; - return new XamlXAstClrTypeReference(lineInfo, type, isMarkupExtension); + return new XamlAstClrTypeReference(lineInfo, type, isMarkupExtension); } var res = ResolveTypeCore(context, xmlns, name, isMarkupExtension, typeArguments, lineInfo, strict); @@ -41,19 +41,19 @@ public static XamlXAstClrTypeReference ResolveType(XamlXAstTransformationContext return ResolveTypeCore(context, xmlns, name, isMarkupExtension, typeArguments, lineInfo, strict); } - static XamlXAstClrTypeReference ResolveTypeCore(XamlXAstTransformationContext context, - string xmlns, string name, bool isMarkupExtension, List typeArguments, IXamlXLineInfo lineInfo, + static XamlAstClrTypeReference ResolveTypeCore(AstTransformationContext context, + string xmlns, string name, bool isMarkupExtension, List typeArguments, IXamlLineInfo lineInfo, bool strict) { if (typeArguments == null) - typeArguments = new List(); + typeArguments = new List(); var targs = typeArguments .Select(ta => ResolveType(context, ta.XmlNamespace, ta.Name, false, ta.GenericArguments, lineInfo, strict) ?.Type) .ToList(); - IXamlXType Attempt(Func cb, string xname) + IXamlType Attempt(Func cb, string xname) { var suffix = (typeArguments.Count != 0) ? ("`" + typeArguments.Count) : ""; if (isMarkupExtension) @@ -62,7 +62,7 @@ IXamlXType Attempt(Func cb, string xname) return cb(xname + suffix) ?? cb(xname + "Extension" + suffix); } - IXamlXType found = null; + IXamlType found = null; // Try to resolve from system if (xmlns == XamlNamespaces.Xaml2006) @@ -71,14 +71,14 @@ IXamlXType Attempt(Func cb, string xname) if (found == null) { - var resolvedNamespaces = XamlXNamespaceInfoHelper.TryResolve(context.Configuration, xmlns); + var resolvedNamespaces = NamespaceInfoHelper.TryResolve(context.Configuration, xmlns); if (resolvedNamespaces?.Count > 0) found = Attempt(formedName => { foreach (var resolvedNs in resolvedNamespaces) { var rname = resolvedNs.ClrNamespace + "." + formedName; - IXamlXType subRes; + IXamlType subRes; if (resolvedNs.Assembly != null) subRes = resolvedNs.Assembly.FindType(rname); else @@ -94,16 +94,16 @@ IXamlXType Attempt(Func cb, string xname) if (typeArguments.Count != 0) found = found?.MakeGenericType(targs); if (found != null) - return new XamlXAstClrTypeReference(lineInfo, found, + return new XamlAstClrTypeReference(lineInfo, found, isMarkupExtension || found.Name.EndsWith("Extension")); if (strict) - throw new XamlXParseException( + throw new XamlParseException( $"Unable to resolve type {name} from namespace {xmlns}", lineInfo); return null; } - public static XamlXAstClrTypeReference ResolveType(XamlXAstTransformationContext context, - string xmlName, bool isMarkupExtension, IXamlXLineInfo lineInfo, + public static XamlAstClrTypeReference ResolveType(AstTransformationContext context, + string xmlName, bool isMarkupExtension, IXamlLineInfo lineInfo, bool strict) { var pair = xmlName.Split(new[] {':'}, 2); @@ -111,17 +111,17 @@ public static XamlXAstClrTypeReference ResolveType(XamlXAstTransformationContext if (!context.NamespaceAliases.TryGetValue(shortNs, out var xmlns)) { if (strict) - throw new XamlXParseException( + throw new XamlParseException( $"Unable to resolve type namespace alias {shortNs}", lineInfo); return null; } - return ResolveType(context, xmlns, name, isMarkupExtension, new List(), lineInfo, strict); + return ResolveType(context, xmlns, name, isMarkupExtension, new List(), lineInfo, strict); } - public IXamlXAstNode Transform(XamlXAstTransformationContext context, IXamlXAstNode node) + public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node) { - if (node is XamlXAstXmlTypeReference xmlref) + if (node is XamlAstXmlTypeReference xmlref) { var resolved = ResolveType(context, xmlref, context.StrictMode); if (resolved == null) @@ -132,8 +132,8 @@ public IXamlXAstNode Transform(XamlXAstTransformationContext context, IXamlXAstN return node; } - public static XamlXAstClrTypeReference ResolveType(XamlXAstTransformationContext context, - XamlXAstXmlTypeReference xmlref, bool strict) + public static XamlAstClrTypeReference ResolveType(AstTransformationContext context, + XamlAstXmlTypeReference xmlref, bool strict) { return ResolveType(context, xmlref.XmlNamespace, xmlref.Name, xmlref.IsMarkupExtension, xmlref.GenericArguments, xmlref, strict); diff --git a/src/XamlX/Transform/Transformers/XamlXXArgumentsTransformer.cs b/src/XamlX/Transform/Transformers/XArgumentsTransformer.cs similarity index 54% rename from src/XamlX/Transform/Transformers/XamlXXArgumentsTransformer.cs rename to src/XamlX/Transform/Transformers/XArgumentsTransformer.cs index 54be13b3..18c6d711 100644 --- a/src/XamlX/Transform/Transformers/XamlXXArgumentsTransformer.cs +++ b/src/XamlX/Transform/Transformers/XArgumentsTransformer.cs @@ -3,24 +3,24 @@ namespace XamlX.Transform.Transformers { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXXArgumentsTransformer : IXamlXAstTransformer + class XArgumentsTransformer : IXamlAstTransformer { - public IXamlXAstNode Transform(XamlXAstTransformationContext context, IXamlXAstNode node) + public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node) { - if (node is XamlXAstObjectNode ni) + if (node is XamlAstObjectNode ni) { - var argDirectives = ni.Children.OfType() - .Where(d => d.Type is XamlXAstXmlTypeReference xref + var argDirectives = ni.Children.OfType() + .Where(d => d.Type is XamlAstXmlTypeReference xref && xref.XmlNamespace == XamlNamespaces.Xaml2006 && xref.Name == "Arguments").ToList(); if (argDirectives.Count > 1 && context.StrictMode) - throw new XamlXParseException("x:Arguments directive is specified more than once", + throw new XamlParseException("x:Arguments directive is specified more than once", argDirectives[1]); if (argDirectives.Count == 0) return node; - ni.Arguments = argDirectives[0].Children.OfType().ToList(); + ni.Arguments = argDirectives[0].Children.OfType().ToList(); ni.Children.Remove(argDirectives[0]); } return node; diff --git a/src/XamlX/Transform/Transformers/XamlXIntrinsicsTransformer.cs b/src/XamlX/Transform/Transformers/XamlIntrinsicsTransformer.cs similarity index 72% rename from src/XamlX/Transform/Transformers/XamlXIntrinsicsTransformer.cs rename to src/XamlX/Transform/Transformers/XamlIntrinsicsTransformer.cs index 48b17169..55014799 100644 --- a/src/XamlX/Transform/Transformers/XamlXIntrinsicsTransformer.cs +++ b/src/XamlX/Transform/Transformers/XamlIntrinsicsTransformer.cs @@ -2,42 +2,42 @@ namespace XamlX.Transform.Transformers { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXIntrinsicsTransformer : IXamlXAstTransformer + class XamlIntrinsicsTransformer : IXamlAstTransformer { - public IXamlXAstNode Transform(XamlXAstTransformationContext context, IXamlXAstNode node) + public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node) { - if (node is XamlXAstObjectNode ni - && ni.Type is XamlXAstXmlTypeReference xml + if (node is XamlAstObjectNode ni + && ni.Type is XamlAstXmlTypeReference xml && xml.XmlNamespace == XamlNamespaces.Xaml2006) { - XamlXAstTextNode ResolveArgumentOrValue(string extension, string name) + XamlAstTextNode ResolveArgumentOrValue(string extension, string name) { - IXamlXAstNode value = null; + IXamlAstNode value = null; if (ni.Arguments.Count == 1 && ni.Children.Count == 0) value = ni.Arguments[0]; else if (ni.Arguments.Count == 0 && ni.Children.Count == 1 - && ni.Children[0] is XamlXAstXamlPropertyValueNode pnode - && pnode.Property is XamlXAstNamePropertyReference pref + && ni.Children[0] is XamlAstXamlPropertyValueNode pnode + && pnode.Property is XamlAstNamePropertyReference pref && pref.Name == name && pnode.Values.Count == 1) value = pnode.Values[0]; if(value == null) - return (XamlXAstTextNode) context.ParseError( + return (XamlAstTextNode) context.ParseError( $"{extension} extension should take exactly one constructor parameter without any content OR {name} property", node); - if (!(value is XamlXAstTextNode textNode)) - return (XamlXAstTextNode) context.ParseError("x:Type parameter should be a text node", value, node); + if (!(value is XamlAstTextNode textNode)) + return (XamlAstTextNode) context.ParseError("x:Type parameter should be a text node", value, node); return textNode; } if (xml.Name == "Null") - return new XamlXNullExtensionNode(node); + return new XamlNullExtensionNode(node); if (xml.Name == "Type") { var textNode = ResolveArgumentOrValue("x:Type", "TypeName"); @@ -53,8 +53,8 @@ XamlXAstTextNode ResolveArgumentOrValue(string extension, string name) if (!context.NamespaceAliases.TryGetValue(pair[0].Trim(), out var resolvedNs)) return context.ParseError($"Unable to resolve namespace {pair[0]}", textNode, node); - return new XamlXTypeExtensionNode(node, - new XamlXAstXmlTypeReference(textNode, resolvedNs, pair[1], xml.GenericArguments), + return new XamlTypeExtensionNode(node, + new XamlAstXmlTypeReference(textNode, resolvedNs, pair[1], xml.GenericArguments), context.Configuration.TypeSystem.FindType("System.Type")); } @@ -83,8 +83,8 @@ XamlXAstTextNode ResolveArgumentOrValue(string extension, string name) if (!context.NamespaceAliases.TryGetValue(ns, out var resolvedNs)) return context.ParseError($"Unable to resolve namespace {ns}", textNode, node); - return new XamlXStaticExtensionNode(ni, - new XamlXAstXmlTypeReference(ni, resolvedNs, tmpair[0], xml.GenericArguments), + return new XamlStaticExtensionNode(ni, + new XamlAstXmlTypeReference(ni, resolvedNs, tmpair[0], xml.GenericArguments), tmpair[1]); } } diff --git a/src/XamlX/Transform/Transformers/XamlXContentConvertTransformer.cs b/src/XamlX/Transform/Transformers/XamlXContentConvertTransformer.cs deleted file mode 100644 index da52fa33..00000000 --- a/src/XamlX/Transform/Transformers/XamlXContentConvertTransformer.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System.Linq; -using XamlX.Ast; - -namespace XamlX.Transform.Transformers -{ -#if !XAMLIL_INTERNAL - public -#endif - class XamlXContentConvertTransformer : IXamlXAstTransformer - { - public IXamlXAstNode Transform(XamlXAstTransformationContext context, IXamlXAstNode node) - { - if (!(node is XamlXAstObjectNode on)) - return node; - var nonDirectiveChildren = on.Children.Where(a => !(a is XamlXAstXmlDirective)).ToList(); - - if (on.Arguments.Count != 0 - || nonDirectiveChildren.Count != 1 - || !(nonDirectiveChildren[0] is IXamlXAstValueNode vn) - || !vn.Type.GetClrType().Equals(context.Configuration.WellKnownTypes.String)) - return node; - - if (XamlXTransformHelpers.TryGetCorrectlyTypedValue(context, vn, on.Type.GetClrType(), out var rv)) - { - if (nonDirectiveChildren.Count != on.Children.Count) - rv = new XamlXValueWithManipulationNode(rv, rv, - new XamlXManipulationGroupNode(rv, on.Children.OfType())); - return rv; - } - - if (on.Type.GetClrType().IsValueType) - throw new XamlXLoadException( - $"Unable to convert value {(vn as XamlXAstTextNode)?.Text}) to {on.Type.GetClrType()}", vn); - - // Parser not found, isn't a value type, probably a regular object creation node with text content - return node; - } - } -} diff --git a/src/XamlX/Transform/Transformers/XamlXDeferredContentTransformer.cs b/src/XamlX/Transform/Transformers/XamlXDeferredContentTransformer.cs deleted file mode 100644 index 51759754..00000000 --- a/src/XamlX/Transform/Transformers/XamlXDeferredContentTransformer.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System.Linq; -using XamlX.Ast; - -namespace XamlX.Transform.Transformers -{ -#if !XAMLIL_INTERNAL - public -#endif - class XamlXDeferredContentTransformer : IXamlXAstTransformer - { - public IXamlXAstNode Transform(XamlXAstTransformationContext context, IXamlXAstNode node) - { - if (!(node is XamlXPropertyAssignmentNode pa)) - return node; - var deferredAttrs = context.Configuration.TypeMappings.DeferredContentPropertyAttributes; - if (deferredAttrs.Count == 0) - return node; - if (!pa.Property.CustomAttributes.Any(ca => deferredAttrs.Any(da => da.Equals(ca.Type)))) - return node; - - if (pa.Values.Count != 1) - throw new XamlXParseException("Property with deferred content can have only one value", node); - var contentNode = pa.Values[0]; - - if (! - (contentNode is XamlXValueWithManipulationNode manipulation - && manipulation.Manipulation is XamlXObjectInitializationNode)) - throw new XamlXParseException( - "Unable to find the object initialization node inside deferred content, " + - "this shouldn't happen in default XamlX configuration, probably some AST transformer have broken the structure", - node); - manipulation.Value = new XamlXDeferredContentInitializeIntermediateRootNode(manipulation.Value); - - pa.Values[0] = - new XamlXDeferredContentNode(pa.Values[0], context.Configuration); - return node; - } - } -} diff --git a/src/XamlX/Transform/Transformers/XamlXFlattenTransformer.cs b/src/XamlX/Transform/Transformers/XamlXFlattenTransformer.cs deleted file mode 100644 index 72523e10..00000000 --- a/src/XamlX/Transform/Transformers/XamlXFlattenTransformer.cs +++ /dev/null @@ -1,17 +0,0 @@ -using XamlX.Ast; - -namespace XamlX.Transform.Transformers -{ -#if !XAMLIL_INTERNAL - public -#endif - class XamlXFlattenTransformer : IXamlXAstTransformer - { - public IXamlXAstNode Transform(XamlXAstTransformationContext context, IXamlXAstNode node) - { - if (node is XamlXManipulationGroupNode group && group.Children.Count == 1) - return group.Children[0]; - return node; - } - } -} diff --git a/src/XamlX/Transform/Transformers/XamlXMarkupExtensionTransformer.cs b/src/XamlX/Transform/Transformers/XamlXMarkupExtensionTransformer.cs deleted file mode 100644 index 08c03761..00000000 --- a/src/XamlX/Transform/Transformers/XamlXMarkupExtensionTransformer.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.Linq; -using XamlX.Ast; - -namespace XamlX.Transform.Transformers -{ -#if !XAMLIL_INTERNAL - public -#endif - class XamlXMarkupExtensionTransformer : IXamlXAstTransformer - { - public IXamlXAstNode Transform(XamlXAstTransformationContext context, IXamlXAstNode node) - { - if (node is IXamlXAstValueNode vn) - { - if (context.ParentNodes().FirstOrDefault() is XamlXMarkupExtensionNode) - return node; - - if (XamlXTransformHelpers.TryConvertMarkupExtension(context, vn, out var rv)) - return rv; - } - - return node; - } - } -} diff --git a/src/XamlX/Transform/XamlContextBase.cs b/src/XamlX/Transform/XamlContextBase.cs new file mode 100644 index 00000000..379fc96e --- /dev/null +++ b/src/XamlX/Transform/XamlContextBase.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Text; +using XamlX.Ast; + +namespace XamlX.Transform +{ +#if !XAMLX_INTERNAL + public +#endif + class XamlContextBase + { + private readonly Dictionary _items = new Dictionary(); + private readonly List _parentNodes = new List(); + public T GetItem() => (T)_items[typeof(T)]; + + public T GetOrCreateItem() where T : new() + { + if (!_items.TryGetValue(typeof(T), out var rv)) + _items[typeof(T)] = rv = new T(); + return (T)rv; + } + + public bool TryGetItem(out T rv) + { + var success = _items.TryGetValue(typeof(T), out var orv); + rv = (T)orv; + return success; + } + + public void SetItem(T item) => _items[typeof(T)] = item; + + + public IEnumerable ParentNodes() + { + for (var c = _parentNodes.Count - 1; c >= 0; c--) + yield return _parentNodes[c]; + } + + protected void PushParent(IXamlAstNode node) => _parentNodes.Add(node); + + protected IXamlAstNode PopParent() + { + var rv = _parentNodes[_parentNodes.Count - 1]; + _parentNodes.RemoveAt(_parentNodes.Count - 1); + return rv; + } + } +} diff --git a/src/XamlX/Transform/XamlLanguageTypeMappings.cs b/src/XamlX/Transform/XamlLanguageTypeMappings.cs new file mode 100644 index 00000000..d4fd9f4e --- /dev/null +++ b/src/XamlX/Transform/XamlLanguageTypeMappings.cs @@ -0,0 +1,57 @@ +using System.Collections.Generic; +using XamlX.TypeSystem; + +namespace XamlX.Transform +{ +#if !XAMLX_INTERNAL + public +#endif + class XamlLanguageTypeMappings + { + public XamlLanguageTypeMappings(IXamlTypeSystem typeSystem) + { + ServiceProvider = typeSystem.GetType("System.IServiceProvider"); + TypeDescriptorContext = typeSystem.GetType("System.ComponentModel.ITypeDescriptorContext"); + SupportInitialize = typeSystem.GetType("System.ComponentModel.ISupportInitialize"); + var tconv = typeSystem.GetType("System.ComponentModel.TypeConverterAttribute"); + if (tconv != null) + TypeConverterAttributes.Add(tconv); + } + + public List XmlnsAttributes { get; set; } = new List(); + public List UsableDuringInitializationAttributes { get; set; } = new List(); + public List ContentAttributes { get; set; } = new List(); + public List TypeConverterAttributes { get; set; } = new List(); + public IXamlType ServiceProvider { get; set; } + public IXamlType TypeDescriptorContext { get; set; } + public IXamlType SupportInitialize { get; set; } + public IXamlType ProvideValueTarget { get; set; } + public IXamlType RootObjectProvider { get; set; } + public IXamlType ParentStackProvider { get; set; } + public IXamlType XmlNamespaceInfoProvider { get; set; } + public IXamlType UriContextProvider { get; set; } + + public IXamlCustomAttributeResolver CustomAttributeResolver { get; set; } + + /// + /// Expected signature: + /// static IServiceProvider InnerServiceProviderFactory(IServiceProvider self); + /// + public IXamlMethod InnerServiceProviderFactoryMethod { get; set; } + /// + /// static Func<IServiceProvider, object> DeferredTransformationFactory(Func<IServiceProvider, object> builder, IServiceProvider provider); + /// + public IXamlMethod DeferredContentExecutorCustomization { get; set; } + public List DeferredContentPropertyAttributes { get; set; } = new List(); + public string RootObjectProviderIntermediateRootPropertyName { get; set; } + } + +#if !XAMLX_INTERNAL + public +#endif + interface IXamlCustomAttributeResolver + { + IXamlCustomAttribute GetCustomAttribute(IXamlType type, IXamlType attributeType); + IXamlCustomAttribute GetCustomAttribute(IXamlProperty property, IXamlType attributeType); + } +} diff --git a/src/XamlX/Transform/XamlXTransformHelpers.cs b/src/XamlX/Transform/XamlTransformHelpers.cs similarity index 61% rename from src/XamlX/Transform/XamlXTransformHelpers.cs rename to src/XamlX/Transform/XamlTransformHelpers.cs index c646a938..849824b1 100644 --- a/src/XamlX/Transform/XamlXTransformHelpers.cs +++ b/src/XamlX/Transform/XamlTransformHelpers.cs @@ -8,75 +8,20 @@ namespace XamlX.Transform { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - static class XamlXTransformHelpers + static class XamlTransformHelpers { - /* - public static void GeneratePropertyAssignments(XamlXAstTransformationContext context, - XamlXAstClrProperty contentProperty, - int count, Func getNode, Action setNode) - { - var type = contentProperty.PropertyType; - // Markup extension ? - if (contentProperty.Setter?.IsPublic == true - && count == 1 - && TryConvertMarkupExtension(context, getNode(0), - contentProperty, out var me)) - setNode(0, me); - // Direct property assignment? - else if (contentProperty.Setter?.IsPublic == true - && count == 1 - && TryGetCorrectlyTypedValue(context, getNode(0), - contentProperty.PropertyType, - out var value)) - setNode(0, - new XamlXPropertyAssignmentNode(getNode(0), contentProperty, value)); - // Collection property? - else if (contentProperty.Getter?.IsPublic == true) - { - for (var ind = 0; ind < count; ind++) - { - if (TryCallAdd(context, contentProperty, contentProperty.PropertyType, getNode(ind), out var addCall)) - setNode(ind, addCall); - else - { - var propFqn = contentProperty.PropertyType.GetFqn(); - var valueFqn = getNode(ind).Type.GetClrType().GetFqn(); - throw new XamlXLoadException( - $"Unable to directly convert {valueFqn} to {propFqn} find a suitable Add({valueFqn}) on type {propFqn}", - getNode(ind)); - } - } - } - else - throw new XamlXLoadException( - $"Unable to handle {getNode(0).Type.GetClrType().GetFqn()} assignment to {contentProperty.Name} " + - $"as either direct assignment or collection initialization, check if value type matches property type or that property type has proper Add method", - getNode(0)); - } - - - public static List GeneratePropertyAssignments(XamlXAstTransformationContext context, - XamlXAstClrProperty property, List nodes) - { - var tmp = nodes.Cast().ToList(); - GeneratePropertyAssignments(context, property, tmp.Count, - i => (IXamlXAstValueNode) tmp[i], - (i, v) => tmp[i] = v); - return tmp.Cast().ToList(); - }*/ - - class AdderCache : Dictionary> + class AdderCache : Dictionary> { } - public static IReadOnlyList FindPossibleAdders(XamlXAstTransformationContext context, - IXamlXType type) + public static IReadOnlyList FindPossibleAdders(AstTransformationContext context, + IXamlType type) { - IReadOnlyList FindPossibleAddersImpl() + IReadOnlyList FindPossibleAddersImpl() { var known = context.Configuration.WellKnownTypes; @@ -87,7 +32,7 @@ IReadOnlyList FindPossibleAddersImpl() if (actualType.GenericTypeDefinition?.Equals(known.IEnumerableT) == true) actualType = known.IListOfT.MakeGenericType(actualType.GenericArguments[0]); - var inspectTypes = new List(); + var inspectTypes = new List(); inspectTypes.Add(actualType); inspectTypes.AddRange(actualType.GetAllInterfaces()); @@ -95,7 +40,7 @@ IReadOnlyList FindPossibleAddersImpl() if (inspectTypes.Any(t => t.GenericTypeDefinition?.Equals(known.IListOfT) == true)) inspectTypes = inspectTypes.Where(t => !t.Equals(known.IList)).ToList(); - var rv = new List(); + var rv = new List(); foreach (var t in inspectTypes) { foreach (var m in t.FindMethods(m => m.Name == "Add" && m.IsPublic && !m.IsStatic @@ -116,7 +61,7 @@ IReadOnlyList FindPossibleAddersImpl() // Add casts for (var c = 0; c < rv.Count; c++) if (!rv[c].ThisOrFirstParameter().Equals(type)) - rv[c] = new XamlXMethodWithCasts(rv[c], new[] {type}.Concat(rv[c].Parameters)); + rv[c] = new XamlMethodWithCasts(rv[c], new[] {type}.Concat(rv[c].Parameters)); return rv; } @@ -131,9 +76,9 @@ IReadOnlyList FindPossibleAddersImpl() } - public static IEnumerable GetMarkupExtensionProvideValueAlternatives( - XamlXAstTransformationContext context, - IXamlXType type) + public static IEnumerable GetMarkupExtensionProvideValueAlternatives( + AstTransformationContext context, + IXamlType type) { var sp = context.Configuration.TypeMappings.ServiceProvider; return type.FindMethods(m => @@ -144,12 +89,12 @@ public static IEnumerable GetMarkupExtensionProvideValueAlternativ class MarkupExtensionProvideValueCache { - public Dictionary TypeToProvideValue = - new Dictionary(); + public Dictionary TypeToProvideValue = + new Dictionary(); } - public static bool TryConvertMarkupExtension(XamlXAstTransformationContext context, - IXamlXAstValueNode node, out XamlXMarkupExtensionNode o) + public static bool TryConvertMarkupExtension(AstTransformationContext context, + IXamlAstValueNode node, out XamlMarkupExtensionNode o) { var cache = context.GetOrCreateItem(); o = null; @@ -176,18 +121,18 @@ public static bool TryConvertMarkupExtension(XamlXAstTransformationContext conte if (provideValue == null) { if (node.Type.IsMarkupExtension) - throw new XamlXParseException( + throw new XamlParseException( $"{node.Type.GetClrType().GetFqn()} was resolved as markup extension, but doesn't have a matching ProvideValue/ProvideTypedValue method", node.Type); return false; } - o = new XamlXMarkupExtensionNode(node, provideValue, node); + o = new XamlMarkupExtensionNode(node, provideValue, node); return true; } - public static bool TryGetCorrectlyTypedValue(XamlXAstTransformationContext context, - IXamlXAstValueNode node, IXamlXType type, out IXamlXAstValueNode rv) + public static bool TryGetCorrectlyTypedValue(AstTransformationContext context, + IXamlAstValueNode node, IXamlType type, out IXamlAstValueNode rv) { if (type.IsAssignableFrom(node.Type.GetClrType())) { @@ -198,14 +143,14 @@ public static bool TryGetCorrectlyTypedValue(XamlXAstTransformationContext conte return TryConvertValue(context, node, type, null, out rv); } - public static IXamlXType TryGetTypeConverterFromCustomAttribute(XamlXTransformerConfiguration cfg, - IXamlXCustomAttribute attribute) + public static IXamlType TryGetTypeConverterFromCustomAttribute(TransformerConfiguration cfg, + IXamlCustomAttribute attribute) { if (attribute != null) { var arg = attribute.Parameters.FirstOrDefault(); - return (arg as IXamlXType) ?? + return (arg as IXamlType) ?? (arg is String sarg ? cfg.TypeSystem.FindType(sarg) : null); } @@ -214,9 +159,9 @@ public static IXamlXType TryGetTypeConverterFromCustomAttribute(XamlXTransformer } - public static bool TryConvertValue(XamlXAstTransformationContext context, - IXamlXAstValueNode node, IXamlXType type, XamlXAstClrProperty propertyContext, - out IXamlXAstValueNode rv) + public static bool TryConvertValue(AstTransformationContext context, + IXamlAstValueNode node, IXamlType type, XamlAstClrProperty propertyContext, + out IXamlAstValueNode rv) { rv = null; var cfg = context.Configuration; @@ -234,7 +179,7 @@ public static bool TryConvertValue(XamlXAstTransformationContext context, if (!nodeType.Equals(cfg.WellKnownTypes.String)) return false; - if (node is XamlXAstTextNode tn) + if (node is XamlAstTextNode tn) { if (type.IsEnum) { @@ -254,8 +199,8 @@ public static bool TryConvertValue(XamlXAstTransformationContext context, if (type.FullName == "System.Type") { - var resolvedType = XamlXTypeReferenceResolver.ResolveType(context, tn.Text, false, tn, true); - rv = new XamlXTypeExtensionNode(tn, resolvedType, type); + var resolvedType = TypeReferenceResolver.ResolveType(context, tn.Text, false, tn, true); + rv = new XamlTypeExtensionNode(tn, resolvedType, type); return true; } @@ -267,14 +212,14 @@ public static bool TryConvertValue(XamlXAstTransformationContext context, rootType.FindMethod(tn.Text, invoke.ReturnType, false, invoke.Parameters.ToArray()); if (handler != null) { - rv = new XamlXLoadMethodDelegateNode(tn, context.RootObject, type, handler); + rv = new XamlLoadMethodDelegateNode(tn, context.RootObject, type, handler); return true; } } } - IXamlXAstValueNode CreateInvariantCulture() => - new XamlXStaticOrTargetedReturnMethodCallNode(node, + IXamlAstValueNode CreateInvariantCulture() => + new XamlStaticOrTargetedReturnMethodCallNode(node, cfg.WellKnownTypes.CultureInfo.Methods.First(x => x.IsPublic && x.IsStatic && x.Name == "get_InvariantCulture"), null); @@ -294,17 +239,17 @@ IXamlXAstValueNode CreateInvariantCulture() => ?? candidates.FirstOrDefault(m => m.Parameters.Count == 1); if (parser != null) { - var args = new List {node}; + var args = new List {node}; if (parser.Parameters.Count == 2) args.Add(CreateInvariantCulture()); - rv = new XamlXStaticOrTargetedReturnMethodCallNode(node, parser, args); + rv = new XamlStaticOrTargetedReturnMethodCallNode(node, parser, args); return true; } if (cfg.TypeMappings.TypeDescriptorContext != null) { - IXamlXType converterType = null; + IXamlType converterType = null; if (propertyContext?.TypeConverters.TryGetValue(type, out converterType) != true) { var typeConverterAttribute = @@ -318,17 +263,17 @@ IXamlXAstValueNode CreateInvariantCulture() => var converterMethod = converterType.FindMethod("ConvertFrom", cfg.WellKnownTypes.Object, false, cfg.TypeMappings.TypeDescriptorContext, cfg.WellKnownTypes.CultureInfo, cfg.WellKnownTypes.Object); - rv = new XamlXAstNeedsParentStackValueNode(node, - new XamlXAstRuntimeCastNode(node, - new XamlXStaticOrTargetedReturnMethodCallNode(node, converterMethod, + rv = new XamlAstNeedsParentStackValueNode(node, + new XamlAstRuntimeCastNode(node, + new XamlStaticOrTargetedReturnMethodCallNode(node, converterMethod, new[] { - new XamlXAstNewClrObjectNode(node, - new XamlXAstClrTypeReference(node, converterType, false), null, - new List()), - new XamlXAstContextLocalNode(node, cfg.TypeMappings.TypeDescriptorContext), + new XamlAstNewClrObjectNode(node, + new XamlAstClrTypeReference(node, converterType, false), null, + new List()), + new XamlAstContextLocalNode(node, cfg.TypeMappings.TypeDescriptorContext), CreateInvariantCulture(), node - }), new XamlXAstClrTypeReference(node, type, false))); + }), new XamlAstClrTypeReference(node, type, false))); return true; } } diff --git a/src/XamlX/Transform/XamlXAstTransformationContext.cs b/src/XamlX/Transform/XamlXAstTransformationContext.cs deleted file mode 100644 index 01a77fce..00000000 --- a/src/XamlX/Transform/XamlXAstTransformationContext.cs +++ /dev/null @@ -1,126 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Xml; -using XamlX.Ast; -using XamlX.TypeSystem; - -namespace XamlX.Transform -{ -#if !XAMLIL_INTERNAL - public -#endif - class XamlXContextBase - { - private Dictionary _items = new Dictionary(); - private List _parentNodes = new List(); - public T GetItem() => (T) _items[typeof(T)]; - - public T GetOrCreateItem() where T : new() - { - if (!_items.TryGetValue(typeof(T), out var rv)) - _items[typeof(T)] = rv = new T(); - return (T)rv; - } - - public bool TryGetItem(out T rv) - { - var success = _items.TryGetValue(typeof(T), out var orv); - rv = (T)orv; - return success; - } - - public void SetItem(T item) => _items[typeof(T)] = item; - - - public IEnumerable ParentNodes() - { - for (var c = _parentNodes.Count - 1; c >= 0; c--) - yield return _parentNodes[c]; - } - - protected void PushParent(IXamlXAstNode node) => _parentNodes.Add(node); - - protected IXamlXAstNode PopParent() - { - var rv = _parentNodes[_parentNodes.Count - 1]; - _parentNodes.RemoveAt(_parentNodes.Count - 1); - return rv; - } - } - -#if !XAMLIL_INTERNAL - public -#endif - class XamlXAstTransformationContext : XamlXContextBase - { - public Dictionary NamespaceAliases { get; set; } = new Dictionary(); - public XamlXTransformerConfiguration Configuration { get; } - public IXamlXAstValueNode RootObject { get; set; } - public bool StrictMode { get; } - - public IXamlXAstNode Error(IXamlXAstNode node, Exception e) - { - if (StrictMode) - throw e; - return node; - } - - public IXamlXAstNode ParseError(string message, IXamlXAstNode node) => - Error(node, new XamlXParseException(message, node)); - - public IXamlXAstNode ParseError(string message, IXamlXAstNode offender, IXamlXAstNode ret) => - Error(ret, new XamlXParseException(message, offender)); - - public XamlXAstTransformationContext(XamlXTransformerConfiguration configuration, - Dictionary namespaceAliases, bool strictMode = true) - { - Configuration = configuration; - NamespaceAliases = namespaceAliases; - StrictMode = strictMode; - } - - class Visitor : IXamlXAstVisitor - { - private readonly XamlXAstTransformationContext _context; - private readonly IXamlXAstTransformer _transformer; - - public Visitor(XamlXAstTransformationContext context, IXamlXAstTransformer transformer) - { - _context = context; - _transformer = transformer; - } - - public IXamlXAstNode Visit(IXamlXAstNode node) - { - #if XAMLIL_DEBUG - return _transformer.Transform(_context, node); - #else - try - { - return _transformer.Transform(_context, node); - } - catch (Exception e) when (!(e is XmlException)) - { - throw new XamlXParseException( - "Internal compiler error while transforming node " + node + ":\n" + e, node); - } - #endif - } - - public void Push(IXamlXAstNode node) => _context.PushParent(node); - - public void Pop() => _context.PopParent(); - } - - public IXamlXAstNode Visit(IXamlXAstNode root, IXamlXAstTransformer transformer) - { - root = root.Visit(new Visitor(this, transformer)); - return root; - } - - public void VisitChildren(IXamlXAstNode root, IXamlXAstTransformer transformer) - { - root.VisitChildren(new Visitor(this, transformer)); - } - } -} diff --git a/src/XamlX/Transform/XamlXCompiler.cs b/src/XamlX/Transform/XamlXCompiler.cs deleted file mode 100644 index fb42ca3f..00000000 --- a/src/XamlX/Transform/XamlXCompiler.cs +++ /dev/null @@ -1,272 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Reflection.Emit; -using XamlX.Ast; -using XamlX.Transform.Emitters; -using XamlX.Transform.Transformers; -using XamlX.TypeSystem; - -namespace XamlX.Transform -{ -#if !XAMLIL_INTERNAL - public -#endif - class XamlXCompiler - { - private readonly XamlXTransformerConfiguration _configuration; - public List Transformers { get; } = new List(); - public List SimplificationTransformers { get; } = new List(); - public List Emitters { get; } = new List(); - - public bool EnableIlVerification { get; set; } - public XamlXCompiler(XamlXTransformerConfiguration configuration, bool fillWithDefaults) - { - _configuration = configuration; - if (fillWithDefaults) - { - Transformers = new List - { - new XamlXKnownDirectivesTransformer(), - new XamlXIntrinsicsTransformer(), - new XamlXXArgumentsTransformer(), - new XamlXTypeReferenceResolver(), - new XamlXMarkupExtensionTransformer(), - new XamlXPropertyReferenceResolver(), - new XamlXContentConvertTransformer(), - new XamlXResolveContentPropertyTransformer(), - new XamlXResolvePropertyValueAddersTransformer(), - new XamlXConvertPropertyValuesToAssignmentsTransformer(), - new XamlXNewObjectTransformer(), - new XamlXDeferredContentTransformer(), - new XamlXTopDownInitializationTransformer(), - }; - SimplificationTransformers = new List - { - new XamlXFlattenTransformer() - }; - Emitters = new List() - { - new NewObjectEmitter(), - new TextNodeEmitter(), - new MethodCallEmitter(), - new PropertyAssignmentEmitter(), - new PropertyValueManipulationEmitter(), - new ManipulationGroupEmitter(), - new ValueWithManipulationsEmitter(), - new MarkupExtensionEmitter(), - new ObjectInitializationNodeEmitter() - }; - } - } - - public XamlXAstTransformationContext CreateTransformationContext(XamlXDocument doc, bool strict) - => new XamlXAstTransformationContext(_configuration, doc.NamespaceAliases, strict); - - public void Transform(XamlXDocument doc,bool strict = true) - { - var ctx = CreateTransformationContext(doc, strict); - - var root = doc.Root; - ctx.RootObject = new XamlXRootObjectNode((XamlXAstObjectNode)root); - foreach (var transformer in Transformers) - { - ctx.VisitChildren(ctx.RootObject, transformer); - root = ctx.Visit(root, transformer); - } - - foreach (var simplifier in SimplificationTransformers) - root = ctx.Visit(root, simplifier); - - doc.Root = root; - } - - XamlXEmitContext InitCodeGen( - IFileSource file, - Func createSubType, - IXamlXEmitter codeGen, XamlXContext context, bool needContextLocal) - { - IXamlXLocal contextLocal = null; - - if (needContextLocal) - { - contextLocal = codeGen.DefineLocal(context.ContextType); - // Pass IService provider as the first argument to context factory - codeGen - .Emit(OpCodes.Ldarg_0); - context.Factory(codeGen); - codeGen.Emit(OpCodes.Stloc, contextLocal); - } - - var emitContext = new XamlXEmitContext(codeGen, _configuration, context, contextLocal, createSubType, file, - EnableIlVerification, Emitters); - return emitContext; - } - - void CompileBuild( - IFileSource fileSource, - IXamlXAstValueNode rootInstance, Func createSubType, - IXamlXEmitter codeGen, XamlXContext context, IXamlXMethod compiledPopulate) - { - var needContextLocal = !(rootInstance is XamlXAstNewClrObjectNode newObj && newObj.Arguments.Count == 0); - var emitContext = InitCodeGen(fileSource, createSubType, codeGen, context, needContextLocal); - - - var rv = codeGen.DefineLocal(rootInstance.Type.GetClrType()); - emitContext.Emit(rootInstance, codeGen, rootInstance.Type.GetClrType()); - codeGen - .Emit(OpCodes.Stloc, rv) - .Emit(OpCodes.Ldarg_0) - .Emit(OpCodes.Ldloc, rv) - .EmitCall(compiledPopulate) - .Emit(OpCodes.Ldloc, rv) - .Emit(OpCodes.Ret); - } - - /// - /// void Populate(IServiceProvider sp, T target); - /// - - void CompilePopulate(IFileSource fileSource, IXamlXAstManipulationNode manipulation, Func createSubType, IXamlXEmitter codeGen, XamlXContext context) - { - // Uncomment to inspect generated IL in debugger - //codeGen = new RecordingIlEmitter(codeGen); - var emitContext = InitCodeGen(fileSource, createSubType, codeGen, context, true); - - codeGen - .Emit(OpCodes.Ldloc, emitContext.ContextLocal) - .Emit(OpCodes.Ldarg_1) - .Emit(OpCodes.Stfld, context.RootObjectField) - .Emit(OpCodes.Ldloc, emitContext.ContextLocal) - .Emit(OpCodes.Ldarg_1) - .Emit(OpCodes.Stfld, context.IntermediateRootObjectField) - .Emit(OpCodes.Ldarg_1); - emitContext.Emit(manipulation, codeGen, null); - codeGen.Emit(OpCodes.Ret); - } - - public IXamlXType CreateContextType(IXamlXTypeBuilder builder) - { - return XamlXContextDefinition.GenerateContextClass(builder, - _configuration.TypeSystem, - _configuration.TypeMappings); - } - - public IXamlXMethodBuilder DefinePopulateMethod(IXamlXTypeBuilder typeBuilder, - XamlXDocument doc, - string name, bool isPublic) - { - var rootGrp = (XamlXValueWithManipulationNode) doc.Root; - return typeBuilder.DefineMethod(_configuration.WellKnownTypes.Void, - new[] {_configuration.TypeMappings.ServiceProvider, rootGrp.Type.GetClrType()}, - name, isPublic, true, false); - } - - public IXamlXMethodBuilder DefineBuildMethod(IXamlXTypeBuilder typeBuilder, - XamlXDocument doc, - string name, bool isPublic) - { - var rootGrp = (XamlXValueWithManipulationNode) doc.Root; - return typeBuilder.DefineMethod(rootGrp.Type.GetClrType(), - new[] {_configuration.TypeMappings.ServiceProvider}, name, isPublic, true, false); - } - - public void Compile(XamlXDocument doc, IXamlXTypeBuilder typeBuilder, IXamlXType contextType, - string populateMethodName, string createMethodName, string namespaceInfoClassName, - string baseUri, IFileSource fileSource) - { - var rootGrp = (XamlXValueWithManipulationNode) doc.Root; - Compile(doc, contextType, - DefinePopulateMethod(typeBuilder, doc, populateMethodName, true), - createMethodName == null ? - null : - DefineBuildMethod(typeBuilder, doc, createMethodName, true), - _configuration.TypeMappings.XmlNamespaceInfoProvider == null ? - null : - typeBuilder.DefineSubType(_configuration.WellKnownTypes.Object, - namespaceInfoClassName, false), - (name, bt) => typeBuilder.DefineSubType(bt, name, false), - baseUri, fileSource); - - } - - public void Compile( XamlXDocument doc, IXamlXType contextType, - IXamlXMethodBuilder populateMethod, IXamlXMethodBuilder buildMethod, - IXamlXTypeBuilder namespaceInfoBuilder, - Func createClosure, - string baseUri, IFileSource fileSource) - { - var rootGrp = (XamlXValueWithManipulationNode) doc.Root; - var staticProviders = new List(); - - if (namespaceInfoBuilder != null) - { - - staticProviders.Add( - XamlXNamespaceInfoHelper.EmitNamespaceInfoProvider(_configuration, namespaceInfoBuilder, doc)); - } - - var context = new XamlXContext(contextType, rootGrp.Type.GetClrType(), - _configuration.TypeMappings, baseUri, staticProviders); - - CompilePopulate(fileSource, rootGrp.Manipulation, createClosure, populateMethod.Generator, context); - - if (buildMethod != null) - { - CompileBuild(fileSource, rootGrp.Value, null, buildMethod.Generator, context, populateMethod); - } - - namespaceInfoBuilder?.CreateType(); - } - - - - } - - -#if !XAMLIL_INTERNAL - public -#endif - interface IXamlXAstTransformer - { - IXamlXAstNode Transform(XamlXAstTransformationContext context, IXamlXAstNode node); - } - -#if !XAMLIL_INTERNAL - public -#endif - class XamlXNodeEmitResult - { - public int ConsumedItems { get; } - public IXamlXType ReturnType { get; set; } - public int ProducedItems => ReturnType == null ? 0 : 1; - public bool AllowCast { get; set; } - - public XamlXNodeEmitResult(int consumedItems, IXamlXType returnType = null) - { - ConsumedItems = consumedItems; - ReturnType = returnType; - } - - public static XamlXNodeEmitResult Void(int consumedItems) => new XamlXNodeEmitResult(consumedItems); - - public static XamlXNodeEmitResult Type(int consumedItems, IXamlXType type) => - new XamlXNodeEmitResult(consumedItems, type); - } - -#if !XAMLIL_INTERNAL - public -#endif - interface IXamlXAstNodeEmitter - { - XamlXNodeEmitResult Emit(IXamlXAstNode node, XamlXEmitContext context, IXamlXEmitter codeGen); - } - -#if !XAMLIL_INTERNAL - public -#endif - interface IXamlXAstEmitableNode - { - XamlXNodeEmitResult Emit(XamlXEmitContext context, IXamlXEmitter codeGen); - } - -} diff --git a/src/XamlX/Transform/XamlXEmitContext.cs b/src/XamlX/Transform/XamlXEmitContext.cs deleted file mode 100644 index fb13d8a5..00000000 --- a/src/XamlX/Transform/XamlXEmitContext.cs +++ /dev/null @@ -1,191 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection.Emit; -using System.Xml; -using XamlX.Ast; -using XamlX.TypeSystem; - -namespace XamlX.Transform -{ -#if !XAMLIL_INTERNAL - public -#endif - class XamlXEmitContext : XamlXContextBase - { - public IFileSource File { get; } - public List Emitters { get; } - - private readonly Dictionary - _locals = new Dictionary(); - - private IXamlXAstNode _currentNode; - - public XamlXTransformerConfiguration Configuration { get; } - public XamlXContext RuntimeContext { get; } - public IXamlXLocal ContextLocal { get; } - public Func CreateSubType { get; } - public IXamlXEmitter Emitter { get; } - - public bool EnableIlVerification { get; } - - public XamlXEmitContext(IXamlXEmitter emitter, XamlXTransformerConfiguration configuration, - XamlXContext runtimeContext, IXamlXLocal contextLocal, - Func createSubType, - IFileSource file, bool enableIlVerification, IEnumerable emitters) - { - File = file; - EnableIlVerification = enableIlVerification; - Emitter = emitter; - Emitters = emitters.ToList(); - Configuration = configuration; - RuntimeContext = runtimeContext; - ContextLocal = contextLocal; - CreateSubType = createSubType; - } - - public void StLocal(XamlXAstCompilerLocalNode node, IXamlXEmitter codeGen) - { - if (!_locals.TryGetValue(node, out var local)) - _locals[node] = local = codeGen.DefineLocal(node.Type); - - codeGen.Emit(OpCodes.Stloc, local); - } - - public void LdLocal(XamlXAstCompilerLocalNode node, IXamlXEmitter codeGen) - { - if (_locals.TryGetValue(node, out var local)) - codeGen.Emit(OpCodes.Ldloc, local); - else - throw new XamlXLoadException("Attempt to read uninitialized local variable", node); - } - - public XamlXLocalsPool.PooledLocal GetLocal(IXamlXType type) - { - return Emitter.LocalsPool.GetLocal(type); - } - - public XamlXNodeEmitResult Emit(IXamlXAstNode value, IXamlXEmitter codeGen, IXamlXType expectedType) - { - XamlXNodeEmitResult res = null; - if (_currentNode != null) - { - PushParent(_currentNode); - _currentNode = value; - res = EmitCore(value, codeGen, expectedType); - _currentNode = PopParent(); - } - else - { - _currentNode = value; - res = EmitCore(value, codeGen, expectedType); - _currentNode = null; - } - - return res; - } - - private XamlXNodeEmitResult EmitCore(IXamlXAstNode value, IXamlXEmitter codeGen, IXamlXType expectedType) - { - CheckingIlEmitter parent = null; - CheckingIlEmitter checkedEmitter = null; - if (EnableIlVerification) - { - parent = codeGen as CheckingIlEmitter; - - parent?.Pause(); - checkedEmitter = new CheckingIlEmitter(codeGen); - } -#if XAMLIL_DEBUG - var res = EmitNode(value, checkedEmitter); -#else - XamlXNodeEmitResult res; - try - { - res = EmitNode(value, checkedEmitter ?? codeGen); - } - catch (Exception e) when (!(e is XmlException)) - { - throw new XamlXLoadException( - "Internal compiler error while emitting node " + value + ":\n" + e, value); - } -#endif - if (EnableIlVerification) - { - var expectedBalance = res.ProducedItems - res.ConsumedItems; - var checkResult = - checkedEmitter.Check(res.ProducedItems - res.ConsumedItems, false); - if (checkResult != null) - throw new XamlXLoadException($"Error during IL verification: {checkResult}\n{checkedEmitter}\n", - value); - parent?.Resume(); - parent?.ExplicitStack(expectedBalance); - } - - var returnedType = res.ReturnType; - - if (returnedType != null || expectedType != null) - { - - if (returnedType != null && expectedType == null) - throw new XamlXLoadException( - $"Emit of node {value} resulted in {returnedType.GetFqn()} while caller expected void", value); - - if (expectedType != null && returnedType == null) - throw new XamlXLoadException( - $"Emit of node {value} resulted in void while caller expected {expectedType.GetFqn()}", value); - - if (!returnedType.Equals(expectedType)) - { - XamlXLocalsPool.PooledLocal local = null; - // ReSharper disable once ExpressionIsAlwaysNull - // Value is assigned inside the closure in certain conditions - - TypeSystemHelpers.EmitConvert(this, value, returnedType, expectedType, ldaddr => - { - if (ldaddr && returnedType.IsValueType) - { - // We need to store the value to a temporary variable, since *address* - // is required (probably for method call on the value type) - local = GetLocal(returnedType); - codeGen - .Stloc(local.Local) - .Ldloca(local.Local); - - } - // Otherwise do nothing, value is already at the top of the stack - return codeGen; - }); - local?.Dispose(); - } - - } - - - return res; - } - - private XamlXNodeEmitResult EmitNode(IXamlXAstNode value, IXamlXEmitter codeGen) - { - if(File!=null) - codeGen.InsertSequencePoint(File, value.Line, value.Position); - - XamlXNodeEmitResult res = null; - foreach (var e in Emitters) - { - if (e is IXamlXAstNodeEmitter ve) - { - res = ve.Emit(value, this, codeGen); - if (res != null) - return res; - } - } - - if (value is IXamlXAstEmitableNode en) - return en.Emit(this, codeGen); - else - throw new XamlXLoadException("Unable to find emitter for node type: " + value.GetType().FullName, - value); - } - } -} diff --git a/src/XamlX/Transform/XamlXLanguageTypeMappings.cs b/src/XamlX/Transform/XamlXLanguageTypeMappings.cs deleted file mode 100644 index 1763b6fc..00000000 --- a/src/XamlX/Transform/XamlXLanguageTypeMappings.cs +++ /dev/null @@ -1,73 +0,0 @@ -using System; -using System.Collections.Generic; -using XamlX.Ast; -using XamlX.TypeSystem; - -namespace XamlX.Transform -{ -#if !XAMLIL_INTERNAL - public -#endif - class XamlXLanguageTypeMappings - { - public XamlXLanguageTypeMappings(IXamlXTypeSystem typeSystem) - { - ServiceProvider = typeSystem.GetType("System.IServiceProvider"); - TypeDescriptorContext = typeSystem.GetType("System.ComponentModel.ITypeDescriptorContext"); - SupportInitialize = typeSystem.GetType("System.ComponentModel.ISupportInitialize"); - var tconv = typeSystem.GetType("System.ComponentModel.TypeConverterAttribute"); - if (tconv != null) - TypeConverterAttributes.Add(tconv); - } - - public List XmlnsAttributes { get; set; } = new List(); - public List UsableDuringInitializationAttributes { get; set; } = new List(); - public List ContentAttributes { get; set; } = new List(); - public List TypeConverterAttributes { get; set; } = new List(); - public IXamlXType ServiceProvider { get; set; } - public IXamlXType TypeDescriptorContext { get; set; } - public IXamlXType SupportInitialize { get; set; } - public IXamlXType ProvideValueTarget { get; set; } - public IXamlXType RootObjectProvider { get; set; } - public IXamlXType ParentStackProvider { get; set; } - public IXamlXType XmlNamespaceInfoProvider { get; set; } - public IXamlXType UriContextProvider { get; set; } - - public IXamlXCustomAttributeResolver CustomAttributeResolver { get; set; } - - /// - /// Expected signature: - /// static IServiceProvider InnerServiceProviderFactory(IServiceProvider self); - /// - public IXamlXMethod InnerServiceProviderFactoryMethod { get; set; } - /// - /// static Func<IServiceProvider, object> DeferredTransformationFactory(Func<IServiceProvider, object> builder, IServiceProvider provider); - /// - public IXamlXMethod DeferredContentExecutorCustomization { get; set; } - public List DeferredContentPropertyAttributes { get; set; } = new List(); - public Func ProvideValueTargetPropertyEmitter { get; set; } - public string RootObjectProviderIntermediateRootPropertyName { get; set; } - public XamlXContextTypeBuilderCallback ContextTypeBuilderCallback { get; set; } - public XamlXContextFactoryCallback ContextFactoryCallback { get; set; } - - } - -#if !XAMLIL_INTERNAL - public -#endif - delegate void XamlXContextTypeBuilderCallback(IXamlXTypeBuilder typeBuilder, IXamlXEmitter constructor); - -#if !XAMLIL_INTERNAL - public -#endif - delegate void XamlXContextFactoryCallback(XamlXContext context, IXamlXEmitter emitter); - -#if !XAMLIL_INTERNAL - public -#endif - interface IXamlXCustomAttributeResolver - { - IXamlXCustomAttribute GetCustomAttribute(IXamlXType type, IXamlXType attributeType); - IXamlXCustomAttribute GetCustomAttribute(IXamlXProperty property, IXamlXType attributeType); - } -} diff --git a/src/XamlX/Transform/XamlXXmlnsMappings.cs b/src/XamlX/Transform/XamlXmlnsMappings.cs similarity index 67% rename from src/XamlX/Transform/XamlXXmlnsMappings.cs rename to src/XamlX/Transform/XamlXmlnsMappings.cs index db00925e..f5c960f2 100644 --- a/src/XamlX/Transform/XamlXXmlnsMappings.cs +++ b/src/XamlX/Transform/XamlXmlnsMappings.cs @@ -3,22 +3,22 @@ namespace XamlX.Transform { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXXmlnsMappings + class XamlXmlnsMappings { - public Dictionary> Namespaces { get; set; } = - new Dictionary>(); + public Dictionary> Namespaces { get; set; } = + new Dictionary>(); - public XamlXXmlnsMappings() + public XamlXmlnsMappings() { } - public static XamlXXmlnsMappings Resolve(IXamlXTypeSystem typeSystem, XamlXLanguageTypeMappings typeMappings) + public static XamlXmlnsMappings Resolve(IXamlTypeSystem typeSystem, XamlLanguageTypeMappings typeMappings) { - var rv = new XamlXXmlnsMappings(); + var rv = new XamlXmlnsMappings(); foreach (var asm in typeSystem.Assemblies) foreach (var attr in asm.CustomAttributes) foreach (var xmlnsType in typeMappings.XmlnsAttributes) @@ -29,11 +29,11 @@ public static XamlXXmlnsMappings Resolve(IXamlXTypeSystem typeSystem, XamlXLangu attr.Parameters[1] is string clrns) { if (!rv.Namespaces.TryGetValue(xmlns, out var lst)) - rv.Namespaces[xmlns] = lst = new List<(IXamlXAssembly asm, string ns)>(); + rv.Namespaces[xmlns] = lst = new List<(IXamlAssembly asm, string ns)>(); lst.Add((asm, clrns)); } else - throw new XamlXParseException( + throw new XamlParseException( $"Unexpected parameters for {xmlnsType.GetFqn()} declared on assembly {asm.Name}", 0, 0); break; diff --git a/src/XamlX/TypeSystem/TypeSystem.cs b/src/XamlX/TypeSystem/TypeSystem.cs index 0016583c..e8a4e7c7 100644 --- a/src/XamlX/TypeSystem/TypeSystem.cs +++ b/src/XamlX/TypeSystem/TypeSystem.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections; using System.Collections.Generic; using System.Linq; @@ -7,167 +7,134 @@ namespace XamlX.TypeSystem { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - interface IXamlXType : IEquatable + interface IXamlType : IEquatable { object Id { get; } string Name { get; } string Namespace { get; } string FullName { get; } - IXamlXAssembly Assembly { get; } - IReadOnlyList Properties { get; } - IReadOnlyList Events { get; } - IReadOnlyList Fields { get; } - IReadOnlyList Methods { get; } - IReadOnlyList Constructors { get; } - IReadOnlyList CustomAttributes { get; } - IReadOnlyList GenericArguments { get; } - bool IsAssignableFrom(IXamlXType type); - IXamlXType MakeGenericType(IReadOnlyList typeArguments); - IXamlXType GenericTypeDefinition { get; } + IXamlAssembly Assembly { get; } + IReadOnlyList Properties { get; } + IReadOnlyList Events { get; } + IReadOnlyList Fields { get; } + IReadOnlyList Methods { get; } + IReadOnlyList Constructors { get; } + IReadOnlyList CustomAttributes { get; } + IReadOnlyList GenericArguments { get; } + bool IsAssignableFrom(IXamlType type); + IXamlType MakeGenericType(IReadOnlyList typeArguments); + IXamlType GenericTypeDefinition { get; } bool IsArray { get; } - IXamlXType ArrayElementType { get; } - IXamlXType MakeArrayType(int dimensions); - IXamlXType BaseType { get; } + IXamlType ArrayElementType { get; } + IXamlType MakeArrayType(int dimensions); + IXamlType BaseType { get; } bool IsValueType { get; } bool IsEnum { get; } - IReadOnlyList Interfaces { get; } + IReadOnlyList Interfaces { get; } bool IsInterface { get; } - IXamlXType GetEnumUnderlyingType(); - IReadOnlyList GenericParameters { get; } + IXamlType GetEnumUnderlyingType(); + IReadOnlyList GenericParameters { get; } int GetHashCode(); } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - interface IXamlXMethod : IEquatable, IXamlXMember + interface IXamlMethod : IEquatable, IXamlMember { bool IsPublic { get; } bool IsStatic { get; } - IXamlXType ReturnType { get; } - IReadOnlyList Parameters { get; } - IXamlXType DeclaringType { get; } - IXamlXMethod MakeGenericMethod(IReadOnlyList typeArguments); + IXamlType ReturnType { get; } + IReadOnlyList Parameters { get; } + IXamlType DeclaringType { get; } + IXamlMethod MakeGenericMethod(IReadOnlyList typeArguments); } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - interface IXamlXCustomEmitMethod : IXamlXMethod - { - void EmitCall(IXamlXEmitter emitter); - } - -#if !XAMLIL_INTERNAL - public -#endif - interface IXamlXMember + interface IXamlMember { string Name { get; } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - interface IXamlXConstructor : IEquatable + interface IXamlConstructor : IEquatable { bool IsPublic { get; } bool IsStatic { get; } - IReadOnlyList Parameters { get; } + IReadOnlyList Parameters { get; } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - interface IXamlXProperty : IEquatable, IXamlXMember + interface IXamlProperty : IEquatable, IXamlMember { - IXamlXType PropertyType { get; } - IXamlXMethod Setter { get; } - IXamlXMethod Getter { get; } - IReadOnlyList CustomAttributes { get; } - IReadOnlyList IndexerParameters { get; } + IXamlType PropertyType { get; } + IXamlMethod Setter { get; } + IXamlMethod Getter { get; } + IReadOnlyList CustomAttributes { get; } + IReadOnlyList IndexerParameters { get; } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - interface IXamlXEventInfo : IEquatable, IXamlXMember + interface IXamlEventInfo : IEquatable, IXamlMember { - IXamlXMethod Add { get; } + IXamlMethod Add { get; } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - interface IXamlXField : IEquatable, IXamlXMember + interface IXamlField : IEquatable, IXamlMember { - IXamlXType FieldType { get; } + IXamlType FieldType { get; } bool IsPublic { get; } bool IsStatic { get; } bool IsLiteral { get; } object GetLiteralValue(); } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - interface IXamlXAssembly : IEquatable + interface IXamlAssembly : IEquatable { string Name { get; } - IReadOnlyList CustomAttributes { get; } - IXamlXType FindType(string fullName); + IReadOnlyList CustomAttributes { get; } + IXamlType FindType(string fullName); } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - interface IXamlXCustomAttribute : IEquatable + interface IXamlCustomAttribute : IEquatable { - IXamlXType Type { get; } + IXamlType Type { get; } List Parameters { get; } Dictionary Properties { get; } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - interface IXamlXTypeSystem + interface IXamlTypeSystem { - IReadOnlyList Assemblies { get; } - IXamlXAssembly FindAssembly(string substring); - IXamlXType FindType(string name); - IXamlXType FindType(string name, string assembly); + IReadOnlyList Assemblies { get; } + IXamlAssembly FindAssembly(string substring); + IXamlType FindType(string name); + IXamlType FindType(string name, string assembly); } -#if !XAMLIL_INTERNAL - public -#endif - interface IXamlXEmitter - { - IXamlXTypeSystem TypeSystem { get; } - IXamlXEmitter Emit(OpCode code); - IXamlXEmitter Emit(OpCode code, IXamlXField field); - IXamlXEmitter Emit(OpCode code, IXamlXMethod method); - IXamlXEmitter Emit(OpCode code, IXamlXConstructor ctor); - IXamlXEmitter Emit(OpCode code, string arg); - IXamlXEmitter Emit(OpCode code, int arg); - IXamlXEmitter Emit(OpCode code, long arg); - IXamlXEmitter Emit(OpCode code, IXamlXType type); - IXamlXEmitter Emit(OpCode code, float arg); - IXamlXEmitter Emit(OpCode code, double arg); - IXamlXLocal DefineLocal(IXamlXType type); - IXamlXLabel DefineLabel(); - IXamlXEmitter MarkLabel(IXamlXLabel label); - IXamlXEmitter Emit(OpCode code, IXamlXLabel label); - IXamlXEmitter Emit(OpCode code, IXamlXLocal local); - void InsertSequencePoint(IFileSource file, int line, int position); - XamlXLocalsPool LocalsPool { get; } - } - -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif interface IFileSource @@ -176,129 +143,127 @@ interface IFileSource byte[] FileContents { get; } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - interface IXamlXLocal + interface IXamlLocal { } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - interface IXamlXLabel + interface IXamlLabel { } - -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - interface IXamlXMethodBuilder : IXamlXMethod + interface IXamlTypeBuilder : IXamlType { - IXamlXEmitter Generator { get; } + IXamlField DefineField(IXamlType type, string name, bool isPublic, bool isStatic); + void AddInterfaceImplementation(IXamlType type); + + IXamlMethodBuilder DefineMethod(IXamlType returnType, IEnumerable args, string name, bool isPublic, bool isStatic, + bool isInterfaceImpl, IXamlMethod overrideMethod = null); + + IXamlProperty DefineProperty(IXamlType propertyType, string name, IXamlMethod setter, IXamlMethod getter); + IXamlConstructorBuilder DefineConstructor(bool isStatic, params IXamlType[] args); + IXamlType CreateType(); + IXamlTypeBuilder DefineSubType(IXamlType baseType, string name, bool isPublic); + void DefineGenericParameters(IReadOnlyList> names); } - -#if !XAMLIL_INTERNAL + +#if !XAMLX_INTERNAL public #endif - interface IXamlXConstructorBuilder : IXamlXConstructor + interface IXamlMethodBuilder : IXamlMethod { - IXamlXEmitter Generator { get; } + TBackendEmitter Generator { get; } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - interface IXamlXTypeBuilder : IXamlXType + interface IXamlConstructorBuilder : IXamlConstructor { - IXamlXField DefineField(IXamlXType type, string name, bool isPublic, bool isStatic); - void AddInterfaceImplementation(IXamlXType type); - - IXamlXMethodBuilder DefineMethod(IXamlXType returnType, IEnumerable args, string name, bool isPublic, bool isStatic, - bool isInterfaceImpl, IXamlXMethod overrideMethod = null); - - IXamlXProperty DefineProperty(IXamlXType propertyType, string name, IXamlXMethod setter, IXamlXMethod getter); - IXamlXConstructorBuilder DefineConstructor(bool isStatic, params IXamlXType[] args); - IXamlXType CreateType(); - IXamlXTypeBuilder DefineSubType(IXamlXType baseType, string name, bool isPublic); - void DefineGenericParameters(IReadOnlyList> names); + TBackendEmitter Generator { get; } } - -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - struct XamlXGenericParameterConstraint + struct XamlGenericParameterConstraint { public bool IsClass { get; set; } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXPseudoType : IXamlXType + class XamlPseudoType : IXamlType { - public XamlXPseudoType(string name) + public XamlPseudoType(string name) { Name = name; } - public bool Equals(IXamlXType other) => other == this; + public bool Equals(IXamlType other) => other == this; public object Id { get; } = Guid.NewGuid(); public string Name { get; } public string Namespace { get; } = ""; public string FullName => Name; - public IXamlXAssembly Assembly { get; } = null; - public IReadOnlyList Properties { get; } = new IXamlXProperty[0]; - public IReadOnlyList Events { get; } = new IXamlXEventInfo[0]; - public IReadOnlyList Fields { get; } = new List(); - public IReadOnlyList Methods { get; } = new IXamlXMethod[0]; - public IReadOnlyList Constructors { get; } = new IXamlXConstructor[0]; - public IReadOnlyList CustomAttributes { get; } = new IXamlXCustomAttribute[0]; - public IReadOnlyList GenericArguments { get; } = new IXamlXType[0]; - public IXamlXType MakeArrayType(int dimensions) => throw new NullReferenceException(); - - public IXamlXType BaseType { get; } + public IXamlAssembly Assembly { get; } = null; + public IReadOnlyList Properties { get; } = new IXamlProperty[0]; + public IReadOnlyList Events { get; } = new IXamlEventInfo[0]; + public IReadOnlyList Fields { get; } = new List(); + public IReadOnlyList Methods { get; } = new IXamlMethod[0]; + public IReadOnlyList Constructors { get; } = new IXamlConstructor[0]; + public IReadOnlyList CustomAttributes { get; } = new IXamlCustomAttribute[0]; + public IReadOnlyList GenericArguments { get; } = new IXamlType[0]; + public IXamlType MakeArrayType(int dimensions) => throw new NullReferenceException(); + + public IXamlType BaseType { get; } public bool IsValueType { get; } = false; public bool IsEnum { get; } = false; - public IReadOnlyList Interfaces { get; } = new IXamlXType[0]; + public IReadOnlyList Interfaces { get; } = new IXamlType[0]; public bool IsInterface => false; - public IXamlXType GetEnumUnderlyingType() => throw new InvalidOperationException(); - public IReadOnlyList GenericParameters { get; } = null; + public IXamlType GetEnumUnderlyingType() => throw new InvalidOperationException(); + public IReadOnlyList GenericParameters { get; } = null; - public bool IsAssignableFrom(IXamlXType type) => type == this; + public bool IsAssignableFrom(IXamlType type) => type == this; - public IXamlXType MakeGenericType(IReadOnlyList typeArguments) + public IXamlType MakeGenericType(IReadOnlyList typeArguments) { throw new NotSupportedException(); } - public IXamlXType GenericTypeDefinition => null; + public IXamlType GenericTypeDefinition => null; public bool IsArray { get; } - public IXamlXType ArrayElementType { get; } - public static XamlXPseudoType Null { get; } = new XamlXPseudoType("{x:Null}"); - public static XamlXPseudoType Unknown { get; } = new XamlXPseudoType("{Unknown type}"); + public IXamlType ArrayElementType { get; } + public static XamlPseudoType Null { get; } = new XamlPseudoType("{x:Null}"); + public static XamlPseudoType Unknown { get; } = new XamlPseudoType("{Unknown type}"); - public static XamlXPseudoType Unresolved(string message) => - new XamlXPseudoType($"{{Unresolved type: '{message}'}}"); + public static XamlPseudoType Unresolved(string message) => + new XamlPseudoType($"{{Unresolved type: '{message}'}}"); } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif class FindMethodMethodSignature { public string Name { get; set; } - public IXamlXType ReturnType { get; set; } + public IXamlType ReturnType { get; set; } public bool IsStatic { get; set; } public bool IsExactMatch { get; set; } = true; public bool DeclaringOnly { get; set; } = false; - public IReadOnlyList Parameters { get; set; } + public IReadOnlyList Parameters { get; set; } - public FindMethodMethodSignature(string name, IXamlXType returnType, params IXamlXType[] parameters) + public FindMethodMethodSignature(string name, IXamlType returnType, params IXamlType[] parameters) { Name = name; ReturnType = returnType; @@ -312,14 +277,14 @@ public override string ToString() } } -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - static class XamlXTypeSystemExtensions + static class XamlTypeSystemExtensions { - public static string GetFqn(this IXamlXType type) => $"{type.Assembly?.Name}:{type.Namespace}.{type.Name}"; + public static string GetFqn(this IXamlType type) => $"{type.Assembly?.Name}:{type.Namespace}.{type.Name}"; - public static string GetFullName(this IXamlXType type) + public static string GetFullName(this IXamlType type) { var name = type.Name; if (type.Namespace != null) @@ -329,15 +294,15 @@ public static string GetFullName(this IXamlXType type) return name; } - public static IXamlXType GetType(this IXamlXTypeSystem sys, string type) + public static IXamlType GetType(this IXamlTypeSystem sys, string type) { var f = sys.FindType(type); if (f == null) - throw new XamlXTypeSystemException("Unable to resolve type " + type); + throw new XamlTypeSystemException("Unable to resolve type " + type); return f; } - public static IEnumerable FindMethods(this IXamlXType type, Func criteria) + public static IEnumerable FindMethods(this IXamlType type, Func criteria) { foreach (var m in type.Methods) if (criteria(m)) @@ -352,7 +317,7 @@ public static IEnumerable FindMethods(this IXamlXType type, Func criteria) + public static IXamlMethod FindMethod(this IXamlType type, Func criteria) { foreach (var m in type.Methods) if (criteria(m)) @@ -367,8 +332,8 @@ public static IXamlXMethod FindMethod(this IXamlXType type, Func args = null) + public static IXamlConstructor FindConstructor(this IXamlType type, List args = null) { if(args == null) - args = new List(); + args = new List(); foreach (var ctor in type.Constructors.Where(c => c.IsPublic && !c.IsStatic && c.Parameters.Count == args.Count)) @@ -456,34 +421,22 @@ public static IXamlXConstructor FindConstructor(this IXamlXType type, List type.MakeGenericType(typeArguments); - public static IEnumerable GetAllInterfaces(this IXamlXType type) + public static IEnumerable GetAllInterfaces(this IXamlType type) { foreach (var i in type.Interfaces) yield return i; @@ -492,7 +445,7 @@ public static IEnumerable GetAllInterfaces(this IXamlXType type) yield return i; } - public static IEnumerable GetAllProperties(this IXamlXType t) + public static IEnumerable GetAllProperties(this IXamlType t) { foreach (var p in t.Properties) yield return p; @@ -501,7 +454,7 @@ public static IEnumerable GetAllProperties(this IXamlXType t) yield return p; } - public static IEnumerable GetAllFields(this IXamlXType t) + public static IEnumerable GetAllFields(this IXamlType t) { foreach (var p in t.Fields) yield return p; @@ -510,7 +463,7 @@ public static IEnumerable GetAllFields(this IXamlXType t) yield return p; } - public static IEnumerable GetAllEvents(this IXamlXType t) + public static IEnumerable GetAllEvents(this IXamlType t) { foreach (var p in t.Events) yield return p; @@ -519,17 +472,17 @@ public static IEnumerable GetAllEvents(this IXamlXType t) yield return p; } - public static bool IsDirectlyAssignableFrom(this IXamlXType type, IXamlXType other) + public static bool IsDirectlyAssignableFrom(this IXamlType type, IXamlType other) { if (type.IsValueType || other.IsValueType) return type.Equals(other); return type.IsAssignableFrom(other); } - public static IXamlXType ThisOrFirstParameter(this IXamlXMethod method) => + public static IXamlType ThisOrFirstParameter(this IXamlMethod method) => method.IsStatic ? method.Parameters[0] : method.DeclaringType; - public static IReadOnlyList ParametersWithThis(this IXamlXMethod method) + public static IReadOnlyList ParametersWithThis(this IXamlMethod method) { if (method.IsStatic) return method.Parameters; @@ -537,16 +490,6 @@ public static IReadOnlyList ParametersWithThis(this IXamlXMethod met lst.Insert(0, method.DeclaringType); return lst; } - - public static IXamlXEmitter DebugHatch(this IXamlXEmitter emitter, string message) - { - #if DEBUG - var debug = emitter.TypeSystem.GetType("XamlX.XamlXDebugHatch").FindMethod(m => m.Name == "Debug"); - emitter.Emit(OpCodes.Ldstr, message); - emitter.Emit(OpCodes.Call, debug); - #endif - return emitter; - } } } diff --git a/src/XamlX/TypeSystem/TypeSystemExtensions.cs b/src/XamlX/TypeSystem/TypeSystemExtensions.cs deleted file mode 100644 index f1860e37..00000000 --- a/src/XamlX/TypeSystem/TypeSystemExtensions.cs +++ /dev/null @@ -1,143 +0,0 @@ -using System; -using System.Reflection; -using System.Reflection.Emit; - -namespace XamlX.TypeSystem -{ -#if !XAMLIL_INTERNAL - public -#endif - static class TypeSystemExtensions - { - public static IXamlXEmitter Ldarg(this IXamlXEmitter emitter, int arg) - => emitter.Emit(OpCodes.Ldarg, arg); - - public static IXamlXEmitter Ldarg_0(this IXamlXEmitter emitter) - => emitter.Emit(OpCodes.Ldarg_0); - - public static IXamlXEmitter Ldfld(this IXamlXEmitter emitter, IXamlXField field) - => emitter.Emit(OpCodes.Ldfld, field); - - public static IXamlXEmitter Ldsfld(this IXamlXEmitter emitter, IXamlXField field) - => emitter.Emit(OpCodes.Ldsfld, field); - - public static IXamlXEmitter LdThisFld(this IXamlXEmitter emitter, IXamlXField field) - => emitter.Ldarg_0().Emit(OpCodes.Ldfld, field); - - public static IXamlXEmitter Stfld(this IXamlXEmitter emitter, IXamlXField field) - => emitter.Emit(OpCodes.Stfld, field); - - public static IXamlXEmitter Stsfld(this IXamlXEmitter emitter, IXamlXField field) - => emitter.Emit(OpCodes.Stsfld, field); - - public static IXamlXEmitter Ldloc(this IXamlXEmitter emitter, IXamlXLocal local) - => emitter.Emit(OpCodes.Ldloc, local); - - public static IXamlXEmitter Ldloca(this IXamlXEmitter emitter, IXamlXLocal local) - => emitter.Emit(OpCodes.Ldloca, local); - - public static IXamlXEmitter Stloc(this IXamlXEmitter emitter, IXamlXLocal local) - => emitter.Emit(OpCodes.Stloc, local); - - public static IXamlXEmitter Ldnull(this IXamlXEmitter emitter) => emitter.Emit(OpCodes.Ldnull); - - public static IXamlXEmitter Ldstr(this IXamlXEmitter emitter, string arg) - => arg == null ? emitter.Ldnull() : emitter.Emit(OpCodes.Ldstr, arg); - - public static IXamlXEmitter Throw(this IXamlXEmitter emitter) - => emitter.Emit(OpCodes.Throw); - - public static IXamlXEmitter Ldc_I4(this IXamlXEmitter emitter, int arg) - => arg == 0 - ? emitter.Emit(OpCodes.Ldc_I4_0) - : arg == 1 - ? emitter.Emit(OpCodes.Ldc_I4_1) - : emitter.Emit(OpCodes.Ldc_I4, arg); - - public static IXamlXEmitter Beq(this IXamlXEmitter emitter, IXamlXLabel label) - => emitter.Emit(OpCodes.Beq, label); - - public static IXamlXEmitter Blt(this IXamlXEmitter emitter, IXamlXLabel label) - => emitter.Emit(OpCodes.Blt, label); - - public static IXamlXEmitter Ble(this IXamlXEmitter emitter, IXamlXLabel label) - => emitter.Emit(OpCodes.Ble, label); - - public static IXamlXEmitter Bgt(this IXamlXEmitter emitter, IXamlXLabel label) - => emitter.Emit(OpCodes.Bgt, label); - - public static IXamlXEmitter Bge(this IXamlXEmitter emitter, IXamlXLabel label) - => emitter.Emit(OpCodes.Bge, label); - - public static IXamlXEmitter Br(this IXamlXEmitter emitter, IXamlXLabel label) - => emitter.Emit(OpCodes.Br, label); - - public static IXamlXEmitter Brfalse(this IXamlXEmitter emitter, IXamlXLabel label) - => emitter.Emit(OpCodes.Brfalse, label); - - public static IXamlXEmitter Brtrue(this IXamlXEmitter emitter, IXamlXLabel label) - => emitter.Emit(OpCodes.Brtrue, label); - - public static IXamlXEmitter Ret(this IXamlXEmitter emitter) - => emitter.Emit(OpCodes.Ret); - - public static IXamlXEmitter Dup(this IXamlXEmitter emitter) - => emitter.Emit(OpCodes.Dup); - - public static IXamlXEmitter Pop(this IXamlXEmitter emitter) - => emitter.Emit(OpCodes.Pop); - - public static IXamlXEmitter Ldtoken(this IXamlXEmitter emitter, IXamlXType type) - => emitter.Emit(OpCodes.Ldtoken, type); - - public static IXamlXEmitter Ldtoken(this IXamlXEmitter emitter, IXamlXMethod method) - => emitter.Emit(OpCodes.Ldtoken, method); - - public static IXamlXEmitter Ldtype(this IXamlXEmitter emitter, IXamlXType type) - { - var conv = emitter.TypeSystem.GetType("System.Type") - .FindMethod(m => m.IsStatic && m.IsPublic && m.Name == "GetTypeFromHandle"); - return emitter.Ldtoken(type).EmitCall(conv); - } - - public static IXamlXEmitter LdMethodInfo(this IXamlXEmitter emitter, IXamlXMethod method) - { - var conv = emitter.TypeSystem.GetType("System.Reflection.MethodInfo") - .FindMethod(m => m.IsStatic && m.IsPublic && m.Name == "GetMethodFromHandle"); - return emitter.Ldtoken(method).EmitCall(conv); - } - - public static IXamlXEmitter Ldftn(this IXamlXEmitter emitter, IXamlXMethod method) - => emitter.Emit(OpCodes.Ldftn, method); - - public static IXamlXEmitter Isinst(this IXamlXEmitter emitter, IXamlXType type) - => emitter.Emit(OpCodes.Isinst, type); - - public static IXamlXEmitter Castclass(this IXamlXEmitter emitter, IXamlXType type) - => emitter.Emit(OpCodes.Castclass, type); - - public static IXamlXEmitter Box(this IXamlXEmitter emitter, IXamlXType type) - => emitter.Emit(OpCodes.Box, type); - - public static IXamlXEmitter Unbox_Any(this IXamlXEmitter emitter, IXamlXType type) - => emitter.Emit(OpCodes.Unbox_Any, type); - - - public static IXamlXEmitter Unbox(this IXamlXEmitter emitter, IXamlXType type) - => emitter.Emit(OpCodes.Unbox, type); - - public static IXamlXEmitter Newobj(this IXamlXEmitter emitter, IXamlXConstructor ctor) - => emitter.Emit(OpCodes.Newobj, ctor); - - public static IXamlXEmitter Newarr(this IXamlXEmitter emitter, IXamlXType type) - => emitter.Emit(OpCodes.Newarr, type); - - public static IXamlXEmitter Ldelem_ref(this IXamlXEmitter emitter) => emitter.Emit(OpCodes.Ldelem_Ref); - public static IXamlXEmitter Stelem_ref(this IXamlXEmitter emitter) => emitter.Emit(OpCodes.Stelem_Ref); - public static IXamlXEmitter Ldlen(this IXamlXEmitter emitter) => emitter.Emit(OpCodes.Ldlen); - - public static IXamlXEmitter Add(this IXamlXEmitter emitter) => emitter.Emit(OpCodes.Add); - - - } -} diff --git a/src/XamlX/TypeSystem/TypeSystemHelpers.cs b/src/XamlX/TypeSystem/TypeSystemHelpers.cs index 056b44e1..166d0776 100644 --- a/src/XamlX/TypeSystem/TypeSystemHelpers.cs +++ b/src/XamlX/TypeSystem/TypeSystemHelpers.cs @@ -8,7 +8,7 @@ namespace XamlX.TypeSystem { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif class TypeSystemHelpers @@ -27,28 +27,10 @@ public static long ConvertLiteralToLong(object literal) return (long) Convert.ChangeType(literal, typeof(long)); } - public static void EmitFieldLiteral(IXamlXField field, IXamlXEmitter codeGen) - { - var ftype = field.FieldType.IsEnum ? field.FieldType.GetEnumUnderlyingType() : field.FieldType; - - if (ftype.Name == "UInt64" || ftype.Name == "Int64") - codeGen.Emit(OpCodes.Ldc_I8, - TypeSystemHelpers.ConvertLiteralToLong(field.GetLiteralValue())); - else if (ftype.Name == "Double") - codeGen.Emit(OpCodes.Ldc_R8, (double) field.GetLiteralValue()); - else if (ftype.Name == "Single") - codeGen.Emit(OpCodes.Ldc_R4, (float) field.GetLiteralValue()); - else if (ftype.Name == "String") - codeGen.Emit(OpCodes.Ldstr, (string) field.GetLiteralValue()); - else - codeGen.Emit(OpCodes.Ldc_I4, - TypeSystemHelpers.ConvertLiteralToInt(field.GetLiteralValue())); - } - - public static XamlXConstantNode GetLiteralFieldConstantNode(IXamlXField field, IXamlXLineInfo info) - => new XamlXConstantNode(info, field.FieldType, GetLiteralFieldConstantValue(field)); + public static XamlConstantNode GetLiteralFieldConstantNode(IXamlField field, IXamlLineInfo info) + => new XamlConstantNode(info, field.FieldType, GetLiteralFieldConstantValue(field)); - public static object GetLiteralFieldConstantValue(IXamlXField field) + public static object GetLiteralFieldConstantValue(IXamlField field) { var value = field.GetLiteralValue(); @@ -61,11 +43,11 @@ public static object GetLiteralFieldConstantValue(IXamlXField field) - public static bool TryGetEnumValueNode(IXamlXType enumType, string value, IXamlXLineInfo lineInfo, out XamlXConstantNode rv) + public static bool TryGetEnumValueNode(IXamlType enumType, string value, IXamlLineInfo lineInfo, out XamlConstantNode rv) { if (TryGetEnumValue(enumType, value, out var constant)) { - rv = new XamlXConstantNode(lineInfo, enumType, constant); + rv = new XamlConstantNode(lineInfo, enumType, constant); return true; } @@ -73,7 +55,7 @@ public static bool TryGetEnumValueNode(IXamlXType enumType, string value, IXamlX return false; } - public static bool TryGetEnumValue(IXamlXType enumType, string value, out object rv) + public static bool TryGetEnumValue(IXamlType enumType, string value, out object rv) { rv = null; if (long.TryParse(value, out var parsedLong)) @@ -126,7 +108,7 @@ static object Or(object l, object r) throw new ArgumentException("Unsupported type " + l.GetType()); } - public static bool ParseConstantIfTypeAllows(string s, IXamlXType type, IXamlXLineInfo info, out XamlXConstantNode rv) + public static bool ParseConstantIfTypeAllows(string s, IXamlType type, IXamlLineInfo info, out XamlConstantNode rv) { rv = null; if (type.Namespace != "System") @@ -162,110 +144,11 @@ object Parse() var r = Parse(); if (r != null) { - rv = new XamlXConstantNode(info, type, r); + rv = new XamlConstantNode(info, type, r); return true; } return false; } - - public static void EmitConvert(XamlXEmitContext context, IXamlXEmitter ilgen, IXamlXLineInfo node, IXamlXType what, - IXamlXType to, IXamlXLocal local) - { - EmitConvert(context, node, what, to, lda => ilgen.Emit(lda ? OpCodes.Ldloca : OpCodes.Ldloc, local)); - } - - public static void EmitConvert(XamlXEmitContext context, IXamlXEmitter ilgen, IXamlXLineInfo node, - IXamlXType what, - IXamlXType to) - { - XamlXLocalsPool.PooledLocal local = null; - - EmitConvert(context, node, what, to, lda => - { - if (!lda) - return ilgen; - local = ilgen.LocalsPool.GetLocal(what); - ilgen - .Stloc(local.Local) - .Ldloca(local.Local); - return ilgen; - }); - local?.Dispose(); - } - - public static void EmitConvert(XamlXEmitContext context, IXamlXLineInfo node, IXamlXType what, - IXamlXType to, Func ld) - { - if (what.Equals(to)) - ld(false); - else if (what == XamlXPseudoType.Null) - { - - if (to.IsValueType) - { - if (to.GenericTypeDefinition?.Equals(context.Configuration.WellKnownTypes.NullableT) == true) - { - using (var loc = context.GetLocal(to)) - ld(false) - .Pop() - .Ldloca(loc.Local) - .Emit(OpCodes.Initobj, to) - .Ldloc(loc.Local); - - } - else - throw new XamlXLoadException("Unable to convert {x:Null} to " + to.GetFqn(), node); - } - else - ld(false); - } - else if (what.IsValueType && to.IsValueType) - { - if (to.IsNullableOf(what)) - { - ld(false).Emit(OpCodes.Newobj, - to.Constructors.First(c => - c.Parameters.Count == 1 && c.Parameters[0].Equals(what))); - } - else if (what.IsNullableOf(what)) - ld(true) - .EmitCall(what.FindMethod(m => m.Name == "get_Value")); - else - throw new XamlXLoadException( - $"Don't know how to convert value type {what.GetFullName()} to value type {to.GetFullName()}", - node); - } - else if (!to.IsValueType && what.IsValueType) - { - if (!to.IsAssignableFrom(what)) - throw new XamlXLoadException( - $"Don't know how to convert value type {what.GetFullName()} to reference type {to.GetFullName()}", - node); - ld(false).Box(what); - } - else if(to.IsValueType && !what.IsValueType) - { - if (!(what.Namespace == "System" && what.Name == "Object")) - throw new XamlXLoadException( - $"Don't know how to convert reference type {what.GetFullName()} to value type {to.GetFullName()}", - node); - ld(false).Unbox_Any(to); - } - else - { - if (to.IsAssignableFrom(what)) - // Downcast, always safe - ld(false); - else if (what.IsInterface || what.IsAssignableFrom(to)) - // Upcast or cast from interface, might throw InvalidCastException - ld(false).Emit(OpCodes.Castclass, to); - else - // Types are completely unrelated, e. g. string to List conversion attempt - throw new XamlXLoadException( - $"Don't know how to convert reference type {what.GetFullName()} to reference type {to.GetFullName()}", - node); - } - } } } diff --git a/src/XamlX/TypeSystem/XamlXLocalsPool.cs b/src/XamlX/TypeSystem/XamlLocalsPool.cs similarity index 55% rename from src/XamlX/TypeSystem/XamlXLocalsPool.cs rename to src/XamlX/TypeSystem/XamlLocalsPool.cs index 765b5714..986499f8 100644 --- a/src/XamlX/TypeSystem/XamlXLocalsPool.cs +++ b/src/XamlX/TypeSystem/XamlLocalsPool.cs @@ -3,22 +3,23 @@ namespace XamlX.TypeSystem { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif - class XamlXLocalsPool + class XamlLocalsPool { - private readonly IXamlXEmitter _emitter; + private readonly Func _localFactory; + + private readonly List<(IXamlType type, IXamlLocal local)> _localsPool = + new List<(IXamlType, IXamlLocal)>(); - private readonly List<(IXamlXType type, IXamlXLocal local)> _localsPool = - new List<(IXamlXType, IXamlXLocal)>(); public sealed class PooledLocal : IDisposable { - public IXamlXLocal Local { get; private set; } - private readonly XamlXLocalsPool _parent; - private readonly IXamlXType _type; + public IXamlLocal Local { get; private set; } + private readonly XamlLocalsPool _parent; + private readonly IXamlType _type; - public PooledLocal( XamlXLocalsPool parent, IXamlXType type, IXamlXLocal local) + public PooledLocal(XamlLocalsPool parent, IXamlType type, IXamlLocal local) { Local = local; _parent = parent; @@ -34,12 +35,12 @@ public void Dispose() } } - public XamlXLocalsPool(IXamlXEmitter emitter) + public XamlLocalsPool(Func localFactory) { - _emitter = emitter; + _localFactory = localFactory; } - public PooledLocal GetLocal(IXamlXType type) + public PooledLocal GetLocal(IXamlType type) { for (var c = 0; c < _localsPool.Count; c++) { @@ -51,7 +52,7 @@ public PooledLocal GetLocal(IXamlXType type) } } - return new PooledLocal(this, type, _emitter.DefineLocal(type)); + return new PooledLocal(this, type, _localFactory(type)); } } diff --git a/src/XamlX/XamlNamespaces.cs b/src/XamlX/XamlNamespaces.cs index 621a82d6..21975be9 100644 --- a/src/XamlX/XamlNamespaces.cs +++ b/src/XamlX/XamlNamespaces.cs @@ -1,6 +1,6 @@ namespace XamlX { -#if !XAMLIL_INTERNAL +#if !XAMLX_INTERNAL public #endif class XamlNamespaces diff --git a/src/XamlX/XamlX.csproj b/src/XamlX/XamlX.csproj index cbf435e6..4f680176 100644 --- a/src/XamlX/XamlX.csproj +++ b/src/XamlX/XamlX.csproj @@ -1,4 +1,4 @@ - + netstandard2.0 diff --git a/tests/CecilNetstandardTests/CecilNetstandardTests.csproj b/tests/CecilNetstandardTests/CecilNetstandardTests.csproj index 69c3c17f..e3686a67 100644 --- a/tests/CecilNetstandardTests/CecilNetstandardTests.csproj +++ b/tests/CecilNetstandardTests/CecilNetstandardTests.csproj @@ -1,4 +1,4 @@ - + netcoreapp2.1;net47;netstandard2.0 @@ -9,6 +9,6 @@ - + diff --git a/tests/CecilNetstandardTests/packages.config b/tests/CecilNetstandardTests/packages.config deleted file mode 100644 index f527c92a..00000000 --- a/tests/CecilNetstandardTests/packages.config +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/tests/CecilTests/CecilTests.csproj b/tests/CecilTests/CecilTests.csproj index f1ead63b..6b139a55 100644 --- a/tests/CecilTests/CecilTests.csproj +++ b/tests/CecilTests/CecilTests.csproj @@ -1,4 +1,4 @@ - + netcoreapp2.1;net47;netstandard2.0 @@ -8,6 +8,6 @@ - + diff --git a/tests/CecilTests/CompilerTestBase.cs b/tests/CecilTests/CompilerTestBase.cs index 6ba7c1fa..be3769ed 100644 --- a/tests/CecilTests/CompilerTestBase.cs +++ b/tests/CecilTests/CompilerTestBase.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Reflection; using Mono.Cecil; +using XamlX.Emit; using XamlX.Transform; using XamlX.TypeSystem; using TypeAttributes = Mono.Cecil.TypeAttributes; @@ -44,7 +45,7 @@ public CompilerTestBase() : this(CreateCecilTypeSystem()) asm.MainModule.TypeSystem.Object); asm.MainModule.Types.Add(ct); var ctb = ((CecilTypeSystem)_typeSystem).CreateTypeBuilder(ct); - var contextTypeDef = XamlXContextDefinition.GenerateContextClass(ctb, _typeSystem, Configuration.TypeMappings); + var contextTypeDef = XamlX.IL.XamlILContextDefinition.GenerateContextClass(ctb, _typeSystem, Configuration.TypeMappings, new XamlLanguageEmitMappings()); asm.MainModule.Types.Add(def); diff --git a/tests/TestClasses/Class1.cs b/tests/TestClasses/Class1.cs index 0f9d64d3..bd14c4f0 100644 --- a/tests/TestClasses/Class1.cs +++ b/tests/TestClasses/Class1.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace XamlParserTests { diff --git a/tests/Tests.Common.props b/tests/Tests.Common.props index 2a3f8776..44daf7d6 100644 --- a/tests/Tests.Common.props +++ b/tests/Tests.Common.props @@ -1,4 +1,4 @@ - + true false diff --git a/tests/XamlParserTests/CompilerTestBase.cs b/tests/XamlParserTests/CompilerTestBase.cs index 93d4c12a..d264dfc5 100644 --- a/tests/XamlParserTests/CompilerTestBase.cs +++ b/tests/XamlParserTests/CompilerTestBase.cs @@ -8,20 +8,22 @@ using XamlX.Parsers; using XamlX.Transform; using XamlX.TypeSystem; +using XamlX.IL; +using XamlX.Emit; namespace XamlParserTests { public partial class CompilerTestBase { - private readonly IXamlXTypeSystem _typeSystem; - public XamlXTransformerConfiguration Configuration { get; } + private readonly IXamlTypeSystem _typeSystem; + public TransformerConfiguration Configuration { get; } - private CompilerTestBase(IXamlXTypeSystem typeSystem) + private CompilerTestBase(IXamlTypeSystem typeSystem) { _typeSystem = typeSystem; - Configuration = new XamlXTransformerConfiguration(typeSystem, + Configuration = new TransformerConfiguration(typeSystem, typeSystem.FindAssembly("XamlParserTests"), - new XamlXLanguageTypeMappings(typeSystem) + new XamlLanguageTypeMappings(typeSystem) { XmlnsAttributes = { @@ -43,8 +45,8 @@ private CompilerTestBase(IXamlXTypeSystem typeSystem) RootObjectProvider = typeSystem.GetType("XamlParserTests.ITestRootObjectProvider"), UriContextProvider = typeSystem.GetType("XamlParserTests.ITestUriContext"), ProvideValueTarget = typeSystem.GetType("XamlParserTests.ITestProvideValueTarget"), - ParentStackProvider = typeSystem.GetType("XamlX.Runtime.IXamlXParentStackProviderV1"), - XmlNamespaceInfoProvider = typeSystem.GetType("XamlX.Runtime.IXamlXXmlNamespaceInfoProviderV1") + ParentStackProvider = typeSystem.GetType("XamlX.Runtime.IXamlParentStackProviderV1"), + XmlNamespaceInfoProvider = typeSystem.GetType("XamlX.Runtime.IXamlXmlNamespaceInfoProviderV1") } ); } @@ -53,13 +55,19 @@ private CompilerTestBase(IXamlXTypeSystem typeSystem) protected object CompileAndPopulate(string xaml, IServiceProvider prov = null, object instance = null) => Compile(xaml).create(prov); - XamlXDocument Compile(IXamlXTypeBuilder builder, IXamlXType context, string xaml) + XamlDocument Compile(IXamlTypeBuilder builder, IXamlType context, string xaml) { - var parsed = XDocumentXamlXParser.Parse(xaml); - var compiler = new XamlXCompiler(Configuration, true) { EnableIlVerification = true }; + var parsed = XDocumentXamlParser.Parse(xaml); + var compiler = new XamlILCompiler( + Configuration, + new XamlLanguageEmitMappings(), + true) + { + EnableIlVerification = true + }; compiler.Transform(parsed); compiler.Compile(parsed, builder, context, "Populate", "Build", - "XamlXNamespaceInfo", + "XamlNamespaceInfo", "http://example.com/", null); return parsed; } @@ -86,7 +94,11 @@ public CompilerTestBase() : this(new SreTypeSystem()) var ct = dm.DefineType(t.Name + "Context"); var ctb = ((SreTypeSystem)_typeSystem).CreateTypeBuilder(ct); var contextTypeDef = - XamlXContextDefinition.GenerateContextClass(ctb, _typeSystem, Configuration.TypeMappings); + XamlILContextDefinition.GenerateContextClass( + ctb, + _typeSystem, + Configuration.TypeMappings, + new XamlLanguageEmitMappings()); var parserTypeBuilder = ((SreTypeSystem) _typeSystem).CreateTypeBuilder(t); diff --git a/tests/XamlParserTests/DebugHatch.cs b/tests/XamlParserTests/DebugHatch.cs index 05dae781..deb0b2dd 100644 --- a/tests/XamlParserTests/DebugHatch.cs +++ b/tests/XamlParserTests/DebugHatch.cs @@ -1,6 +1,6 @@ namespace XamlX { - public class XamlXDebugHatch + public class XamlDebugHatch { public static void Debug(string point) { diff --git a/tests/XamlParserTests/Helpers.cs b/tests/XamlParserTests/Helpers.cs index c8ba0e7b..e300bf38 100644 --- a/tests/XamlParserTests/Helpers.cs +++ b/tests/XamlParserTests/Helpers.cs @@ -56,7 +56,7 @@ static void StructDiff(object parsed, object expected, string path, bool isRoot foreach (var prop in parsed.GetType().GetProperties() .Where(p => p.GetMethod != null && p.GetMethod.IsPublic)) { - if (prop.DeclaringType == typeof(XamlXAstNode) + if (prop.DeclaringType == typeof(XamlAstNode) && (prop.Name == "Line" || prop.Name == "Position")) { if(!isRoot && (int)prop.GetValue(parsed) == 0) diff --git a/tests/XamlParserTests/InitializationTests.cs b/tests/XamlParserTests/InitializationTests.cs index fe973c2b..9abe2158 100644 --- a/tests/XamlParserTests/InitializationTests.cs +++ b/tests/XamlParserTests/InitializationTests.cs @@ -134,7 +134,6 @@ public void Initialization_Events_Should_Be_Triggered_For_Supports_Initialize() [Fact] public void UsableDuringInitialization_Should_Revert_Initialization_Order() { - CompileAndRun(@" diff --git a/tests/XamlParserTests/IntrinsicsTests.cs b/tests/XamlParserTests/IntrinsicsTests.cs index 0dfc1f77..b0798a83 100644 --- a/tests/XamlParserTests/IntrinsicsTests.cs +++ b/tests/XamlParserTests/IntrinsicsTests.cs @@ -40,7 +40,7 @@ public void Null_Extension_Should_Be_Operational() [Fact] public void Null_Extension_Should_Cause_Compilation_Error_When_Applied_To_Value_Type() { - Assert.Throws(() => Compile(@" + Assert.Throws(() => Compile(@" ")); diff --git a/tests/XamlParserTests/MarkupExtensionTests.cs b/tests/XamlParserTests/MarkupExtensionTests.cs index 4a3819b8..19f7b8b3 100644 --- a/tests/XamlParserTests/MarkupExtensionTests.cs +++ b/tests/XamlParserTests/MarkupExtensionTests.cs @@ -145,7 +145,7 @@ public void Unknown_Reference_Type_To_Value_Type_Should_Trigger_InvalidCastExcep [Fact] public void Value_Type_To_Reference_Type_Should_Trigger_Compile_Error() { - Assert.Throws(() => Compile(@" + Assert.Throws(() => Compile(@" ")); } @@ -153,7 +153,7 @@ public void Value_Type_To_Reference_Type_Should_Trigger_Compile_Error() [Fact] public void Mismatched_Value_Type_To_Value_Type_Should_Trigger_Compile_Error() { - Assert.Throws(() => Compile(@" + Assert.Throws(() => Compile(@" ")); } diff --git a/tests/XamlParserTests/ParserTests.cs b/tests/XamlParserTests/ParserTests.cs index bfb6055a..4372f10b 100644 --- a/tests/XamlParserTests/ParserTests.cs +++ b/tests/XamlParserTests/ParserTests.cs @@ -12,7 +12,7 @@ namespace XamlParserTests { public class ParserTests { - class NullLineInfo : IXamlXLineInfo + class NullLineInfo : IXamlLineInfo { public int Line { get; set; } = 1; public int Position { get; set; } = 1; @@ -21,7 +21,7 @@ class NullLineInfo : IXamlXLineInfo [Fact] public void Parser_Should_Be_Able_To_Parse_A_Simple_Tree() { - var root = XDocumentXamlXParser.Parse( + var root = XDocumentXamlParser.Parse( @" "); var ni = new NullLineInfo(); - var rootType = new XamlXAstXmlTypeReference(ni, "rootns", "Root"); - var childType = new XamlXAstXmlTypeReference(ni, "rootns", "Child"); - var subChildType = new XamlXAstXmlTypeReference(ni, "rootns", "SubChild"); - var nsSubChildType = new XamlXAstXmlTypeReference(ni, "testns", "SubChild"); - var namespacedType = new XamlXAstXmlTypeReference(ni, "testns", "Namespaced"); - var extensionType = new XamlXAstXmlTypeReference(ni, "rootns", "Extension") + var rootType = new XamlAstXmlTypeReference(ni, "rootns", "Root"); + var childType = new XamlAstXmlTypeReference(ni, "rootns", "Child"); + var subChildType = new XamlAstXmlTypeReference(ni, "rootns", "SubChild"); + var nsSubChildType = new XamlAstXmlTypeReference(ni, "testns", "SubChild"); + var namespacedType = new XamlAstXmlTypeReference(ni, "testns", "Namespaced"); + var extensionType = new XamlAstXmlTypeReference(ni, "rootns", "Extension") { IsMarkupExtension = true }; - var other = new XamlXDocument + var other = new XamlDocument { NamespaceAliases = new Dictionary { @@ -62,122 +62,122 @@ public void Parser_Should_Be_Able_To_Parse_A_Simple_Tree() ["d"] = "directive", ["x"] = "http://schemas.microsoft.com/winfx/2006/xaml" }, - Root = new XamlXAstObjectNode(ni, rootType) + Root = new XamlAstObjectNode(ni, rootType) { Children = { // - new XamlXAstXmlDirective(ni, "directive", "Directive", new[] + new XamlAstXmlDirective(ni, "directive", "Directive", new[] { - new XamlXAstTextNode(ni, "DirectiveValue") + new XamlAstTextNode(ni, "DirectiveValue") }), //d:DirectiveExt='{Extension 123}'> - new XamlXAstXmlDirective(ni, "directive", "DirectiveExt", new[] + new XamlAstXmlDirective(ni, "directive", "DirectiveExt", new[] { - new XamlXAstObjectNode(ni, extensionType) + new XamlAstObjectNode(ni, extensionType) { Arguments = { - new XamlXAstTextNode(ni, "123"), + new XamlAstTextNode(ni, "123"), } } }), // - new XamlXAstObjectNode(ni, nsSubChildType) + new XamlAstObjectNode(ni, nsSubChildType) { Children = { - new XamlXAstXamlPropertyValueNode(ni, new XamlXAstNamePropertyReference(ni, + new XamlAstXamlPropertyValueNode(ni, new XamlAstNamePropertyReference(ni, nsSubChildType, "Prop", nsSubChildType), - new XamlXAstTextNode(ni, "321")), + new XamlAstTextNode(ni, "321")), // Root.AttachedProp='AttachedValue' - new XamlXAstXamlPropertyValueNode(ni, new XamlXAstNamePropertyReference(ni, + new XamlAstXamlPropertyValueNode(ni, new XamlAstNamePropertyReference(ni, rootType, "AttachedProp", nsSubChildType), - new XamlXAstTextNode(ni, "AttachedValue")), + new XamlAstTextNode(ni, "AttachedValue")), } }, //DottedValue - new XamlXAstXamlPropertyValueNode(ni, new XamlXAstNamePropertyReference(ni, + new XamlAstXamlPropertyValueNode(ni, new XamlAstNamePropertyReference(ni, childType, "DottedProp", childType), new[] { - new XamlXAstTextNode(ni, "DottedValue") + new XamlAstTextNode(ni, "DottedValue") }), // AttachedValue - new XamlXAstXamlPropertyValueNode(ni, new XamlXAstNamePropertyReference(ni, + new XamlAstXamlPropertyValueNode(ni, new XamlAstNamePropertyReference(ni, rootType, "AttachedDottedProp", childType), new[] { - new XamlXAstTextNode(ni, "AttachedValue") + new XamlAstTextNode(ni, "AttachedValue") }), // - new XamlXAstXamlPropertyValueNode(ni, new XamlXAstNamePropertyReference(ni, + new XamlAstXamlPropertyValueNode(ni, new XamlAstNamePropertyReference(ni, childType, "NodeListProp", childType), new[] { // - new XamlXAstObjectNode(ni, subChildType), + new XamlAstObjectNode(ni, subChildType), // - new XamlXAstObjectNode(ni, subChildType), + new XamlAstObjectNode(ni, subChildType), }) } }, // - new XamlXAstObjectNode(ni, new XamlXAstXmlTypeReference(ni, "rootns", "GenericType", + new XamlAstObjectNode(ni, new XamlAstXmlTypeReference(ni, "rootns", "GenericType", new[] { childType, - new XamlXAstXmlTypeReference(ni, "testns", "NamespacedGeneric", new[] + new XamlAstXmlTypeReference(ni, "testns", "NamespacedGeneric", new[] { childType, - new XamlXAstXmlTypeReference(ni, "rootns", "GenericType", new[] + new XamlAstXmlTypeReference(ni, "rootns", "GenericType", new[] { childType, namespacedType @@ -194,7 +194,7 @@ public void Parser_Should_Be_Able_To_Parse_A_Simple_Tree() [Theory, InlineData(false), InlineData(true)] public void Parser_Should_Handle_Ignorable_Content(bool map) { - var root = XDocumentXamlXParser.Parse(@" + var root = XDocumentXamlParser.Parse(@" @@ -202,27 +202,27 @@ public void Parser_Should_Handle_Ignorable_Content(bool map) ", map ? new Dictionary() {["test"] = "mapped"} : null); var ni = new NullLineInfo(); - var rootType = new XamlXAstXmlTypeReference(ni, "rootns", "Root"); + var rootType = new XamlAstXmlTypeReference(ni, "rootns", "Root"); if (map) { - Helpers.StructDiff(root.Root, new XamlXAstObjectNode(ni, rootType) + Helpers.StructDiff(root.Root, new XamlAstObjectNode(ni, rootType) { Children = { - new XamlXAstXmlDirective(ni, "mapped", "DataContext", new[] {new XamlXAstTextNode(ni, "123"),}), - new XamlXAstObjectNode(ni, new XamlXAstXmlTypeReference(ni, "mapped", "DesignWidth")) + new XamlAstXmlDirective(ni, "mapped", "DataContext", new[] {new XamlAstTextNode(ni, "123"),}), + new XamlAstObjectNode(ni, new XamlAstXmlTypeReference(ni, "mapped", "DesignWidth")) { Children = { - new XamlXAstTextNode(ni, "test") + new XamlAstTextNode(ni, "test") } } } }); } else - Helpers.StructDiff(root.Root, new XamlXAstObjectNode(ni, rootType) + Helpers.StructDiff(root.Root, new XamlAstObjectNode(ni, rootType) { }); @@ -233,9 +233,9 @@ public void Empty_Extension_With_Space_Should_Be_Parsed() { var ni = new NullLineInfo(); var parsed = XamlMarkupExtensionParser.Parse(ni, "{Binding }", - n => new XamlXAstXmlTypeReference(ni, "", n)); - Helpers.StructDiff(parsed, new XamlXAstObjectNode(new NullLineInfo(), - new XamlXAstXmlTypeReference(ni, "", "Binding") + n => new XamlAstXmlTypeReference(ni, "", n)); + Helpers.StructDiff(parsed, new XamlAstObjectNode(new NullLineInfo(), + new XamlAstXmlTypeReference(ni, "", "Binding") { IsMarkupExtension = true })); diff --git a/tests/XamlParserTests/ServiceProviderTests.cs b/tests/XamlParserTests/ServiceProviderTests.cs index 32213048..4ccd45cd 100644 --- a/tests/XamlParserTests/ServiceProviderTests.cs +++ b/tests/XamlParserTests/ServiceProviderTests.cs @@ -41,14 +41,14 @@ public class ServiceProviderTestsClass public class ServiceProviderTests : CompilerTestBase { - void CompileAndRun(string xaml, CallbackExtensionCallback cb, IXamlXParentStackProviderV1 parentStack) + void CompileAndRun(string xaml, CallbackExtensionCallback cb, IXamlParentStackProviderV1 parentStack) => Compile(xaml).create(new DictionaryServiceProvider { [typeof(CallbackExtensionCallback)] = cb, - [typeof(IXamlXParentStackProviderV1)] = parentStack + [typeof(IXamlParentStackProviderV1)] = parentStack }); - class ListParentsProvider : List, IXamlXParentStackProviderV1 + class ListParentsProvider : List, IXamlParentStackProviderV1 { public IEnumerable Parents => this; } @@ -76,7 +76,7 @@ public void Parent_Stack_Should_Provide_Info_About_Parents(bool importParents) { //Manual unrolling of enumerable, useful for state tracking var stack = new List(); - var parentsEnumerable = sp.GetService().Parents; + var parentsEnumerable = sp.GetService().Parents; using (var parentsEnumerator = parentsEnumerable.GetEnumerator()) { while (parentsEnumerator.MoveNext()) @@ -218,32 +218,32 @@ public void Namespace_Info_Should_Be_Preserved() xmlns:clr2='clr-namespace:Dummy;assembly=XamlParserTests' Property='{Callback}'/>", sp => { - var nsList = sp.GetService().XmlNamespaces; + var nsList = sp.GetService().XmlNamespaces; // Direct calls without struct diff because of EntryPointNotFoundException issue before Assert.True(nsList.TryGetValue("clr1", out var xlst)); Assert.Equal("System.Collections.Generic", xlst[0].ClrNamespace); Helpers.StructDiff(nsList, - new Dictionary> + new Dictionary> { - [""] = new List + [""] = new List { - new XamlXXmlNamespaceInfoV1 + new XamlXmlNamespaceInfoV1 { ClrNamespace = "XamlParserTests", ClrAssemblyName = typeof(ServiceProviderTests).Assembly.GetName().Name } }, - ["clr1"] = new List + ["clr1"] = new List { - new XamlXXmlNamespaceInfoV1 + new XamlXmlNamespaceInfoV1 { ClrNamespace = "System.Collections.Generic", ClrAssemblyName = "netstandard" } }, - ["clr2"] = new List + ["clr2"] = new List { - new XamlXXmlNamespaceInfoV1 + new XamlXmlNamespaceInfoV1 { ClrNamespace = "Dummy", ClrAssemblyName = "XamlParserTests" diff --git a/tests/XamlParserTests/XamlParserTests.csproj b/tests/XamlParserTests/XamlParserTests.csproj index 0fd0747a..05566d0e 100644 --- a/tests/XamlParserTests/XamlParserTests.csproj +++ b/tests/XamlParserTests/XamlParserTests.csproj @@ -1,6 +1,6 @@ - + - netcoreapp2.1;net47;netstandard2.0 + netcoreapp2.1;net47