diff --git a/AspNetCore.sln b/AspNetCore.sln
index 1954cda59cd9..e27f44a76e56 100644
--- a/AspNetCore.sln
+++ b/AspNetCore.sln
@@ -1547,6 +1547,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Signal
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "testassets", "testassets", "{BB3D6EDD-AE71-4D25-B61B-7EBF7A1BA1D1}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RazorSourceGenerators", "src\Razor\SourceGenerator\src\RazorSourceGenerators.csproj", "{1822B2E7-2B15-44DA-BD6C-CF3DF66F3E36}"
+EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Analyzer.Testing", "src\Analyzers\Microsoft.AspNetCore.Analyzer.Testing\src\Microsoft.AspNetCore.Analyzer.Testing.csproj", "{399EF81E-C3B5-4D86-8BF1-DC7926252A63}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Caching", "Caching", "{0F39820F-F4A5-41C6-9809-D79B68F032EF}"
@@ -7447,6 +7449,18 @@ Global
{399EF81E-C3B5-4D86-8BF1-DC7926252A63}.Release|x64.Build.0 = Release|Any CPU
{399EF81E-C3B5-4D86-8BF1-DC7926252A63}.Release|x86.ActiveCfg = Release|Any CPU
{399EF81E-C3B5-4D86-8BF1-DC7926252A63}.Release|x86.Build.0 = Release|Any CPU
+ {1822B2E7-2B15-44DA-BD6C-CF3DF66F3E36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1822B2E7-2B15-44DA-BD6C-CF3DF66F3E36}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1822B2E7-2B15-44DA-BD6C-CF3DF66F3E36}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {1822B2E7-2B15-44DA-BD6C-CF3DF66F3E36}.Debug|x64.Build.0 = Debug|Any CPU
+ {1822B2E7-2B15-44DA-BD6C-CF3DF66F3E36}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {1822B2E7-2B15-44DA-BD6C-CF3DF66F3E36}.Debug|x86.Build.0 = Debug|Any CPU
+ {1822B2E7-2B15-44DA-BD6C-CF3DF66F3E36}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1822B2E7-2B15-44DA-BD6C-CF3DF66F3E36}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1822B2E7-2B15-44DA-BD6C-CF3DF66F3E36}.Release|x64.ActiveCfg = Release|Any CPU
+ {1822B2E7-2B15-44DA-BD6C-CF3DF66F3E36}.Release|x64.Build.0 = Release|Any CPU
+ {1822B2E7-2B15-44DA-BD6C-CF3DF66F3E36}.Release|x86.ActiveCfg = Release|Any CPU
+ {1822B2E7-2B15-44DA-BD6C-CF3DF66F3E36}.Release|x86.Build.0 = Release|Any CPU
{4FB95E16-918B-49C1-9F65-49D07CDE072C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4FB95E16-918B-49C1-9F65-49D07CDE072C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4FB95E16-918B-49C1-9F65-49D07CDE072C}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -8305,6 +8319,7 @@ Global
{C1CDD339-B51B-42BE-99F2-F39A4EC0D404} = {BB3D6EDD-AE71-4D25-B61B-7EBF7A1BA1D1}
{BB3D6EDD-AE71-4D25-B61B-7EBF7A1BA1D1} = {1A304CA0-7795-4684-88E5-E66402966927}
{399EF81E-C3B5-4D86-8BF1-DC7926252A63} = {05A169C7-4F20-4516-B10A-B13C5649D346}
+ {1822B2E7-2B15-44DA-BD6C-CF3DF66F3E36} = {DA9E1AB0-0094-4777-BF3F-BC5596C3CDA9}
{0F39820F-F4A5-41C6-9809-D79B68F032EF} = {017429CC-C5FB-48B4-9C46-034E29EE2F06}
{8DFA596B-BD00-404E-9445-BCFAC65BDC34} = {017429CC-C5FB-48B4-9C46-034E29EE2F06}
{4FB95E16-918B-49C1-9F65-49D07CDE072C} = {8DFA596B-BD00-404E-9445-BCFAC65BDC34}
diff --git a/eng/ProjectReferences.props b/eng/ProjectReferences.props
index 5ad1aa1d9ca5..97c2cd8d811c 100644
--- a/eng/ProjectReferences.props
+++ b/eng/ProjectReferences.props
@@ -106,6 +106,7 @@
+
diff --git a/eng/Versions.props b/eng/Versions.props
index 9a94921908b6..16f1f8c96b52 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -191,7 +191,7 @@
- 3.8.0-5.20519.18
+ 3.9.0-2.20521.12
5.0.0-preview.4.20180.4
@@ -220,9 +220,9 @@
15.8.166
1.2.6
15.8.166
- 3.7.0
- 3.7.0
- 3.7.0
+ 3.8.0
+ 3.8.0
+ 3.8.0
3.3.0
3.0.0
1.0.0-20200708.1
diff --git a/eng/Workarounds.targets b/eng/Workarounds.targets
index ce40da6d759a..ed58aca9cd17 100644
--- a/eng/Workarounds.targets
+++ b/eng/Workarounds.targets
@@ -21,13 +21,6 @@
'$(GenerateRazorAssemblyInfo)' == 'true'" />
-
-
-
-
diff --git a/src/Identity/UI/src/Microsoft.AspNetCore.Identity.UI.csproj b/src/Identity/UI/src/Microsoft.AspNetCore.Identity.UI.csproj
index 0512647672c8..ceebc2861397 100644
--- a/src/Identity/UI/src/Microsoft.AspNetCore.Identity.UI.csproj
+++ b/src/Identity/UI/src/Microsoft.AspNetCore.Identity.UI.csproj
@@ -7,11 +7,9 @@
true
aspnetcore;identity;membership;razorpages
Microsoft.AspNetCore.Mvc.ApplicationParts.NullApplicationPartFactory, Microsoft.AspNetCore.Mvc.Core
- false
- false
false
- true
true
+ Microsoft.AspNetCore.Identity.UI.Views.V4
true
true
@@ -21,9 +19,7 @@
_UpdatedIdentityUIStaticWebAssets
- Bootstrap4
$(MSBuildThisFileDirectory)THIRD-PARTY-NOTICES.TXT
-
@@ -47,105 +43,14 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Microsoft.AspNetCore.Identity.UI.Views.$(UIFrameworkVersion)
-
-
-
+
- <_RazorGenerate Include="Areas\Identity\Pages\$(UIFrameworkVersion)\**\*.cshtml" />
+ <_RazorGenerate Include="Areas\Identity\Pages\V4\**\*.cshtml" />
-
-
-
-
-
- <_GeneratedRazorViews Include="$(TargetDir)$(TargetName).Views.%(UIFrameworkVersionMoniker.Identity).dll" />
- <_GeneratedRazorViews Include="$(TargetDir)$(TargetName).Views.%(UIFrameworkVersionMoniker.Identity).pdb" />
-
-
- %(FileName)%(Extension)
- PreserveNewest
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -153,7 +58,7 @@
<_V4Content Include="wwwroot\V4\**" />
-
+
Microsoft.AspNetCore.Identity.UI
$([MSBuild]::NormalizePath('$(MSBuildThisFileDirectory)wwwroot/V4'))
diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTagHelperDescriptorProvider.cs b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTagHelperDescriptorProvider.cs
index d0d9805f6b4b..f9360795e179 100644
--- a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTagHelperDescriptorProvider.cs
+++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/src/ViewComponentTagHelperDescriptorProvider.cs
@@ -1,4 +1,4 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
@@ -38,16 +38,21 @@ public void Execute(TagHelperDescriptorProviderContext context)
var types = new List();
var visitor = new ViewComponentTypeVisitor(vcAttribute, nonVCAttribute, types);
- // We always visit the global namespace.
- visitor.Visit(compilation.Assembly.GlobalNamespace);
+ if ((context.DiscoveryMode & TagHelperDiscoveryMode.CurrentAssembly) == TagHelperDiscoveryMode.CurrentAssembly)
+ {
+ visitor.Visit(compilation.Assembly.GlobalNamespace);
+ }
- foreach (var reference in compilation.References)
+ if ((context.DiscoveryMode & TagHelperDiscoveryMode.References) == TagHelperDiscoveryMode.References)
{
- if (compilation.GetAssemblyOrModuleSymbol(reference) is IAssemblySymbol assembly)
+ foreach (var reference in compilation.References)
{
- if (IsTagHelperAssembly(assembly))
+ if (compilation.GetAssemblyOrModuleSymbol(reference) is IAssemblySymbol assembly)
{
- visitor.Visit(assembly.GlobalNamespace);
+ if (IsTagHelperAssembly(assembly))
+ {
+ visitor.Visit(assembly.GlobalNamespace);
+ }
}
}
}
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/DefaultDocumentWriter.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/DefaultDocumentWriter.cs
index c5fb4de90e25..058112def09c 100644
--- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/DefaultDocumentWriter.cs
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/CodeGeneration/DefaultDocumentWriter.cs
@@ -1,4 +1,4 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
@@ -124,6 +124,18 @@ public override void VisitDocument(DocumentIntermediateNode node)
.WriteLine("// ")
.WriteLine("#pragma warning disable 1591");
+ if (Context.Options.GenerateDesignerIfDefs)
+ {
+ if (Context.Options.DesignTime)
+ {
+ Context.CodeWriter.WriteLine("#ifdef RAZOR_SOURCEGENERATED_DESIGNTIME");
+ }
+ else
+ {
+ Context.CodeWriter.WriteLine("#ifdef RAZOR_SOURCEGENERATED_RUNTIME");
+ }
+ }
+
VisitDefault(node);
Context.CodeWriter.WriteLine("#pragma warning restore 1591");
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCodeGenerationOptionsBuilder.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCodeGenerationOptionsBuilder.cs
index 1422b410ff41..d57925133f54 100644
--- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCodeGenerationOptionsBuilder.cs
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCodeGenerationOptionsBuilder.cs
@@ -52,7 +52,10 @@ public override RazorCodeGenerationOptions Build()
SuppressMetadataAttributes,
SuppressPrimaryMethodBody,
SuppressNullabilityEnforcement,
- OmitMinimizedComponentAttributeValues);
+ OmitMinimizedComponentAttributeValues)
+ {
+ GenerateDesignerIfDefs = GenerateDesignerIfDefs,
+ };
}
public override void SetDesignTime(bool designTime)
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorDiagnostic.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorDiagnostic.cs
index 40f558df2679..6e1d2be21490 100644
--- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorDiagnostic.cs
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorDiagnostic.cs
@@ -1,4 +1,4 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Properties/AssemblyInfo.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Properties/AssemblyInfo.cs
index feb088c7424d..eb475eb879fa 100644
--- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Properties/AssemblyInfo.cs
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Properties/AssemblyInfo.cs
@@ -5,6 +5,7 @@
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Razor.OmniSharpPlugin.StrongNamed, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Razor.LanguageServer, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("rzc, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
+[assembly: InternalsVisibleTo("RazorSourceGenerators, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Razor.GenerateTool, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Razor.Test.Common, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Razor.LanguageServer.Common, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/PublicAPI.Unshipped.txt b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/PublicAPI.Unshipped.txt
index 7dc5c58110bf..65856dbb1ab4 100644
--- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/PublicAPI.Unshipped.txt
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/PublicAPI.Unshipped.txt
@@ -1 +1,6 @@
-#nullable enable
+Microsoft.AspNetCore.Razor.Language.TagHelperDescriptorProviderContext.DiscoveryMode.get -> Microsoft.AspNetCore.Razor.Language.TagHelperDiscoveryMode
+Microsoft.AspNetCore.Razor.Language.TagHelperDescriptorProviderContext.DiscoveryMode.set -> void
+Microsoft.AspNetCore.Razor.Language.TagHelperDiscoveryMode
+Microsoft.AspNetCore.Razor.Language.TagHelperDiscoveryMode.All = Microsoft.AspNetCore.Razor.Language.TagHelperDiscoveryMode.CurrentAssembly | Microsoft.AspNetCore.Razor.Language.TagHelperDiscoveryMode.References -> Microsoft.AspNetCore.Razor.Language.TagHelperDiscoveryMode
+Microsoft.AspNetCore.Razor.Language.TagHelperDiscoveryMode.CurrentAssembly = 1 -> Microsoft.AspNetCore.Razor.Language.TagHelperDiscoveryMode
+Microsoft.AspNetCore.Razor.Language.TagHelperDiscoveryMode.References = 2 -> Microsoft.AspNetCore.Razor.Language.TagHelperDiscoveryMode
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorCodeGenerationOptions.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorCodeGenerationOptions.cs
index b481dfeb07a6..3323e17912e9 100644
--- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorCodeGenerationOptions.cs
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorCodeGenerationOptions.cs
@@ -121,5 +121,11 @@ public static RazorCodeGenerationOptions CreateDesignTime(Action
public virtual bool OmitMinimizedComponentAttributeValues { get; }
+
+ ///
+ /// Gets or sets a value that determines if special ifdefs are added to the generated code to support
+ /// features such as Edit & Continue in the IDE.
+ ///
+ internal bool GenerateDesignerIfDefs { get; set; }
}
}
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorCodeGenerationOptionsBuilder.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorCodeGenerationOptionsBuilder.cs
index 48d725b6145f..fdec37f0ac78 100644
--- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorCodeGenerationOptionsBuilder.cs
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorCodeGenerationOptionsBuilder.cs
@@ -64,6 +64,11 @@ public abstract class RazorCodeGenerationOptionsBuilder
///
public virtual bool OmitMinimizedComponentAttributeValues { get; set; }
+ ///
+ /// .
+ ///
+ internal bool GenerateDesignerIfDefs { get; set; }
+
public abstract RazorCodeGenerationOptions Build();
public virtual void SetDesignTime(bool designTime)
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorDiagnostic.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorDiagnostic.cs
index a4bd3c2b5e49..a33257cdf501 100644
--- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorDiagnostic.cs
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorDiagnostic.cs
@@ -1,4 +1,4 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorProjectItem.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorProjectItem.cs
index 6c245de89398..e0f0709d7dca 100644
--- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorProjectItem.cs
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorProjectItem.cs
@@ -1,4 +1,4 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Diagnostics;
@@ -130,9 +130,11 @@ public string FilePathWithoutExtension
}
}
+ internal RazorSourceDocument RazorSourceDocument { get; set; }
+
private string DebuggerToString()
{
return CombinedPath;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorSourceDocument.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorSourceDocument.cs
index 31acb7dfd69c..6362f1708f08 100644
--- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorSourceDocument.cs
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorSourceDocument.cs
@@ -1,4 +1,4 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
@@ -193,6 +193,11 @@ public static RazorSourceDocument ReadFrom(RazorProjectItem projectItem)
filePath = projectItem.FilePath;
}
+ if (projectItem.RazorSourceDocument is not null)
+ {
+ return projectItem.RazorSourceDocument;
+ }
+
using (var stream = projectItem.Read())
{
// Autodetect the encoding.
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/TagHelperDescriptorProviderContext.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/TagHelperDescriptorProviderContext.cs
index 4bf792c62da6..814bd04f969c 100644
--- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/TagHelperDescriptorProviderContext.cs
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/TagHelperDescriptorProviderContext.cs
@@ -1,4 +1,4 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
@@ -16,6 +16,8 @@ public abstract class TagHelperDescriptorProviderContext
public abstract ICollection Results { get; }
+ public TagHelperDiscoveryMode DiscoveryMode { get; set; } = TagHelperDiscoveryMode.All;
+
public static TagHelperDescriptorProviderContext Create()
{
return new DefaultContext(new List());
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/TagHelperDiscoveryMode.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/TagHelperDiscoveryMode.cs
new file mode 100644
index 000000000000..0a20a59fb2f6
--- /dev/null
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/TagHelperDiscoveryMode.cs
@@ -0,0 +1,15 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ [Flags]
+ public enum TagHelperDiscoveryMode
+ {
+ CurrentAssembly = 1,
+ References = 2,
+ All = CurrentAssembly | References,
+ }
+}
diff --git a/src/Razor/Microsoft.CodeAnalysis.Razor/src/BindTagHelperDescriptorProvider.cs b/src/Razor/Microsoft.CodeAnalysis.Razor/src/BindTagHelperDescriptorProvider.cs
index 22eeb425b070..4488255e657f 100644
--- a/src/Razor/Microsoft.CodeAnalysis.Razor/src/BindTagHelperDescriptorProvider.cs
+++ b/src/Razor/Microsoft.CodeAnalysis.Razor/src/BindTagHelperDescriptorProvider.cs
@@ -101,6 +101,11 @@ public void Execute(TagHelperDescriptorProviderContext context)
return;
}
+ if ((context.DiscoveryMode & TagHelperDiscoveryMode.References) != TagHelperDiscoveryMode.References)
+ {
+ return;
+ }
+
// Tag Helper defintion for case #1. This is the most general case.
context.Results.Add(CreateFallbackBindTagHelper());
diff --git a/src/Razor/Microsoft.CodeAnalysis.Razor/src/ComponentTagHelperDescriptorProvider.cs b/src/Razor/Microsoft.CodeAnalysis.Razor/src/ComponentTagHelperDescriptorProvider.cs
index 8c7a8ddd2dac..181306d50885 100644
--- a/src/Razor/Microsoft.CodeAnalysis.Razor/src/ComponentTagHelperDescriptorProvider.cs
+++ b/src/Razor/Microsoft.CodeAnalysis.Razor/src/ComponentTagHelperDescriptorProvider.cs
@@ -40,15 +40,21 @@ public void Execute(TagHelperDescriptorProviderContext context)
var types = new List();
var visitor = new ComponentTypeVisitor(symbols, types);
- // Visit the primary output of this compilation, as well as all references.
- visitor.Visit(compilation.Assembly);
- foreach (var reference in compilation.References)
+ if ((context.DiscoveryMode & TagHelperDiscoveryMode.CurrentAssembly) == TagHelperDiscoveryMode.CurrentAssembly)
{
- // We ignore .netmodules here - there really isn't a case where they are used by user code
- // even though the Roslyn APIs all support them.
- if (compilation.GetAssemblyOrModuleSymbol(reference) is IAssemblySymbol assembly)
+ visitor.Visit(compilation.Assembly);
+ }
+
+ if ((context.DiscoveryMode & TagHelperDiscoveryMode.References) == TagHelperDiscoveryMode.References)
+ {
+ foreach (var reference in compilation.References)
{
- visitor.Visit(assembly);
+ // We ignore .netmodules here - there really isn't a case where they are used by user code
+ // even though the Roslyn APIs all support them.
+ if (compilation.GetAssemblyOrModuleSymbol(reference) is IAssemblySymbol assembly)
+ {
+ visitor.Visit(assembly.GlobalNamespace);
+ }
}
}
diff --git a/src/Razor/Microsoft.CodeAnalysis.Razor/src/DefaultTagHelperDescriptorProvider.cs b/src/Razor/Microsoft.CodeAnalysis.Razor/src/DefaultTagHelperDescriptorProvider.cs
index 074ad68527e7..593c79eb873f 100644
--- a/src/Razor/Microsoft.CodeAnalysis.Razor/src/DefaultTagHelperDescriptorProvider.cs
+++ b/src/Razor/Microsoft.CodeAnalysis.Razor/src/DefaultTagHelperDescriptorProvider.cs
@@ -1,4 +1,4 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
@@ -35,16 +35,21 @@ public void Execute(TagHelperDescriptorProviderContext context)
var types = new List();
var visitor = new TagHelperTypeVisitor(iTagHelper, types);
- // We always visit the global namespace.
- visitor.Visit(compilation.Assembly.GlobalNamespace);
+ if ((context.DiscoveryMode & TagHelperDiscoveryMode.CurrentAssembly) == TagHelperDiscoveryMode.CurrentAssembly)
+ {
+ visitor.Visit(compilation.Assembly.GlobalNamespace);
+ }
- foreach (var reference in compilation.References)
+ if ((context.DiscoveryMode & TagHelperDiscoveryMode.References) == TagHelperDiscoveryMode.References)
{
- if (compilation.GetAssemblyOrModuleSymbol(reference) is IAssemblySymbol assembly)
+ foreach (var reference in compilation.References)
{
- if (IsTagHelperAssembly(assembly))
+ if (compilation.GetAssemblyOrModuleSymbol(reference) is IAssemblySymbol assembly)
{
- visitor.Visit(assembly.GlobalNamespace);
+ if (IsTagHelperAssembly(assembly))
+ {
+ visitor.Visit(assembly.GlobalNamespace);
+ }
}
}
}
diff --git a/src/Razor/Microsoft.CodeAnalysis.Razor/src/EventHandlerTagHelperDescriptorProvider.cs b/src/Razor/Microsoft.CodeAnalysis.Razor/src/EventHandlerTagHelperDescriptorProvider.cs
index 25bc587b47c0..5271da7e0d06 100644
--- a/src/Razor/Microsoft.CodeAnalysis.Razor/src/EventHandlerTagHelperDescriptorProvider.cs
+++ b/src/Razor/Microsoft.CodeAnalysis.Razor/src/EventHandlerTagHelperDescriptorProvider.cs
@@ -36,7 +36,7 @@ public void Execute(TagHelperDescriptorProviderContext context)
return;
}
- var eventHandlerData = GetEventHandlerData(compilation);
+ var eventHandlerData = GetEventHandlerData(compilation, context.DiscoveryMode);
foreach (var tagHelper in CreateEventHandlerTagHelpers(eventHandlerData))
{
@@ -44,7 +44,7 @@ public void Execute(TagHelperDescriptorProviderContext context)
}
}
- private List GetEventHandlerData(Compilation compilation)
+ private List GetEventHandlerData(Compilation compilation, TagHelperDiscoveryMode discoveryMode)
{
var eventHandlerAttribute = compilation.GetTypeByMetadataName(ComponentsApi.EventHandlerAttribute.FullTypeName);
if (eventHandlerAttribute == null)
@@ -56,15 +56,21 @@ private List GetEventHandlerData(Compilation compilation)
var types = new List();
var visitor = new EventHandlerDataVisitor(types);
- // Visit the primary output of this compilation, as well as all references.
- visitor.Visit(compilation.Assembly);
- foreach (var reference in compilation.References)
+ if ((discoveryMode & TagHelperDiscoveryMode.CurrentAssembly) == TagHelperDiscoveryMode.CurrentAssembly)
{
- // We ignore .netmodules here - there really isn't a case where they are used by user code
- // even though the Roslyn APIs all support them.
- if (compilation.GetAssemblyOrModuleSymbol(reference) is IAssemblySymbol assembly)
+ visitor.Visit(compilation.Assembly.GlobalNamespace);
+ }
+
+ if ((discoveryMode & TagHelperDiscoveryMode.References) == TagHelperDiscoveryMode.References)
+ {
+ foreach (var reference in compilation.References)
{
- visitor.Visit(assembly);
+ // We ignore .netmodules here - there really isn't a case where they are used by user code
+ // even though the Roslyn APIs all support them.
+ if (compilation.GetAssemblyOrModuleSymbol(reference) is IAssemblySymbol assembly)
+ {
+ visitor.Visit(assembly.GlobalNamespace);
+ }
}
}
diff --git a/src/Razor/Microsoft.CodeAnalysis.Razor/src/KeyTagHelperDescriptorProvider.cs b/src/Razor/Microsoft.CodeAnalysis.Razor/src/KeyTagHelperDescriptorProvider.cs
index 789abca3183a..8d6c15c785a9 100644
--- a/src/Razor/Microsoft.CodeAnalysis.Razor/src/KeyTagHelperDescriptorProvider.cs
+++ b/src/Razor/Microsoft.CodeAnalysis.Razor/src/KeyTagHelperDescriptorProvider.cs
@@ -27,6 +27,11 @@ public void Execute(TagHelperDescriptorProviderContext context)
return;
}
+ if ((context.DiscoveryMode & TagHelperDiscoveryMode.References) != TagHelperDiscoveryMode.References)
+ {
+ return;
+ }
+
var renderTreeBuilderType = compilation.GetTypeByMetadataName(ComponentsApi.RenderTreeBuilder.FullTypeName);
if (renderTreeBuilderType == null)
{
diff --git a/src/Razor/Microsoft.CodeAnalysis.Razor/src/Properties/AssemblyInfo.cs b/src/Razor/Microsoft.CodeAnalysis.Razor/src/Properties/AssemblyInfo.cs
index c83b18dbc584..0f7b58646633 100644
--- a/src/Razor/Microsoft.CodeAnalysis.Razor/src/Properties/AssemblyInfo.cs
+++ b/src/Razor/Microsoft.CodeAnalysis.Razor/src/Properties/AssemblyInfo.cs
@@ -5,6 +5,7 @@
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Razor.OmniSharpPlugin.StrongNamed, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Razor.LanguageServer, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("rzc, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
+[assembly: InternalsVisibleTo("RazorSourceGenerators, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Mvc.Razor.Extensions.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Razor.Test.Common, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Razor.LanguageServer.Common, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
diff --git a/src/Razor/Microsoft.CodeAnalysis.Razor/src/RefTagHelperDescriptorProvider.cs b/src/Razor/Microsoft.CodeAnalysis.Razor/src/RefTagHelperDescriptorProvider.cs
index 1eafca4181e8..4068cfdd41e7 100644
--- a/src/Razor/Microsoft.CodeAnalysis.Razor/src/RefTagHelperDescriptorProvider.cs
+++ b/src/Razor/Microsoft.CodeAnalysis.Razor/src/RefTagHelperDescriptorProvider.cs
@@ -27,6 +27,11 @@ public void Execute(TagHelperDescriptorProviderContext context)
return;
}
+ if ((context.DiscoveryMode & TagHelperDiscoveryMode.References) != TagHelperDiscoveryMode.References)
+ {
+ return;
+ }
+
var elementReference = compilation.GetTypeByMetadataName(ComponentsApi.ElementReference.FullTypeName);
if (elementReference == null)
{
diff --git a/src/Razor/Microsoft.CodeAnalysis.Razor/src/SplatTagHelperDescriptorProvider.cs b/src/Razor/Microsoft.CodeAnalysis.Razor/src/SplatTagHelperDescriptorProvider.cs
index 3d6421442726..7e3656b36dc0 100644
--- a/src/Razor/Microsoft.CodeAnalysis.Razor/src/SplatTagHelperDescriptorProvider.cs
+++ b/src/Razor/Microsoft.CodeAnalysis.Razor/src/SplatTagHelperDescriptorProvider.cs
@@ -27,6 +27,11 @@ public void Execute(TagHelperDescriptorProviderContext context)
return;
}
+ if ((context.DiscoveryMode & TagHelperDiscoveryMode.References) != TagHelperDiscoveryMode.References)
+ {
+ return;
+ }
+
var renderTreeBuilder = compilation.GetTypeByMetadataName(ComponentsApi.RenderTreeBuilder.FullTypeName);
if (renderTreeBuilder == null)
{
diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/integrationtests/BuildIncrementalismTest.cs b/src/Razor/Microsoft.NET.Sdk.Razor/integrationtests/BuildIncrementalismTest.cs
index 700c19038513..4345be90f203 100644
--- a/src/Razor/Microsoft.NET.Sdk.Razor/integrationtests/BuildIncrementalismTest.cs
+++ b/src/Razor/Microsoft.NET.Sdk.Razor/integrationtests/BuildIncrementalismTest.cs
@@ -66,35 +66,7 @@ public async Task BuildIncremental_SimpleMvc_PersistsTargetInputFile()
}
}
- [Fact]
- [InitializeTestProject("SimpleMvc")]
- public async Task RazorGenerate_RegeneratesTagHelperInputs_IfFileChanges()
- {
- // Act - 1
- var expectedTagHelperCacheContent = @"""Name"":""SimpleMvc.SimpleTagHelper""";
- var result = await DotnetMSBuild("Build");
- var file = Path.Combine(Project.DirectoryPath, "SimpleTagHelper.cs");
- var tagHelperOutputCache = Path.Combine(IntermediateOutputPath, "SimpleMvc.TagHelpers.output.cache");
- var generatedFile = Path.Combine(RazorIntermediateOutputPath, "Views", "Home", "Index.cshtml.g.cs");
-
- // Assert - 1
- Assert.BuildPassed(result);
- Assert.FileContains(result, tagHelperOutputCache, expectedTagHelperCacheContent);
- var fileThumbPrint = GetThumbPrint(generatedFile);
-
- // Act - 2
- // Update the source content and build. We should expect the outputs to be regenerated.
- ReplaceContent(string.Empty, file);
- result = await DotnetMSBuild("Build");
-
- // Assert - 2
- Assert.BuildPassed(result);
- Assert.FileDoesNotContain(result, tagHelperOutputCache, @"""Name"":""SimpleMvc.SimpleTagHelper""");
- var newThumbPrint = GetThumbPrint(generatedFile);
- Assert.NotEqual(fileThumbPrint, newThumbPrint);
- }
-
- [Fact]
+ [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/28780")]
[InitializeTestProject("SimpleMvc")]
public async Task Build_ErrorInGeneratedCode_ReportsMSBuildError_OnIncrementalBuild()
{
@@ -171,7 +143,7 @@ async Task VerifyError()
}
}
- [Fact]
+ [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/28780")]
[InitializeTestProject("MvcWithComponents")]
public async Task BuildComponents_DoesNotRegenerateComponentDefinition_WhenDefinitionIsUnchanged()
{
@@ -220,118 +192,6 @@ public async Task BuildComponents_DoesNotRegenerateComponentDefinition_WhenDefin
Assert.Equal(definitionThumbprint, GetThumbPrint(tagHelperOutputCache));
}
- [Fact]
- [InitializeTestProject("MvcWithComponents")]
- public async Task BuildComponents_RegeneratesComponentDefinition_WhenFilesChange()
- {
- // Act - 1
- var updatedContent = "@code { [Parameter] public string AParameter { get; set; } }";
- var tagHelperOutputCache = Path.Combine(IntermediateOutputPath, "MvcWithComponents.TagHelpers.output.cache");
-
- var generatedFile = Path.Combine(RazorIntermediateOutputPath, "Views", "Shared", "NavMenu.razor.g.cs");
- var generatedDefinitionFile = Path.Combine(RazorComponentIntermediateOutputPath, "Views", "Shared", "NavMenu.razor.g.cs");
-
- // Assert - 1
- var result = await DotnetMSBuild("Build");
-
- Assert.BuildPassed(result);
- var outputFile = Path.Combine(OutputPath, "MvcWithComponents.dll");
- Assert.FileExists(result, OutputPath, "MvcWithComponents.dll");
- var outputAssemblyThumbprint = GetThumbPrint(outputFile);
-
- Assert.FileExists(result, generatedDefinitionFile);
- var generatedDefinitionThumbprint = GetThumbPrint(generatedDefinitionFile);
- Assert.FileExists(result, generatedFile);
- var generatedFileThumbprint = GetThumbPrint(generatedFile);
-
- Assert.FileExists(result, tagHelperOutputCache);
- Assert.FileContains(
- result,
- tagHelperOutputCache,
- @"""Name"":""MvcWithComponents.Views.Shared.NavMenu""");
-
- var definitionThumbprint = GetThumbPrint(tagHelperOutputCache);
-
- // Act - 2
- ReplaceContent(updatedContent, "Views", "Shared", "NavMenu.razor");
- result = await DotnetMSBuild("Build");
-
- // Assert - 2
- Assert.FileExists(result, OutputPath, "MvcWithComponents.dll");
- Assert.NotEqual(outputAssemblyThumbprint, GetThumbPrint(outputFile));
-
- Assert.FileExists(result, generatedDefinitionFile);
- Assert.NotEqual(generatedDefinitionThumbprint, GetThumbPrint(generatedDefinitionFile));
- Assert.FileExists(result, generatedFile);
- Assert.NotEqual(generatedFileThumbprint, GetThumbPrint(generatedFile));
-
- Assert.FileExists(result, tagHelperOutputCache);
- Assert.FileContains(
- result,
- tagHelperOutputCache,
- @"""Name"":""MvcWithComponents.Views.Shared.NavMenu""");
-
- Assert.FileContains(
- result,
- tagHelperOutputCache,
- "AParameter");
-
- Assert.NotEqual(definitionThumbprint, GetThumbPrint(tagHelperOutputCache));
- }
-
- [Fact]
- [InitializeTestProject("MvcWithComponents")]
- public async Task BuildComponents_DoesNotModifyFiles_IfFilesDoNotChange()
- {
- // Act - 1
- var tagHelperOutputCache = Path.Combine(IntermediateOutputPath, "MvcWithComponents.TagHelpers.output.cache");
-
- var file = Path.Combine(Project.DirectoryPath, "Views", "Shared", "NavMenu.razor.g.cs");
- var generatedFile = Path.Combine(RazorIntermediateOutputPath, "Views", "Shared", "NavMenu.razor.g.cs");
- var generatedDefinitionFile = Path.Combine(RazorComponentIntermediateOutputPath, "Views", "Shared", "NavMenu.razor.g.cs");
-
- // Assert - 1
- var result = await DotnetMSBuild("Build");
-
- Assert.BuildPassed(result);
- var outputFile = Path.Combine(OutputPath, "MvcWithComponents.dll");
- Assert.FileExists(result, OutputPath, "MvcWithComponents.dll");
- var outputAssemblyThumbprint = GetThumbPrint(outputFile);
-
- Assert.FileExists(result, generatedDefinitionFile);
- var generatedDefinitionThumbprint = GetThumbPrint(generatedDefinitionFile);
- Assert.FileExists(result, generatedFile);
- var generatedFileThumbprint = GetThumbPrint(generatedFile);
-
- Assert.FileExists(result, tagHelperOutputCache);
- Assert.FileContains(
- result,
- tagHelperOutputCache,
- @"""Name"":""MvcWithComponents.Views.Shared.NavMenu""");
-
- var definitionThumbprint = GetThumbPrint(tagHelperOutputCache);
-
- // Act - 2
- result = await DotnetMSBuild("Build");
-
- // Assert - 2
- Assert.FileExists(result, OutputPath, "MvcWithComponents.dll");
- Assert.Equal(outputAssemblyThumbprint, GetThumbPrint(outputFile));
-
- Assert.FileExists(result, generatedDefinitionFile);
- Assert.Equal(generatedDefinitionThumbprint, GetThumbPrint(generatedDefinitionFile));
- Assert.FileExists(result, generatedFile);
- Assert.Equal(generatedFileThumbprint, GetThumbPrint(generatedFile));
-
- Assert.FileExists(result, tagHelperOutputCache);
- Assert.FileContains(
- result,
- tagHelperOutputCache,
- @"""Name"":""MvcWithComponents.Views.Shared.NavMenu""");
-
- Assert.Equal(definitionThumbprint, GetThumbPrint(tagHelperOutputCache));
- }
-
[Fact]
[InitializeTestProject("AppWithP2PReference", additionalProjects: "ClassLibrary")]
public async Task IncrementalBuild_WithP2P_WorksWhenBuildProjectReferencesIsDisabled()
@@ -369,7 +229,7 @@ public async Task IncrementalBuild_WithP2P_WorksWhenBuildProjectReferencesIsDisa
Assert.FileExists(result, OutputPath, "ClassLibrary.Views.pdb");
}
- [Fact]
+ [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/28780")]
[InitializeTestProject("ClassLibrary")]
public async Task Build_TouchesUpToDateMarkerFile()
{
diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/integrationtests/BuildIntegrationTest.cs b/src/Razor/Microsoft.NET.Sdk.Razor/integrationtests/BuildIntegrationTest.cs
index 7f7e829b06f3..04102d7f2e4f 100644
--- a/src/Razor/Microsoft.NET.Sdk.Razor/integrationtests/BuildIntegrationTest.cs
+++ b/src/Razor/Microsoft.NET.Sdk.Razor/integrationtests/BuildIntegrationTest.cs
@@ -4,6 +4,7 @@
using System;
using System.IO;
using System.Linq;
+using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Testing;
@@ -35,7 +36,7 @@ private async Task Build_SimpleMvc_WithoutBuildServer_CanBuildSuccessfully(MSBui
{
var result = await DotnetMSBuild("Build",
"/p:UseRazorBuildServer=false",
- suppressBuildServer: true,
+ suppressTestSpecificBuildServer: true,
msBuildProcessKind: msBuildProcessKind);
Assert.BuildPassed(result);
@@ -217,7 +218,7 @@ public async Task Build_WithP2P_CopiesRazorAssembly()
Assert.FileExists(result, OutputPath, "ClassLibrary.Views.pdb");
}
- [Fact]
+ [Fact(Skip = "Blocked until https://github.com/dotnet/roslyn/issues/50090 is resolved.")]
[InitializeTestProject("SimplePages", additionalProjects: "LinkedDir")]
public async Task Build_SetsUpEmbeddedResourcesWithLogicalName()
{
@@ -478,25 +479,6 @@ public async Task Build_GeneratesHostingAttributes_WhenGenerateRazorHostingAssem
Assert.FileDoesNotContain(result, razorAssemblyInfo, "Microsoft.AspNetCore.Razor.Hosting.RazorConfigurationNameAttribute");
}
- [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/13303")]
- [InitializeTestProject("SimpleMvcFSharp", language: "F#")]
- public async Task Build_SimpleMvcFSharp_NoopsWithoutFailing()
- {
- var result = await DotnetMSBuild("Build");
-
- Assert.BuildPassed(result);
-
- Assert.FileExists(result, OutputPath, "SimpleMvcFSharp.dll");
- Assert.FileExists(result, OutputPath, "SimpleMvcFSharp.pdb");
- Assert.FileExists(result, IntermediateOutputPath, "SimpleMvcFSharp.dll");
- Assert.FileExists(result, IntermediateOutputPath, "SimpleMvcFSharp.pdb");
-
- Assert.FileDoesNotExist(result, OutputPath, "SimpleMvcFSharp.Views.dll");
- Assert.FileDoesNotExist(result, OutputPath, "SimpleMvcFSharp.Views.pdb");
- Assert.FileDoesNotExist(result, IntermediateOutputPath, "SimpleMvcFSharp.RazorAssemblyInfo.cs");
- Assert.FileDoesNotExist(result, IntermediateOutputPath, "SimpleMvcFSharp.RazorAssemblyInfo.fs");
- }
-
[Fact]
[InitializeTestProject("SimpleMvc")]
public async Task Build_WithGenerateRazorAssemblyInfo_False_DoesNotGenerateAssemblyInfo()
@@ -568,6 +550,7 @@ public async Task Build_WithP2P_WorksWhenBuildProjectReferencesIsDisabled()
[InitializeTestProject("AppWithP2PReference", additionalProjects: new[] { "ClassLibrary", "ClassLibraryMvc21" })]
public async Task Build_WithP2P_Referencing21Project_Works()
{
+
// Verifies building with different versions of Razor.Tasks works. Loosely modeled after the repro
// scenario listed in https://github.com/Microsoft/msbuild/issues/3572
var additionalProjectContent = @"
@@ -577,7 +560,7 @@ public async Task Build_WithP2P_Referencing21Project_Works()
";
AddProjectFileContent(additionalProjectContent);
- var result = await DotnetMSBuild(target: default);
+ var result = await DotnetMSBuild(target: default, suppressTestSpecificBuildServer: true);
Assert.BuildPassed(result);
@@ -628,21 +611,18 @@ public async Task Build_WithDeterministicFlagSet_OutputsDeterministicViewsAssemb
[Fact]
[InitializeTestProject("SimpleMvc")]
- public async Task Build_WithoutServer_ErrorDuringBuild_DisplaysErrorInMsBuildOutput()
+ public async Task Build_ErrorDuringBuild_DisplaysErrorInMsBuildOutput()
{
var result = await DotnetMSBuild(
"Build",
"/p:UseRazorBuildServer=false /p:RazorLangVersion=99.0",
- suppressBuildServer: true);
+ suppressTestSpecificBuildServer: true);
Assert.BuildFailed(result);
- Assert.BuildOutputContainsLine(
+ Assert.BuildError(
result,
- $"Invalid option 99.0 for Razor language version --version; must be Latest or a valid version in range 1.0 to 5.0.");
-
- // Compilation failed without creating the views assembly
- Assert.FileExists(result, IntermediateOutputPath, "SimpleMvc.dll");
- Assert.FileDoesNotExist(result, IntermediateOutputPath, "SimpleMvc.Views.dll");
+ "RZ3600",
+ message: "Invalid value 99.0 for RazorLangVersion. Valid values include 'Latest' or a valid version in range 1.0 to 5.0.");
}
[Fact]
@@ -652,7 +632,7 @@ public async Task Build_ImplicitCSharp8_NullableEnforcement_WarningsDuringBuild_
var result = await DotnetMSBuild(
"Build",
"/p:Nullable=enable",
- suppressBuildServer: true);
+ suppressTestSpecificBuildServer: true);
var indexFilePath = Path.Combine(RazorIntermediateOutputPath, "Views", "Home", "Index.cshtml.g.cs");
Assert.BuildPassed(result, allowWarnings: true);
@@ -668,7 +648,7 @@ public async Task Build_ExplicitCSharp73_NullableEnforcement_Disabled_NoNullable
var result = await DotnetMSBuild(
"Build",
"/p:LangVersion=7.3",
- suppressBuildServer: true);
+ suppressTestSpecificBuildServer: true);
var indexFilePath = Path.Combine(RazorIntermediateOutputPath, "Views", "Home", "Index.cshtml.g.cs");
Assert.BuildPassed(result, allowWarnings: false);
@@ -698,7 +678,7 @@ public async Task Build_CSharp8_NullableEnforcement_WarningsDuringBuild_NoBuildS
var result = await DotnetMSBuild(
"Build",
"/p:LangVersion=8.0 /p:Nullable=enable",
- suppressBuildServer: true);
+ suppressTestSpecificBuildServer: true);
var indexFilePath = Path.Combine(RazorIntermediateOutputPath, "Views", "Home", "Index.cshtml.g.cs");
Assert.BuildPassed(result, allowWarnings: true);
@@ -714,7 +694,7 @@ public async Task Build_Mvc_WithoutAddRazorSupportForMvc()
var result = await DotnetMSBuild(
"Build",
"/p:AddRazorSupportForMvc=false",
- suppressBuildServer: true);
+ suppressTestSpecificBuildServer: true);
Assert.BuildWarning(result, "RAZORSDK1004");
}
@@ -733,6 +713,42 @@ public async Task Build_WithNoResolvedRazorConfiguration()
Assert.BuildWarning(result, "RAZORSDK1000");
}
+ [Fact]
+ [InitializeTestProject("SimpleMvc")]
+ public async Task Build_EmbedRazorGenerateSources_EmbedsCshtmlFiles()
+ {
+ var result = await DotnetMSBuild("Build", "/p:EmbedRazorGenerateSources=true");
+
+ Assert.BuildPassed(result);
+
+ Assert.FileExists(result, IntermediateOutputPath, "SimpleMvc.Views.dll");
+
+ var assembly = LoadAssemblyFromBytes(result.Project.DirectoryPath, IntermediateOutputPath, "SimpleMvc.Views.dll");
+ var resources = assembly.GetManifestResourceNames();
+
+ Assert.Equal(new string[]
+ {
+ "/Views/Home/About.cshtml",
+ "/Views/Home/Contact.cshtml",
+ "/Views/Home/Index.cshtml",
+ "/Views/Shared/Error.cshtml",
+ "/Views/Shared/_Layout.cshtml",
+ "/Views/Shared/_ValidationScriptsPartial.cshtml",
+ "/Views/_ViewImports.cshtml",
+ "/Views/_ViewStart.cshtml",
+ },
+ resources.OrderBy(r => r, StringComparer.Ordinal));
+ }
+
+ private Assembly LoadAssemblyFromBytes(params string[] paths)
+ {
+ // We need to load the assembly from bytes to load it without locking the file - and yes, we need to
+ // load the pdb too, or else the CLR will load/lock it based on the path specified in the assembly.
+ var assemblyBytes = File.ReadAllBytes(Path.Combine(paths));
+ var symbolBytes = File.ReadAllBytes(Path.ChangeExtension(Path.Combine(paths), ".pdb"));
+ return Assembly.Load(assemblyBytes, symbolBytes);
+ }
+
private static DependencyContext ReadDependencyContext(string depsFilePath)
{
var reader = new DependencyContextJsonReader();
diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/integrationtests/BuildIntrospectionTest.cs b/src/Razor/Microsoft.NET.Sdk.Razor/integrationtests/BuildIntrospectionTest.cs
index 041b59a9a5cc..d1e05b93f3fc 100644
--- a/src/Razor/Microsoft.NET.Sdk.Razor/integrationtests/BuildIntrospectionTest.cs
+++ b/src/Razor/Microsoft.NET.Sdk.Razor/integrationtests/BuildIntrospectionTest.cs
@@ -287,5 +287,32 @@ public async Task IntrospectRazorSdkWatchItems()
Assert.BuildOutputContainsLine(result, "Watch: Index.razor");
Assert.BuildOutputContainsLine(result, "Watch: Index.razor.css");
}
+
+ [Fact(Skip = "Blocked until https://github.com/dotnet/roslyn/issues/50090 is resolved.")]
+ [InitializeTestProject("SimpleMvc", additionalProjects: "LinkedDir")]
+ public async Task Build_WorksWithLinkedFiles()
+ {
+ // Arrange
+ var projectContent = @"
+
+
+
+
+
+";
+ AddProjectFileContent(projectContent);
+
+ var result = await DotnetMSBuild("ResolveRazorGenerateInputs", "/t:_IntrospectRazorGenerateWithTargetPath");
+
+ Assert.BuildPassed(result);
+
+ Assert.FileExists(result, RazorIntermediateOutputPath, "LinkedFile.cshtml.g.cs");
+ Assert.FileExists(result, RazorIntermediateOutputPath, "LinkedFileOut", "LinkedFile2.cshtml.g.cs");
+ Assert.FileExists(result, RazorIntermediateOutputPath, "LinkedFileOut", "LinkedFileWithRename.cshtml.g.cs");
+
+ Assert.BuildOutputContainsLine(result, $@"RazorGenerateWithTargetPath: {Path.Combine("..", "LinkedDir", "LinkedFile.cshtml")} LinkedFile.cshtml {Path.Combine(RazorIntermediateOutputPath, "LinkedFile.cshtml.g.cs")}");
+ Assert.BuildOutputContainsLine(result, $@"RazorGenerateWithTargetPath: {Path.Combine("..", "LinkedDir", "LinkedFile2.cshtml")} LinkedFileOut\LinkedFile2.cshtml {Path.Combine(RazorIntermediateOutputPath, "LinkedFileOut", "LinkedFile2.cshtml.g.cs")}");
+ Assert.BuildOutputContainsLine(result, $@"RazorGenerateWithTargetPath: {Path.Combine("..", "LinkedDir", "LinkedFile3.cshtml")} LinkedFileOut\LinkedFileWithRename.cshtml {Path.Combine(RazorIntermediateOutputPath, "LinkedFileOut", "LinkedFileWithRename.cshtml.g.cs")}");
+ }
}
}
diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/integrationtests/BuildPerformanceTest.cs b/src/Razor/Microsoft.NET.Sdk.Razor/integrationtests/BuildPerformanceTest.cs
deleted file mode 100644
index 05b2ab08bbd4..000000000000
--- a/src/Razor/Microsoft.NET.Sdk.Razor/integrationtests/BuildPerformanceTest.cs
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Text.RegularExpressions;
-using System.Threading.Tasks;
-using Xunit;
-
-namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
-{
- public class BuildPerformanceTest : MSBuildIntegrationTestBase, IClassFixture
- {
- public BuildPerformanceTest(BuildServerTestFixture buildServer)
- : base(buildServer)
- {
- }
-
- [Fact]
- [InitializeTestProject("SimpleMvc")]
- public async Task BuildMvcApp()
- {
- var result = await DotnetMSBuild(target: default, args: "/clp:PerformanceSummary");
-
- Assert.BuildPassed(result);
- var summary = ParseTaskPerformanceSummary(result.Output);
-
- Assert.Equal(1, summary.First(f => f.Name == "RazorGenerate").Calls);
- Assert.Equal(1, summary.First(f => f.Name == "RazorTagHelper").Calls);
-
- // Incremental builds
- for (var i = 0; i < 2; i++)
- {
- result = await DotnetMSBuild(target: default, args: "/clp:PerformanceSummary");
-
- Assert.BuildPassed(result);
- summary = ParseTaskPerformanceSummary(result.Output);
-
- Assert.DoesNotContain(summary, item => item.Name == "RazorGenerate");
- Assert.DoesNotContain(summary, item => item.Name == "RazorTagHelper");
- }
- }
-
- [Fact]
- [InitializeTestProject("MvcWithComponents")]
- public async Task BuildMvcAppWithComponents()
- {
- var result = await DotnetMSBuild(target: default, args: "/clp:PerformanceSummary");
-
- Assert.BuildPassed(result);
- var summary = ParseTaskPerformanceSummary(result.Output);
-
- // One for declaration build, one for the "real" code gen
- Assert.Equal(2, summary.First(f => f.Name == "RazorGenerate").Calls);
- Assert.Equal(1, summary.First(f => f.Name == "RazorTagHelper").Calls);
-
- // Incremental builds
- for (var i = 0; i < 2; i++)
- {
- result = await DotnetMSBuild(target: default, args: "/clp:PerformanceSummary");
-
- Assert.BuildPassed(result);
- summary = ParseTaskPerformanceSummary(result.Output);
-
- Assert.DoesNotContain(summary, item => item.Name == "RazorGenerate");
- Assert.DoesNotContain(summary, item => item.Name == "RazorTagHelper");
- }
- }
-
- private List ParseTaskPerformanceSummary(string output)
- {
- const string Header = "Task Performance Summary:";
- var lines = output.Split(Environment.NewLine);
- var taskSection = Array.LastIndexOf(lines, Header);
- Assert.True(taskSection != -1, $"Could not find line ${Header} in {output}");
-
- var entries = new List();
- // 6 ms FindAppConfigFile 4 calls
- var matcher = new Regex(@"\s+(?");
- var result = await DotnetMSBuild(RazorGenerateTarget, "/t:_IntrospectRazorGenerateWithTargetPath");
+ var result = await DotnetMSBuild("Build", "/t:_IntrospectRazorGenerateWithTargetPath");
Assert.BuildPassed(result);
- // RazorGenerate should compile the assembly, but not the views.
- Assert.FileExists(result, IntermediateOutputPath, "SimpleMvc.dll");
- Assert.FileDoesNotExist(result, IntermediateOutputPath, "SimpleMvc.Views.dll");
-
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "_ViewImports.cshtml.g.cs");
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "_ViewStart.cshtml.g.cs");
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "Home", "About.cshtml.g.cs");
diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/integrationtests/ScopedCssIntegrationTests.cs b/src/Razor/Microsoft.NET.Sdk.Razor/integrationtests/ScopedCssIntegrationTests.cs
index a98f599281d3..6ab6d800e39c 100644
--- a/src/Razor/Microsoft.NET.Sdk.Razor/integrationtests/ScopedCssIntegrationTests.cs
+++ b/src/Razor/Microsoft.NET.Sdk.Razor/integrationtests/ScopedCssIntegrationTests.cs
@@ -64,7 +64,7 @@ public async Task CanOverrideScopeIdentifiers()
");
- var result = await DotnetMSBuild("Build", "/p:EnableDefaultScopedCssItems=false");
+ var result = await DotnetMSBuild("Build", "/p:EnableDefaultScopedCssItems=false /p:_RazorSourceGeneratorWriteGeneratedOutput=true");
Assert.BuildPassed(result);
var scoped = Assert.FileExists(result, IntermediateOutputPath, "scopedcss", "Styles", "Pages", "Counter.rz.scp.css");
@@ -169,7 +169,7 @@ public async Task Publish_Publishes_IndividualScopedCssFiles_WhenNoBundlingIsEna
[InitializeTestProject("ComponentApp", language: "C#")]
public async Task Build_GeneratedComponentContainsScope()
{
- var result = await DotnetMSBuild("Build");
+ var result = await DotnetMSBuild("Build", "/p:_RazorSourceGeneratorWriteGeneratedOutput=true");
Assert.BuildPassed(result);
var generatedCounter = Assert.FileExists(result, IntermediateOutputPath, "scopedcss", "Components", "Pages", "Counter.razor.rz.scp.css");
@@ -188,7 +188,7 @@ public async Task Build_GeneratedComponentContainsScope()
[InitializeTestProject("ComponentApp", language: "C#")]
public async Task Build_RemovingScopedCssAndBuilding_UpdatesGeneratedCodeAndBundle()
{
- var result = await DotnetMSBuild("Build");
+ var result = await DotnetMSBuild("Build", "/p:_RazorSourceGeneratorWriteGeneratedOutput=true");
Assert.BuildPassed(result);
Assert.FileExists(result, IntermediateOutputPath, "scopedcss", "Components", "Pages", "Counter.razor.rz.scp.css");
@@ -201,7 +201,7 @@ public async Task Build_RemovingScopedCssAndBuilding_UpdatesGeneratedCodeAndBund
File.Delete(Path.Combine(Project.DirectoryPath, "Components", "Pages", "Counter.razor.css"));
- result = await DotnetMSBuild("Build");
+ result = await DotnetMSBuild("Build", "/p:_RazorSourceGeneratorWriteGeneratedOutput=true");
Assert.BuildPassed(result);
Assert.FileDoesNotExist(result, IntermediateOutputPath, "scopedcss", "Components", "Pages", "Counter.razor.rz.scp.css");
@@ -237,7 +237,7 @@ public async Task Build_ScopedCssTransformation_AndBundling_IsIncremental()
var thumbprintLookup = new Dictionary();
// Act 1
- var result = await DotnetMSBuild("Build");
+ var result = await DotnetMSBuild("Build", "/p:_RazorSourceGeneratorWriteGeneratedOutput=true");
var directoryPath = Path.Combine(result.Project.DirectoryPath, IntermediateOutputPath, "scopedcss");
diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/src/Microsoft.NET.Sdk.Razor.csproj b/src/Razor/Microsoft.NET.Sdk.Razor/src/Microsoft.NET.Sdk.Razor.csproj
index d7ea394a9c6c..d95539f072c2 100644
--- a/src/Razor/Microsoft.NET.Sdk.Razor/src/Microsoft.NET.Sdk.Razor.csproj
+++ b/src/Razor/Microsoft.NET.Sdk.Razor/src/Microsoft.NET.Sdk.Razor.csproj
@@ -1,4 +1,4 @@
-
+
Razor is a markup syntax for adding server-side logic to web pages. This package contains MSBuild support for Razor.
$(DefaultNetCoreTargetFramework);net46
@@ -36,6 +36,11 @@
ReferenceOutputAssembly="false"
SkipGetTargetFrameworkProperties="true"
UndefineProperties="TargetFramework;TargetFrameworks" />
+
+
@@ -72,6 +77,7 @@
+
@@ -79,6 +85,10 @@
Text="rzc outputs were not found in $(ArtifactsBinDir)rzc\$(Configuration)\$(DefaultNetCoreTargetFramework)\publish"
Condition="'@(RazorToolsOutput->Count())' == '0'" />
+
+
@@ -88,6 +98,10 @@
+
+
+
+
diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.CodeGeneration.targets b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.CodeGeneration.targets
index 76c4bba7c972..24461361ace1 100644
--- a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.CodeGeneration.targets
+++ b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.CodeGeneration.targets
@@ -174,12 +174,4 @@ Copyright (c) .NET Foundation. All rights reserved.
$(ResolveRazorCompileInputsDependsOn);_ResolveGeneratedRazorCompileInputs
-
-
-
-
-
-
diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.Compilation.targets b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.Compilation.targets
index c512c7ee49f2..cb3e20b8509e 100644
--- a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.Compilation.targets
+++ b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.Compilation.targets
@@ -66,8 +66,10 @@ Copyright (c) .NET Foundation. All rights reserved.
+
+
+
+
+
true
@@ -156,7 +163,7 @@ Copyright (c) .NET Foundation. All rights reserved.
Prefer32Bit="$(Prefer32Bit)"
PreferredUILang="$(PreferredUILang)"
ProvideCommandLineArgs="$(ProvideCommandLineArgs)"
- References="@(RazorReferencePath)"
+ References="@(ReferencePath);@(IntermediateAssembly)"
ReportAnalyzer="$(ReportAnalyzer)"
Resources="@(_RazorCoreCompileResourceInputs);@(CompiledLicenseFile)"
ResponseFiles="$(CompilerResponseFile)"
diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.DesignTime.targets b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.DesignTime.targets
index 4d8e0b5c4d8e..a5fdd32589ee 100644
--- a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.DesignTime.targets
+++ b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.DesignTime.targets
@@ -89,7 +89,8 @@ Copyright (c) .NET Foundation. All rights reserved.
+ Returns="@(RazorGenerateWithTargetPath)"
+ Condition="'$(_UseRazorSourceGenerator)' != 'true'">
+ DependsOnTargets="$(_RazorGenerateComponentDeclarationDesignTimeDependsOn)"
+ Condition="'$(_UseRazorSourceGenerator)' != 'true'">
diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.SourceGenerators.targets b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.SourceGenerators.targets
new file mode 100644
index 000000000000..606a2f350d0b
--- /dev/null
+++ b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.SourceGenerators.targets
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+ <_RazorSdkSourceGeneratorDirectoryRoot>$(RazorSdkDirectoryRoot)source-generators\
+ <_RazorReferenceAssemblyTagHelpersOutputPath>$([System.IO.Path]::GetFullPath($(IntermediateOutputPath)))RazorTagHelper.refs.out.cache
+
+
+
+
+ <_RazorAnalyzer Include="$(_RazorSdkSourceGeneratorDirectoryRoot)Newtonsoft.Json.dll" />
+ <_RazorAnalyzer Include="$(_RazorSdkSourceGeneratorDirectoryRoot)Microsoft.AspNetCore.Mvc.Razor.Extensions.dll" />
+ <_RazorAnalyzer Include="$(_RazorSdkSourceGeneratorDirectoryRoot)Microsoft.AspNetCore.Razor.Language.dll" />
+ <_RazorAnalyzer Include="$(_RazorSdkSourceGeneratorDirectoryRoot)Microsoft.CodeAnalysis.Razor.dll" />
+ <_RazorAnalyzer Include="$(_RazorSdkSourceGeneratorDirectoryRoot)RazorSourceGenerators.dll" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_RazorAdditionalFile Include="@(RazorComponentWithTargetPath)" />
+
+ <_RazorAdditionalFile Include="@(RazorGenerateWithTargetPath)" Condition="'$(RazorCompileOnBuild)' != 'false'" />
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Sdk.Razor.CurrentVersion.targets b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Sdk.Razor.CurrentVersion.targets
index ed4cd57af019..41c71b1bbd88 100644
--- a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Sdk.Razor.CurrentVersion.targets
+++ b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Sdk.Razor.CurrentVersion.targets
@@ -1,4 +1,4 @@
-
+ <_TargetingNET60OrLater Condition=" '$(TargetFrameworkIdentifier)' == '.NETCoreApp' AND
+ $([MSBuild]::VersionGreaterThanOrEquals('$(TargetFrameworkVersion)', '6.0')) ">true
+
+ <_UseRazorSourceGenerator Condition="'$(_TargetingNET60OrLater)' == 'true'">true
+
@@ -97,9 +105,14 @@ Copyright (c) .NET Foundation. All rights reserved.
ResolveRazorConfiguration;
ResolveRazorGenerateInputs;
AssignRazorGenerateTargetPaths;
+ _ResolveGeneratedRazorCompileInputs;
+ _CheckForIncorrectMvcConfiguration;
+
+
+
+ $(PrepareForRazorGenerateDependsOn);
ResolveAssemblyReferenceRazorGenerateInputs;
_CheckForMissingRazorCompiler;
- _CheckForIncorrectMvcConfiguration;
ResolveTagHelperRazorGenerateInputs
@@ -112,6 +125,10 @@ Copyright (c) .NET Foundation. All rights reserved.
PrepareForRazorGenerate;
+
+
+
+ $(RazorGenerateDependsOn);
_CheckForMissingRazorCompiler;
RazorCoreGenerate
@@ -128,7 +145,6 @@ Copyright (c) .NET Foundation. All rights reserved.
ResolveRazorEmbeddedResources;
- _FixupRazorReferencePathForRazorCompile;
@@ -146,12 +162,12 @@ Copyright (c) .NET Foundation. All rights reserved.
_RazorAddDebugSymbolsProjectOutputGroupOutput
-
+
RazorComponentGenerate;
$(CoreCompileDependsOn)
-
+
RazorGenerateComponentDeclarationDesignTime;
$(CoreCompileDependsOn)
@@ -354,9 +370,11 @@ Copyright (c) .NET Foundation. All rights reserved.
-
+
+
+
-
+
@@ -597,17 +615,6 @@ Copyright (c) .NET Foundation. All rights reserved.
-
-
-
-
-
-
-
-
+ false
+ false
+ false
+
+
+ false
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Razor/SourceGenerator/src/SourceGeneratorProjectItem.cs b/src/Razor/SourceGenerator/src/SourceGeneratorProjectItem.cs
new file mode 100644
index 000000000000..0a73fa227c91
--- /dev/null
+++ b/src/Razor/SourceGenerator/src/SourceGeneratorProjectItem.cs
@@ -0,0 +1,46 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.IO;
+using Microsoft.AspNetCore.Razor.Language;
+
+namespace Microsoft.CodeAnalysis.Razor
+{
+ internal class SourceGeneratorProjectItem : RazorProjectItem
+ {
+ private readonly string _fileKind;
+
+ public SourceGeneratorProjectItem(string basePath, string filePath, string relativePhysicalPath, string fileKind, AdditionalText additionalText, string cssScope)
+ {
+ BasePath = basePath;
+ FilePath = filePath;
+ RelativePhysicalPath = relativePhysicalPath;
+ _fileKind = fileKind;
+ AdditionalText = additionalText;
+ CssScope = cssScope;
+ var text = AdditionalText.GetText();
+ RazorSourceDocument = new SourceTextRazorSourceDocument(AdditionalText.Path, relativePhysicalPath, text);
+ }
+
+ public AdditionalText AdditionalText { get; }
+
+ public override string BasePath { get; }
+
+ public override string FilePath { get; }
+
+ public override bool Exists => true;
+
+ public override string PhysicalPath => AdditionalText.Path;
+
+ public override string RelativePhysicalPath { get; }
+
+ public override string FileKind => _fileKind ?? base.FileKind;
+
+ public override string CssScope { get; }
+
+ public override Stream Read()
+ => throw new NotSupportedException("This API should not be invoked. We should instead be relying on " +
+ "the RazorSourceDocument instead associated with this item instead.");
+ }
+}
diff --git a/src/Razor/SourceGenerator/src/SourceTextRazorSourceDocument.cs b/src/Razor/SourceGenerator/src/SourceTextRazorSourceDocument.cs
new file mode 100644
index 000000000000..c391c5ee3388
--- /dev/null
+++ b/src/Razor/SourceGenerator/src/SourceTextRazorSourceDocument.cs
@@ -0,0 +1,70 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Linq;
+using System.Text;
+using Microsoft.AspNetCore.Razor.Language;
+using Microsoft.CodeAnalysis.Text;
+
+namespace Microsoft.CodeAnalysis.Razor
+{
+ internal class SourceTextRazorSourceDocument : RazorSourceDocument
+ {
+ private readonly SourceText _sourceText;
+
+ public SourceTextRazorSourceDocument(string filePath, string relativePath, SourceText sourceText)
+ {
+ FilePath = filePath;
+ RelativePath = relativePath;
+ _sourceText = sourceText;
+ Lines = new SourceTextSourceLineCollection(filePath, sourceText.Lines);
+ }
+
+ public override char this[int position] => _sourceText[position];
+
+ public override Encoding Encoding => _sourceText.Encoding;
+
+ public override string FilePath { get; }
+
+ public override int Length => _sourceText.Length;
+
+ public override string RelativePath { get; }
+
+ public override RazorSourceLineCollection Lines { get; }
+
+ public override void CopyTo(int sourceIndex, char[] destination, int destinationIndex, int count)
+ {
+ _sourceText.CopyTo(sourceIndex, destination, destinationIndex, count);
+ }
+
+ public override byte[] GetChecksum() => _sourceText.GetChecksum().ToArray();
+
+ public override string GetChecksumAlgorithm() => _sourceText.ChecksumAlgorithm.ToString().ToUpperInvariant();
+
+ private class SourceTextSourceLineCollection : RazorSourceLineCollection
+ {
+ private readonly string _filePath;
+ private readonly TextLineCollection _textLines;
+
+ public SourceTextSourceLineCollection(string filePath, TextLineCollection textLines)
+ {
+ _filePath = filePath;
+ _textLines = textLines;
+ }
+
+ public override int Count => _textLines.Count;
+
+ public override int GetLineLength(int index)
+ {
+ var line = _textLines[index];
+ return line.EndIncludingLineBreak - line.Start;
+ }
+
+ internal override SourceLocation GetLocation(int position)
+ {
+ var line = _textLines.GetLineFromPosition(position);
+ return new SourceLocation(_filePath, position, line.LineNumber, position);
+ }
+ }
+ }
+}
diff --git a/src/Razor/SourceGenerator/src/StaticCompilationTagHelperFeature.cs b/src/Razor/SourceGenerator/src/StaticCompilationTagHelperFeature.cs
new file mode 100644
index 000000000000..f65b6cf226c4
--- /dev/null
+++ b/src/Razor/SourceGenerator/src/StaticCompilationTagHelperFeature.cs
@@ -0,0 +1,55 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.AspNetCore.Razor.Language;
+
+namespace Microsoft.CodeAnalysis.Razor
+{
+ internal sealed class StaticCompilationTagHelperFeature : RazorEngineFeatureBase, ITagHelperFeature
+ {
+ private ITagHelperDescriptorProvider[] _providers;
+
+ public IReadOnlyList GetDescriptors()
+ {
+ if (Compilation is null)
+ {
+ return Array.Empty();
+ }
+
+ var results = new List();
+
+
+ var context = TagHelperDescriptorProviderContext.Create(results);
+ context.SetCompilation(Compilation);
+ context.DiscoveryMode = DiscoveryMode;
+
+ for (var i = 0; i < _providers.Length; i++)
+ {
+ _providers[i].Execute(context);
+ }
+
+ return results;
+ }
+
+ public Compilation Compilation { get; set; }
+
+ public TagHelperDiscoveryMode DiscoveryMode { get; set; }
+
+ protected override void OnInitialized()
+ {
+ _providers = Engine.Features.OfType().OrderBy(f => f.Order).ToArray();
+ }
+
+ internal static bool IsValidCompilation(Compilation compilation)
+ {
+ var @string = compilation.GetSpecialType(SpecialType.System_String);
+
+ // Do some minimal tests to verify the compilation is valid. If symbols for System.String
+ // is missing or errored, the compilation may be missing references.
+ return @string != null && @string.TypeKind != TypeKind.Error;
+ }
+ }
+}
diff --git a/src/Razor/SourceGenerator/src/StaticTagHelperFeature.cs b/src/Razor/SourceGenerator/src/StaticTagHelperFeature.cs
new file mode 100644
index 000000000000..6fc6a52ca057
--- /dev/null
+++ b/src/Razor/SourceGenerator/src/StaticTagHelperFeature.cs
@@ -0,0 +1,17 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+using Microsoft.AspNetCore.Razor.Language;
+
+namespace Microsoft.CodeAnalysis.Razor
+{
+ internal sealed class StaticTagHelperFeature : ITagHelperFeature
+ {
+ public RazorEngine Engine { get; set; }
+
+ public IReadOnlyList TagHelpers { get; set; }
+
+ public IReadOnlyList GetDescriptors() => TagHelpers;
+ }
+}
diff --git a/src/Razor/SourceGenerator/src/TagHelperSerializer.cs b/src/Razor/SourceGenerator/src/TagHelperSerializer.cs
new file mode 100644
index 000000000000..6f3d97dc279e
--- /dev/null
+++ b/src/Razor/SourceGenerator/src/TagHelperSerializer.cs
@@ -0,0 +1,40 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using Microsoft.AspNetCore.Razor.Language;
+using Microsoft.CodeAnalysis.Razor.Serialization;
+using Newtonsoft.Json;
+
+namespace RazorSourceGenerators
+{
+ internal class TagHelperSerializer
+ {
+ private static readonly JsonSerializer Serializer = new JsonSerializer
+ {
+ Converters =
+ {
+ new TagHelperDescriptorJsonConverter(),
+ new RazorDiagnosticJsonConverter(),
+ }
+ };
+
+ public static void Serialize(string manifestFilePath, IReadOnlyList tagHelpers)
+ {
+ using var stream = File.OpenWrite(manifestFilePath);
+ using var writer = new StreamWriter(stream, Encoding.UTF8, bufferSize: 4096, leaveOpen: true);
+
+ Serializer.Serialize(writer, tagHelpers);
+ }
+
+ public static IReadOnlyList Deserialize(string manifestFilePath)
+ {
+ using var stream = File.OpenRead(manifestFilePath);
+ using var reader = new JsonTextReader(new StreamReader(stream));
+
+ return Serializer.Deserialize>(reader);
+ }
+ }
+}
diff --git a/src/Razor/test/testassets/MvcWithComponents/Views/Home/#FileName.cshtml b/src/Razor/test/testassets/MvcWithComponents/Views/Home/$FileName.cshtml
similarity index 100%
rename from src/Razor/test/testassets/MvcWithComponents/Views/Home/#FileName.cshtml
rename to src/Razor/test/testassets/MvcWithComponents/Views/Home/$FileName.cshtml
diff --git a/src/Shared/MSBuild.Testing/Assert.cs b/src/Shared/MSBuild.Testing/Assert.cs
index 8262db43dd72..ff5e3b9b39c9 100644
--- a/src/Shared/MSBuild.Testing/Assert.cs
+++ b/src/Shared/MSBuild.Testing/Assert.cs
@@ -20,8 +20,8 @@ internal class Assert : Xunit.Assert
{
// Matches `{filename}: error {code}: {message} [{project}]
// See https://stackoverflow.com/questions/3441452/msbuild-and-ignorestandarderrorwarningformat/5180353#5180353
- private static readonly Regex ErrorRegex = new Regex(@"^(?'location'.+): error (?'errorcode'[A-Z0-9]+): (?'message'.+) \[(?'project'.+)\]$");
- private static readonly Regex WarningRegex = new Regex(@"^(?'location'.+): warning (?'errorcode'[A-Z0-9]+): (?'message'.+) \[(?'project'.+)\]$");
+ private static readonly Regex ErrorRegex = new Regex(@"^((?'location'.+): )?error (?'errorcode'[A-Z0-9]+): (?'message'.+) \[(?'project'.+)\]$");
+ private static readonly Regex WarningRegex = new Regex(@"^((?'location'.+): )?warning (?'errorcode'[A-Z0-9]+): (?'message'.+) \[(?'project'.+)\]$");
private static readonly string[] AllowedBuildWarnings = new[]
{
"MSB3491" , // The process cannot access the file. As long as the build succeeds, we're ok.
@@ -50,7 +50,7 @@ public static void BuildPassed(MSBuildResult result, bool allowWarnings = false)
}
}
- public static void BuildError(MSBuildResult result, string errorCode, string location = null)
+ public static void BuildError(MSBuildResult result, string errorCode, string location = null, string message = null)
{
if (result == null)
{
@@ -75,6 +75,11 @@ public static void BuildError(MSBuildResult result, string errorCode, string loc
continue;
}
+ if (message != null && match.Groups["message"].Value.Trim() != message)
+ {
+ continue;
+ }
+
// This is a match
return;
}
@@ -516,7 +521,11 @@ public static void AssemblyContainsType(MSBuildResult result, string assemblyPat
assemblyPath = Path.Combine(result.Project.DirectoryPath, Path.Combine(assemblyPath));
var typeNames = GetDeclaredTypeNames(assemblyPath);
- Assert.Contains(fullTypeName, typeNames);
+
+ if (!typeNames.Contains(fullTypeName, StringComparer.Ordinal))
+ {
+ throw new MSBuildXunitException(result, $"{fullTypeName} was not found in {string.Join(", ", typeNames)}");
+ }
}
public static void AssemblyDoesNotContainType(MSBuildResult result, string assemblyPath, string fullTypeName)