Skip to content

Commit

Permalink
Merge pull request #736 from burningice2866/features/735
Browse files Browse the repository at this point in the history
Change hardcoded usage of Microsoft.CSharp.CSharpProvider to instantiate it using CodeDomProvider.CreateProvider
  • Loading branch information
napernik authored Sep 30, 2020
2 parents 189613f + b7b9eef commit 8668c64
Show file tree
Hide file tree
Showing 12 changed files with 315 additions and 421 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ private void saveTypeCodeActivity_Save_ExecuteCode(object sender, EventArgs e)
helper.SetLocalizedControlled(hasLocalization);
}

helper.SetCachable(hasCaching);
helper.SetCacheable(hasCaching);
helper.SetNewTypeFullName(typeName, typeNamespace);
helper.SetNewTypeTitle(typeTitle);
helper.SetNewFieldDescriptors(dataFieldDescriptors, null, labelFieldName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ private void codeActivity1_ExecuteCode(object sender, EventArgs e)

if (helper.IsEditProcessControlledAllowed)
{
helper.SetCachable(hasCaching);
helper.SetCacheable(hasCaching);
helper.SetPublishControlled(hasPublishing);
helper.SetLocalizedControlled(hasLocalization);
helper.SetSearchable(isSearchable);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ private void initializeStateCodeActivity_Initialize_ExecuteCode(object sender, E
{"TypeNamespace", dataTypeDescriptor.Namespace},
{"TypeTitle", dataTypeDescriptor.Title},
{"LabelFieldName", dataTypeDescriptor.LabelFieldName},
{"HasCaching", helper.IsCachable},
{"HasCaching", helper.IsCacheable},
{"HasPublishing", helper.IsPublishControlled},
{"DataFieldDescriptors", fieldDescriptors},
{"OldTypeName", dataTypeDescriptor.Name},
Expand Down Expand Up @@ -135,7 +135,7 @@ private void saveTypeCodeActivity_Save_ExecuteCode(object sender, EventArgs e)
helper.SetNewTypeTitle(typeTitle);
// TODO: fix
helper.SetNewFieldDescriptors(dataFieldDescriptors, null, labelFieldName);
helper.SetCachable(hasCaching);
helper.SetCacheable(hasCaching);

if (helper.IsEditProcessControlledAllowed)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ private void initialStateCodeActivity_ExecuteCode(object sender, EventArgs e)
{BindingNames.KeyFieldName, dataTypeDescriptor.KeyPropertyNames.Single() },
{BindingNames.LabelFieldName, dataTypeDescriptor.LabelFieldName},
{BindingNames.InternalUrlPrefix, dataTypeDescriptor.InternalUrlPrefix},
{BindingNames.HasCaching, helper.IsCachable},
{BindingNames.HasCaching, helper.IsCacheable},
{BindingNames.HasPublishing, helper.IsPublishControlled},
{BindingNames.IsSearchable, helper.IsSearchable},
{BindingNames.DataFieldDescriptors, fieldDescriptors},
Expand Down Expand Up @@ -164,7 +164,7 @@ private void finalizeStateCodeActivity_ExecuteCode(object sender, EventArgs e)

if (helper.IsEditProcessControlledAllowed)
{
helper.SetCachable(hasCaching);
helper.SetCacheable(hasCaching);
helper.SetSearchable(isSearchable);
helper.SetPublishControlled(hasPublishing);
helper.SetLocalizedControlled(hasLocalization);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ private void finalizeCodeActivity_Finalize_ExecuteCode(object sender, EventArgs
DataFacade.AddNew(reference);
}

function.SetFunctinoCode(code);
function.SetFunctionCode(code);

function = DataFacade.AddNew(function);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ private void saveCodeActivity_Save_ExecuteCode(object sender, EventArgs e)
ManagedParameterManager.Save(function.Id, parameters);

DataFacade.Update(function);
InlineFunctionHelper.SetFunctinoCode(function, code);
function.SetFunctionCode(code);

transactionScope.Complete();
}
Expand Down
1 change: 1 addition & 0 deletions Composite/Composite.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@
<Compile Include="AspNet\CmsPageHttpHandler.cs" />
<Compile Include="Core\Serialization\CompositeJsonSerializer.cs" />
<Compile Include="Core\Serialization\CompositeSerializationBinder.cs" />
<Compile Include="Core\Types\CSharpCodeProviderFactory.cs" />
<Compile Include="Core\WebClient\PageStructureRpc.cs" />
<Compile Include="Core\WebClient\Renderings\Page\PagePreviewContext.cs" />
<Compile Include="Core\WebClient\Renderings\Page\IPageContentFilter.cs" />
Expand Down
13 changes: 13 additions & 0 deletions Composite/Core/Types/CSharpCodeProviderFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System.CodeDom.Compiler;
using Microsoft.CSharp;

namespace Composite.Core.Types
{
internal class CSharpCodeProviderFactory
{
public static CSharpCodeProvider CreateCompiler()
{
return (CSharpCodeProvider)CodeDomProvider.CreateProvider("c#");
}
}
}
76 changes: 44 additions & 32 deletions Composite/Core/Types/CodeCompatibilityChecker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
using Composite.Data;
using Composite.Data.DynamicTypes;
using Composite.Data.GeneratedTypes;
using Microsoft.CSharp;


namespace Composite.Core.Types
{
Expand All @@ -30,23 +28,19 @@ internal static class CodeCompatibilityChecker
/// <returns></returns>
public static CompatibilityCheckResult CheckCompatibilityWithAppCodeFolder(DataTypeDescriptor dataTypeDescriptorToTest)
{
return CheckAgainsAppCode(dataTypeDescriptorToTest, true);
return CheckAgainstAppCode(dataTypeDescriptorToTest, true);
}



/// <summary>
/// This method will check if any code in en App_Code folder depends on the given data interface.
/// </summary>
/// <param name="dataTypeDescriptorToTest"></param>
/// <returns></returns>
public static CompatibilityCheckResult CheckIfAppCodeDependsOnInterface(DataTypeDescriptor dataTypeDescriptorToTest)
{
return CheckAgainsAppCode(dataTypeDescriptorToTest, false);
return CheckAgainstAppCode(dataTypeDescriptorToTest, false);
}



/// <summary>
/// This method checks to see if any change in the given data type descriptor will make code
/// in App_Code fail and hence the site will fail.
Expand All @@ -60,44 +54,57 @@ public static CompatibilityCheckResult CheckIfAppCodeDependsOnInterface(DataType
[SuppressMessage("Composite.IO", "Composite.DotNotUseStreamWriterClass:DotNotUseStreamWriterClass", Justification = "File api is used for creating temporary files")]
[SuppressMessage("Composite.IO", "Composite.DoNotUseFileStreamClass:DoNotUseFileStreamClass", Justification = "File api is used for creating temporary files")]
[SuppressMessage("Composite.IO", "Composite.DoNotUseFileClass:DoNotUseFileClass", Justification = "File api is used for creating temporary files")]
private static CompatibilityCheckResult CheckAgainsAppCode(DataTypeDescriptor dataTypeDescriptorToTest, bool includeDataTypeDescriptor)
private static CompatibilityCheckResult CheckAgainstAppCode(DataTypeDescriptor dataTypeDescriptorToTest, bool includeDataTypeDescriptor)
{
List<string> filesToCompile = GetAppCodeFiles().ToList();

if (filesToCompile.Count == 0) return new CompatibilityCheckResult();
var filesToCompile = GetAppCodeFiles().ToList();
if (filesToCompile.Count == 0)
{
return new CompatibilityCheckResult();
}

var csCompiler = new CSharpCodeProvider();
var csCompiler = CSharpCodeProviderFactory.CreateCompiler();

List<Assembly> referencedAssemblies = new List<Assembly>();
var referencedAssemblies = new List<Assembly>();
var codeTypeDeclarations = new Dictionary<string, List<CodeTypeDeclaration>>();

foreach (var dataTypeDescriptor in DataMetaDataFacade.GeneratedTypeDataTypeDescriptors)
{
if (!includeDataTypeDescriptor && dataTypeDescriptor.DataTypeId == dataTypeDescriptorToTest.DataTypeId) continue;
if (!includeDataTypeDescriptor && dataTypeDescriptor.DataTypeId == dataTypeDescriptorToTest.DataTypeId)
{
continue;
}

DataTypeDescriptor dataTypeDescriptorToUse = dataTypeDescriptor;
if (includeDataTypeDescriptor && dataTypeDescriptor.DataTypeId == dataTypeDescriptorToTest.DataTypeId) dataTypeDescriptorToUse = dataTypeDescriptorToTest;
var dataTypeDescriptorToUse = dataTypeDescriptor;

if (includeDataTypeDescriptor && dataTypeDescriptor.DataTypeId == dataTypeDescriptorToTest.DataTypeId)
{
dataTypeDescriptorToUse = dataTypeDescriptorToTest;
}

referencedAssemblies.AddRange(InterfaceCodeGenerator.GetReferencedAssemblies(dataTypeDescriptorToUse));
CodeTypeDeclaration codeTypeDeclaration = InterfaceCodeGenerator.CreateCodeTypeDeclaration(dataTypeDescriptorToUse);

List<CodeTypeDeclaration> declarations;
if (!codeTypeDeclarations.TryGetValue(dataTypeDescriptorToUse.Namespace, out declarations))
var codeTypeDeclaration = InterfaceCodeGenerator.CreateCodeTypeDeclaration(dataTypeDescriptorToUse);
if (!codeTypeDeclarations.TryGetValue(dataTypeDescriptorToUse.Namespace, out var declarations))
{
declarations = new List<CodeTypeDeclaration>();

codeTypeDeclarations.Add(dataTypeDescriptorToUse.Namespace, declarations);
}

declarations.Add(codeTypeDeclaration);

string tempFilePath = GetTempFileName(dataTypeDescriptorToUse);
var tempFilePath = GetTempFileName(dataTypeDescriptorToUse);

filesToCompile.Add(tempFilePath);

using (FileStream file = File.Create(tempFilePath))
using (var file = File.Create(tempFilePath))
{
using (var sw = new StreamWriter(file))
{
var codeNamespace = new CodeNamespace(dataTypeDescriptorToUse.Namespace);

codeNamespace.Types.Add(codeTypeDeclaration);

csCompiler.GenerateCodeFromNamespace(codeNamespace, sw, new CodeGeneratorOptions());
}

Expand All @@ -111,7 +118,6 @@ private static CompatibilityCheckResult CheckAgainsAppCode(DataTypeDescriptor da

filesToCompile.Sort();


var compilerParameters = new CompilerParameters
{
GenerateExecutable = false,
Expand All @@ -120,24 +126,28 @@ private static CompatibilityCheckResult CheckAgainsAppCode(DataTypeDescriptor da

compilerParameters.ReferencedAssemblies.AddRangeIfNotContained(referencedAssemblies.Select(f => f.Location).ToArray());
compilerParameters.ReferencedAssemblies.AddRangeIfNotContained(CodeGenerationManager.CompiledAssemblies.Select(f => f.Location).ToArray());

compilerParameters.AddLoadedAssemblies(false);
compilerParameters.AddAssemblyLocationsFromBin();
compilerParameters.AddCommonAssemblies();
compilerParameters.RemoveGeneratedAssemblies();


var codeCompileUnit = new CodeCompileUnit();
foreach (var kvp in codeTypeDeclarations)
{
var codeNamespace = new CodeNamespace(kvp.Key);

codeNamespace.Types.AddRange(kvp.Value.ToArray());
codeCompileUnit.Namespaces.Add(codeNamespace);
}

var compiler = new CSharpCodeProvider();
var compiler = CSharpCodeProviderFactory.CreateCompiler();
var compileResult = compiler.CompileAssemblyFromFile(compilerParameters, filesToCompile.ToArray());

if (compileResult.Errors.Count == 0) return new CompatibilityCheckResult();
if (!compileResult.Errors.HasErrors)
{
return new CompatibilityCheckResult();
}

// Checking for a missing assembly error, if it is present, that means that App_Code check isn't applicable due to circular reference
foreach (CompilerError error in compileResult.Errors)
Expand All @@ -154,9 +164,9 @@ private static CompatibilityCheckResult CheckAgainsAppCode(DataTypeDescriptor da

private static string GetTempFileName(DataTypeDescriptor typeDescriptor)
{
string folderPath = PathUtil.Resolve(GlobalSettingsFacade.GeneratedAssembliesDirectory);
var folderPath = PathUtil.Resolve(GlobalSettingsFacade.GeneratedAssembliesDirectory);

string filePath = Path.Combine(folderPath, typeDescriptor.GetFullInterfaceName() + ".cs");
var filePath = Path.Combine(folderPath, typeDescriptor.GetFullInterfaceName() + ".cs");
if (filePath.Length > 255)
{
filePath = Path.Combine(folderPath, typeDescriptor.DataTypeId + ".cs");
Expand All @@ -166,11 +176,13 @@ private static string GetTempFileName(DataTypeDescriptor typeDescriptor)
}

[SuppressMessage("Composite.IO", "Composite.DoNotUseDirectoryClass:DoNotUseDirectoryClass")]
private static string[] GetAppCodeFiles()
private static IEnumerable<string> GetAppCodeFiles()
{
string appCodeFolderPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, GlobalSettingsFacade.AppCodeDirectory);

if (!Directory.Exists(appCodeFolderPath)) return new string[0];
var appCodeFolderPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, GlobalSettingsFacade.AppCodeDirectory);
if (!Directory.Exists(appCodeFolderPath))
{
return new string[0];
}

return Directory.GetFiles(appCodeFolderPath, "*.cs", SearchOption.AllDirectories);
}
Expand Down
Loading

0 comments on commit 8668c64

Please sign in to comment.