|
namespace System.Workflow.ComponentModel.Compiler
{
#region Imports
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.CodeDom;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.CodeDom.Compiler;
using System.Reflection;
using System.ComponentModel.Design.Serialization;
using System.Xml;
using System.Globalization;
using System.IO;
using System.Text;
using System.Diagnostics;
using System.Text.RegularExpressions;
using Microsoft.CSharp;
using Microsoft.VisualBasic;
using System.Workflow.ComponentModel.Design;
using System.Workflow.ComponentModel.Serialization;
using System.Security.Policy;
using System.Runtime.Versioning;
using System.Configuration;
using System.Collections.ObjectModel;
#endregion
#region WorkflowMarkupSourceAttribute Class
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
[Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")]
public sealed class WorkflowMarkupSourceAttribute : Attribute
{
private string fileName;
private string md5Digest;
public WorkflowMarkupSourceAttribute(string fileName, string md5Digest)
{
this.fileName = fileName;
this.md5Digest = md5Digest;
}
public string FileName
{
get
{
return this.fileName;
}
}
public string MD5Digest
{
get
{
return this.md5Digest;
}
}
}
#endregion
#region Interface IWorkflowCompilerOptionsService
[Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")]
public interface IWorkflowCompilerOptionsService
{
string RootNamespace { get; }
string Language { get; }
bool CheckTypes { get; }
}
[Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")]
public class WorkflowCompilerOptionsService : IWorkflowCompilerOptionsService
{
internal const string DefaultLanguage = "CSharp";
public virtual string RootNamespace
{
get
{
return string.Empty;
}
}
public virtual string Language
{
get
{
return WorkflowCompilerOptionsService.DefaultLanguage;
}
}
public virtual bool CheckTypes
{
get
{
return false;
}
}
public virtual string TargetFrameworkMoniker
{
get
{
return string.Empty;
}
}
}
#endregion
#region WorkflowCompilationContext
[Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")]
public sealed class WorkflowCompilationContext
{
[ThreadStatic]
static WorkflowCompilationContext current = null;
ContextScope scope;
ReadOnlyCollection<AuthorizedType> authorizedTypes;
WorkflowCompilationContext(ContextScope scope)
{
this.scope = scope;
}
public static WorkflowCompilationContext Current
{
get
{
return WorkflowCompilationContext.current;
}
private set
{
WorkflowCompilationContext.current = value;
}
}
public string RootNamespace
{
get
{
return this.scope.RootNamespace;
}
}
public string Language
{
get
{
return this.scope.Language;
}
}
public bool CheckTypes
{
get
{
return this.scope.CheckTypes;
}
}
internal FrameworkName TargetFramework
{
get
{
return this.scope.TargetFramework;
}
}
internal Version TargetFrameworkVersion
{
get
{
FrameworkName fx = this.scope.TargetFramework;
if (fx != null)
{
return fx.Version;
}
else
{
return MultiTargetingInfo.DefaultTargetFramework;
}
}
}
internal IServiceProvider ServiceProvider
{
get
{
return this.scope;
}
}
public static IDisposable CreateScope(IServiceProvider serviceProvider)
{
if (serviceProvider == null)
{
throw new ArgumentNullException("serviceProvider");
}
IWorkflowCompilerOptionsService optionsService = serviceProvider.GetService(typeof(IWorkflowCompilerOptionsService)) as IWorkflowCompilerOptionsService;
if (optionsService != null)
{
return CreateScope(serviceProvider, optionsService);
}
else
{
return new DefaultContextScope(serviceProvider);
}
}
public IList<AuthorizedType> GetAuthorizedTypes()
{
if (this.authorizedTypes == null)
{
try
{
IList<AuthorizedType> authorizedTypes;
IDictionary<string, IList<AuthorizedType>> authorizedTypesDictionary =
ConfigurationManager.GetSection("System.Workflow.ComponentModel.WorkflowCompiler/authorizedTypes") as IDictionary<string, IList<AuthorizedType>>;
Version targetVersion = null;
FrameworkName framework = this.scope.TargetFramework;
if (framework != null)
{
targetVersion = framework.Version;
}
else
{
targetVersion = MultiTargetingInfo.DefaultTargetFramework;
}
string normalizedVersionString = string.Format(CultureInfo.InvariantCulture, "v{0}.{1}", targetVersion.Major, targetVersion.Minor);
if (authorizedTypesDictionary.TryGetValue(normalizedVersionString, out authorizedTypes))
{
this.authorizedTypes = new ReadOnlyCollection<AuthorizedType>(authorizedTypes);
}
}
catch
{
}
}
return this.authorizedTypes;
}
internal static IDisposable CreateScope(IServiceProvider serviceProvider, WorkflowCompilerParameters parameters)
{
return new ParametersContextScope(serviceProvider, parameters);
}
static IDisposable CreateScope(IServiceProvider serviceProvider, IWorkflowCompilerOptionsService optionsService)
{
WorkflowCompilerOptionsService standardService = optionsService as WorkflowCompilerOptionsService;
if (standardService != null)
{
return new StandardContextScope(serviceProvider, standardService);
}
else
{
return new InterfaceContextScope(serviceProvider, optionsService);
}
}
abstract class ContextScope : IDisposable, IServiceProvider
{
IServiceProvider serviceProvider;
WorkflowCompilationContext currentContext;
bool disposed;
protected ContextScope(IServiceProvider serviceProvider)
{
this.serviceProvider = serviceProvider;
this.currentContext = WorkflowCompilationContext.Current;
WorkflowCompilationContext.Current = new WorkflowCompilationContext(this);
}
~ContextScope()
{
DisposeImpl();
}
public abstract string RootNamespace { get; }
public abstract string Language { get; }
public abstract bool CheckTypes { get; }
public abstract FrameworkName TargetFramework { get; }
public void Dispose()
{
DisposeImpl();
GC.SuppressFinalize(this);
}
public object GetService(Type serviceType)
{
return this.serviceProvider.GetService(serviceType);
}
void DisposeImpl()
{
if (!this.disposed)
{
WorkflowCompilationContext.Current = this.currentContext;
this.disposed = true;
}
}
}
class InterfaceContextScope : ContextScope
{
IWorkflowCompilerOptionsService service;
public InterfaceContextScope(IServiceProvider serviceProvider, IWorkflowCompilerOptionsService service)
: base(serviceProvider)
{
this.service = service;
}
public override string RootNamespace
{
get
{
return this.service.RootNamespace;
}
}
public override string Language
{
get
{
return this.service.Language;
}
}
public override bool CheckTypes
{
get
{
return this.service.CheckTypes;
}
}
public override FrameworkName TargetFramework
{
get
{
return null;
}
}
}
class StandardContextScope : ContextScope
{
WorkflowCompilerOptionsService service;
FrameworkName fxName;
public StandardContextScope(IServiceProvider serviceProvider, WorkflowCompilerOptionsService service)
: base(serviceProvider)
{
this.service = service;
}
public override string RootNamespace
{
get
{
return this.service.RootNamespace;
}
}
public override string Language
{
get
{
return this.service.Language;
}
}
public override bool CheckTypes
{
get
{
return this.service.CheckTypes;
}
}
public override FrameworkName TargetFramework
{
get
{
if (this.fxName == null)
{
string fxName = this.service.TargetFrameworkMoniker;
if (!string.IsNullOrEmpty(fxName))
{
this.fxName = new FrameworkName(fxName);
}
}
return this.fxName;
}
}
}
class ParametersContextScope : ContextScope
{
WorkflowCompilerParameters parameters;
public ParametersContextScope(IServiceProvider serviceProvider, WorkflowCompilerParameters parameters)
: base(serviceProvider)
{
this.parameters = parameters;
}
public override string RootNamespace
{
get
{
return WorkflowCompilerParameters.ExtractRootNamespace(this.parameters);
}
}
public override string Language
{
get
{
return this.parameters.LanguageToUse;
}
}
public override bool CheckTypes
{
get
{
return this.parameters.CheckTypes;
}
}
public override FrameworkName TargetFramework
{
get
{
if (this.parameters.MultiTargetingInformation != null)
{
return this.parameters.MultiTargetingInformation.TargetFramework;
}
else
{
return null;
}
}
}
}
class DefaultContextScope : ContextScope
{
public DefaultContextScope(IServiceProvider serviceProvider)
: base(serviceProvider)
{
}
public override string RootNamespace
{
get
{
return string.Empty;
}
}
public override string Language
{
get
{
return WorkflowCompilerOptionsService.DefaultLanguage;
}
}
public override bool CheckTypes
{
get
{
return false;
}
}
public override FrameworkName TargetFramework
{
get
{
return null;
}
}
}
}
#endregion
#region Class WorkflowCompiler
[Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")]
public sealed class WorkflowCompiler
{
public WorkflowCompilerResults Compile(WorkflowCompilerParameters parameters, params string[] files)
{
if (parameters == null)
throw new ArgumentNullException("parameters");
if (files == null)
throw new ArgumentNullException("files");
string createdDirectoryName = null;
string createdTempFileName = null;
AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation;
setup.LoaderOptimization = LoaderOptimization.MultiDomainHost;
AppDomain compilerDomain = AppDomain.CreateDomain("CompilerDomain", null, setup);
bool generateInMemory = false;
string originalOutputAssembly = parameters.OutputAssembly;
try
{
if (parameters.GenerateInMemory)
{
generateInMemory = true;
parameters.GenerateInMemory = false;
if (string.IsNullOrEmpty(parameters.OutputAssembly))
{
// We need to remember the filename generated by Path.GetTempFileName so we can clean it up.
createdTempFileName = Path.GetTempFileName();
parameters.OutputAssembly = createdTempFileName + ".dll";
}
else
{
int tries = 0;
while (true)
{
try
{
tries++;
createdDirectoryName = Path.GetTempPath() + "\\" + Guid.NewGuid();
DirectoryInfo info = Directory.CreateDirectory(createdDirectoryName);
parameters.OutputAssembly = info.FullName + "\\" + parameters.OutputAssembly;
break;
}
catch
{
// If we have tried 10 times without success, give up. Something must be wrong
// with what gets returned by GetTempPath or we have exceeded max_path by appending
// the GUID.
if (tries >= 10)
{
throw;
}
}
}
}
}
WorkflowCompilerInternal compiler = (WorkflowCompilerInternal)compilerDomain.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, typeof(WorkflowCompilerInternal).FullName);
WorkflowCompilerResults results = compiler.Compile(parameters, files);
if (generateInMemory && !results.Errors.HasErrors)
{
results.CompiledAssembly = Assembly.Load(File.ReadAllBytes(results.PathToAssembly));
results.PathToAssembly = null;
}
return results;
}
finally
{
string outputAssembly = parameters.OutputAssembly;
if (generateInMemory)
{
parameters.GenerateInMemory = true;
parameters.OutputAssembly = originalOutputAssembly;
}
AppDomain.Unload(compilerDomain);
// The temp file must be deleted after the app domain is unloaded, or else it will
// be "busy", causing the delete to throw an access exception.
if (generateInMemory)
{
try
{
// There will always be an outputAssemblyName to delete.
File.Delete(outputAssembly);
// If we created a temp file name with Path.GetTempFileName, we need to delete it here.
if (createdTempFileName != null)
{
File.Delete(createdTempFileName);
}
// If we created a directory, delete it.
if (createdDirectoryName != null)
{
Directory.Delete(createdDirectoryName, true);
}
}
catch
{ }
}
}
}
}
#endregion
#region Class TypeAuthorizerClass
internal sealed class TypeAuthorizerClass : ITypeAuthorizer
{
public TypeAuthorizerClass(IList<AuthorizedType> authorizedTypes, WorkflowCompilerResults results, string filename)
{
if (results == null)
{
throw new ArgumentNullException("results");
}
if (string.IsNullOrWhiteSpace(filename))
{
throw new ArgumentException("filename");
}
// It is okay for authorizedTypes to be null. Nothing may have been specified in the config.
this.AuthorizedTypes = authorizedTypes;
this.Results = results;
this.Filename = filename;
}
public IList<AuthorizedType> AuthorizedTypes
{
get;
private set;
}
public WorkflowCompilerResults Results
{
get;
private set;
}
public string Filename
{
get;
private set;
}
public bool IsTypeAuthorized(Type typeToAuthorize)
{
if (typeToAuthorize == null)
{
Results.Errors.Add(new WorkflowCompilerError(this.Filename, -1, -1, ErrorNumbers.Error_TypeNotAuthorized.ToString(CultureInfo.InvariantCulture), SR.GetString(SR.Error_TypeNotAuthorized, SR.GetString(SR.NullConditionExpression))));
return false;
}
bool authorized = false;
if (AuthorizedTypes != null)
{
foreach (AuthorizedType authorizedType in AuthorizedTypes)
{
if (authorizedType.RegularExpression.IsMatch(typeToAuthorize.AssemblyQualifiedName))
{
authorized = (String.Compare(bool.TrueString, authorizedType.Authorized, StringComparison.OrdinalIgnoreCase) == 0);
if (!authorized)
break;
}
}
}
if (!authorized)
{
Results.Errors.Add(new WorkflowCompilerError(this.Filename, -1, -1, ErrorNumbers.Error_TypeNotAuthorized.ToString(CultureInfo.InvariantCulture), SR.GetString(SR.Error_TypeNotAuthorized, typeToAuthorize)));
}
return authorized;
}
}
#endregion
#region Class WorkflowCompilerInternal
internal sealed class WorkflowCompilerInternal : MarshalByRefObject
{
#region Lifetime service
public override object InitializeLifetimeService()
{
return null;
}
#endregion
#region File based compilation
public WorkflowCompilerResults Compile(WorkflowCompilerParameters parameters, string[] allFiles)
{
WorkflowCompilerResults results = new WorkflowCompilerResults(parameters.TempFiles);
// Split the xoml files from cs/vb files.
StringCollection xomlFiles = new StringCollection();
StringCollection userCodeFiles = new StringCollection();
foreach (string file in allFiles)
{
if (file.EndsWith(".xoml", StringComparison.OrdinalIgnoreCase))
xomlFiles.Add(file);
else
userCodeFiles.Add(file);
}
string[] files = new string[xomlFiles.Count];
xomlFiles.CopyTo(files, 0);
string[] codeFiles = new string[userCodeFiles.Count];
userCodeFiles.CopyTo(codeFiles, 0);
string mscorlibPath = typeof(object).Assembly.Location;
ServiceContainer serviceContainer = new ServiceContainer();
MultiTargetingInfo mtInfo = parameters.MultiTargetingInformation;
if (mtInfo == null)
{
XomlCompilerHelper.FixReferencedAssemblies(parameters, results, parameters.LibraryPaths);
}
string mscorlibName = Path.GetFileName(mscorlibPath);
// Add assembly resolver.
ReferencedAssemblyResolver resolver = new ReferencedAssemblyResolver(parameters.ReferencedAssemblies, parameters.LocalAssembly);
AppDomain.CurrentDomain.AssemblyResolve += resolver.ResolveEventHandler;
// prepare service container
TypeProvider typeProvider = new TypeProvider(new ServiceContainer());
int mscorlibIndex = -1;
if ((parameters.ReferencedAssemblies != null) && (parameters.ReferencedAssemblies.Count > 0))
{
for (int i = 0; i < parameters.ReferencedAssemblies.Count; i++)
{
string assemblyPath = parameters.ReferencedAssemblies[i];
if ((mscorlibIndex == -1) && (string.Compare(mscorlibName, Path.GetFileName(assemblyPath), StringComparison.OrdinalIgnoreCase) == 0))
{
mscorlibIndex = i;
mscorlibPath = assemblyPath;
}
typeProvider.AddAssemblyReference(assemblyPath);
}
}
// a note about references to mscorlib:
// If we found mscorlib in the list of reference assemblies, we should remove it prior to sending it to the CodeDOM compiler.
// The CodeDOM compiler would add the right mscorlib [based on the version of the provider we use] and the duplication would
// cause a compilation error.
// If we didn't found a reference to mscorlib we need to add it to the type-provider, though, so we will support exposing
// those known types.
if (mscorlibIndex != -1)
{
parameters.ReferencedAssemblies.RemoveAt(mscorlibIndex);
if (string.IsNullOrEmpty(parameters.CoreAssemblyFileName))
{
parameters.CoreAssemblyFileName = mscorlibPath;
}
}
else
{
typeProvider.AddAssemblyReference(mscorlibPath);
}
serviceContainer.AddService(typeof(ITypeProvider), typeProvider);
TempFileCollection intermediateTempFiles = null;
string localAssemblyPath = string.Empty;
string createdDirectoryName = null;
try
{
using (WorkflowCompilationContext.CreateScope(serviceContainer, parameters))
{
parameters.LocalAssembly = GenerateLocalAssembly(files, codeFiles, parameters, results, out intermediateTempFiles, out localAssemblyPath, out createdDirectoryName);
if (parameters.LocalAssembly != null)
{
// WinOE Bug 17591: we must set the local assembly here,
// otherwise, the resolver won't be able to resolve custom types correctly.
resolver.SetLocalAssembly(parameters.LocalAssembly);
// Work around HERE!!!
// prepare type provider
typeProvider.SetLocalAssembly(parameters.LocalAssembly);
typeProvider.AddAssembly(parameters.LocalAssembly);
results.Errors.Clear();
XomlCompilerHelper.InternalCompileFromDomBatch(files, codeFiles, parameters, results, localAssemblyPath);
}
}
}
catch (Exception e)
{
results.Errors.Add(new WorkflowCompilerError(String.Empty, -1, -1, ErrorNumbers.Error_UnknownCompilerException.ToString(CultureInfo.InvariantCulture), SR.GetString(SR.Error_CompilationFailed, e.Message)));
}
finally
{
// Delate the temp files.
if (intermediateTempFiles != null && parameters.TempFiles.KeepFiles == false)
{
foreach (string file in intermediateTempFiles)
{
try
{
System.IO.File.Delete(file);
}
catch
{
}
}
try
{
// GenerateLocalAssembly may have created a directory, so let's try to delete it
// We can't just delete Path.GetDirectoryName(localAssemblyPath) because it might be the Temp directory.
if (createdDirectoryName != null)
{
Directory.Delete(createdDirectoryName, true);
}
}
catch
{
}
}
}
return results;
}
#endregion
#region Code for Generating Local Assembly
private static ValidationErrorCollection ValidateIdentifiers(IServiceProvider serviceProvider, Activity activity)
{
ValidationErrorCollection validationErrors = new ValidationErrorCollection();
Dictionary<string, int> names = new Dictionary<string, int>();
Walker walker = new Walker();
walker.FoundActivity += delegate(Walker walker2, WalkerEventArgs e)
{
Activity currentActivity = e.CurrentActivity;
if (!currentActivity.Enabled)
{
e.Action = WalkerAction.Skip;
return;
}
ValidationError identifierError = null;
if (names.ContainsKey(currentActivity.QualifiedName))
{
if (names[currentActivity.QualifiedName] != 1)
{
identifierError = new ValidationError(SR.GetString(SR.Error_DuplicatedActivityID, currentActivity.QualifiedName), ErrorNumbers.Error_DuplicatedActivityID, false, "Name");
identifierError.UserData[typeof(Activity)] = currentActivity;
validationErrors.Add(identifierError);
names[currentActivity.QualifiedName] = 1;
}
return;
}
// Undone: AkashS - remove this check when we allow root activities to not have a name.
if (!string.IsNullOrEmpty(currentActivity.Name))
{
names[currentActivity.Name] = 0;
identifierError = ValidationHelpers.ValidateIdentifier("Name", serviceProvider, currentActivity.Name);
if (identifierError != null)
{
identifierError.UserData[typeof(Activity)] = currentActivity;
validationErrors.Add(identifierError);
}
}
};
walker.Walk(activity as Activity);
return validationErrors;
}
private Assembly GenerateLocalAssembly(string[] files, string[] codeFiles, WorkflowCompilerParameters parameters, WorkflowCompilerResults results, out TempFileCollection tempFiles2, out string localAssemblyPath, out string createdDirectoryName)
{
localAssemblyPath = string.Empty;
createdDirectoryName = null;
tempFiles2 = null;
// Generate code for the markup files.
CodeCompileUnit markupCompileUnit = GenerateCodeFromFileBatch(files, parameters, results);
if (results.Errors.HasErrors)
return null;
SupportedLanguages language = CompilerHelpers.GetSupportedLanguage(parameters.LanguageToUse);
// Convert all compile units to source files.
CodeDomProvider codeDomProvider = CompilerHelpers.GetCodeDomProvider(language, parameters.CompilerVersion);
// Clone the parameters.
CompilerParameters clonedParams = XomlCompilerHelper.CloneCompilerParameters(parameters);
clonedParams.TempFiles.KeepFiles = true;
tempFiles2 = clonedParams.TempFiles;
clonedParams.GenerateInMemory = true;
if (string.IsNullOrEmpty(parameters.OutputAssembly))
localAssemblyPath = clonedParams.OutputAssembly = clonedParams.TempFiles.AddExtension("dll");
else
{
string tempAssemblyDirectory = clonedParams.TempFiles.BasePath;
int postfix = 0;
while (true)
{
try
{
if (Directory.Exists(tempAssemblyDirectory))
{
break;
}
Directory.CreateDirectory(tempAssemblyDirectory);
createdDirectoryName = tempAssemblyDirectory;
break;
}
catch
{
// If we have tried 10 times without success, give up. Something must be wrong
// with what gets returned by TempFiles.BasePath
if (postfix >= 10)
{
throw;
}
tempAssemblyDirectory = clonedParams.TempFiles.BasePath + postfix++;
}
}
localAssemblyPath = clonedParams.OutputAssembly = tempAssemblyDirectory + "\\" + Path.GetFileName(clonedParams.OutputAssembly);
clonedParams.TempFiles.AddFile(localAssemblyPath, true);
// Working around the fact that when the OutputAssembly is specified, the
// codeDomProvider.CompileAssemblyFromFile call below does NOT add the pdb file
// to the clonedParams.TempFiles collection. Instead, it looks as though it
// does a clonedParams.TempFiles.BasePath.AddExtension("pdb"), which is a file
// that doesn't actually get created.
// We need to add the pdb file to the clonedParameters.TempFiles collection so that
// it gets deleted, even in the case where we didn't end up creating the tempAssemblyDirectory above.
string pdbFilename = Path.GetFileNameWithoutExtension(localAssemblyPath) + ".pdb";
clonedParams.TempFiles.AddFile(Path.GetDirectoryName(localAssemblyPath) + "\\" + pdbFilename, true);
}
// Explictily ignore warnings (in case the user set this property in the project options).
clonedParams.TreatWarningsAsErrors = false;
if (clonedParams.CompilerOptions != null && clonedParams.CompilerOptions.Length > 0)
{
// Need to remove /delaysign option together with the /keyfile or /keycontainer
// the temp assembly should not be signed or we'll have problems loading it.
// Custom splitting: need to take strings like '"one two"' into account
// even though it has a space inside, it should not be split.
string source = clonedParams.CompilerOptions;
ArrayList optionsList = new ArrayList();
int begin = 0;
int end = 0;
bool insideString = false;
while (end < source.Length)
{
int currentLength = end - begin;
if (source[end] == '"')
{
insideString = !insideString;
}
else if (source[end] == ' ' && !insideString)
{
// Split only if not inside string like in "inside some string".
// Split here. Ignore multiple spaces.
if (begin == end)
{
begin++; // end will get incremented in the end of the loop.
}
else
{
string substring = source.Substring(begin, end - begin);
optionsList.Add(substring);
begin = end + 1; // end will get incremented in the end of the loop
}
}
end++;
}
// The remaining sub-string.
if (begin != end)
{
string substring = source.Substring(begin, end - begin);
optionsList.Add(substring);
}
string[] options = optionsList.ToArray(typeof(string)) as string[];
clonedParams.CompilerOptions = string.Empty;
foreach (string option in options)
{
if (option.Length > 0 &&
!option.StartsWith("/delaysign", StringComparison.OrdinalIgnoreCase) &&
!option.StartsWith("/keyfile", StringComparison.OrdinalIgnoreCase) &&
!option.StartsWith("/keycontainer", StringComparison.OrdinalIgnoreCase))
{
clonedParams.CompilerOptions += " " + option;
}
}
}
// Disable compiler optimizations, but include debug information.
clonedParams.CompilerOptions = (clonedParams.CompilerOptions == null) ? "/optimize-" : clonedParams.CompilerOptions + " /optimize-";
clonedParams.IncludeDebugInformation = true;
if (language == SupportedLanguages.CSharp)
clonedParams.CompilerOptions += " /unsafe";
// Add files.
ArrayList ccus = new ArrayList((ICollection)parameters.UserCodeCompileUnits);
ccus.Add(markupCompileUnit);
ArrayList userCodeFiles = new ArrayList();
userCodeFiles.AddRange(codeFiles);
userCodeFiles.AddRange(XomlCompilerHelper.GenerateFiles(codeDomProvider, clonedParams, (CodeCompileUnit[])ccus.ToArray(typeof(CodeCompileUnit))));
// Generate the temporary assembly.
CompilerResults results2 = codeDomProvider.CompileAssemblyFromFile(clonedParams, (string[])userCodeFiles.ToArray(typeof(string)));
if (results2.Errors.HasErrors)
{
results.AddCompilerErrorsFromCompilerResults(results2);
return null;
}
return results2.CompiledAssembly;
}
internal static CodeCompileUnit GenerateCodeFromFileBatch(string[] files, WorkflowCompilerParameters parameters, WorkflowCompilerResults results)
{
WorkflowCompilationContext context = WorkflowCompilationContext.Current;
if (context == null)
throw new Exception(SR.GetString(SR.Error_MissingCompilationContext));
CodeCompileUnit codeCompileUnit = new CodeCompileUnit();
foreach (string fileName in files)
{
TypeAuthorizerClass typeAuthorizer = null;
// Only set up a TypeAuthorizerClass if CheckTypes is specified.
if (parameters.CheckTypes)
{
typeAuthorizer = new TypeAuthorizerClass(context.GetAuthorizedTypes(), results, fileName);
}
Activity rootActivity = null;
try
{
DesignerSerializationManager manager = new DesignerSerializationManager(context.ServiceProvider);
using (manager.CreateSession())
{
WorkflowMarkupSerializationManager xomlSerializationManager = new WorkflowMarkupSerializationManager(manager);
xomlSerializationManager.WorkflowMarkupStack.Push(parameters);
xomlSerializationManager.LocalAssembly = parameters.LocalAssembly;
using (XmlReader reader = XmlReader.Create(fileName))
{
if (typeAuthorizer == null)
{
rootActivity = WorkflowMarkupSerializationHelpers.LoadXomlDocument(xomlSerializationManager, reader, fileName);
}
else
{
rootActivity = WorkflowMarkupSerializationHelpers.LoadXomlDocument(xomlSerializationManager, reader, fileName, typeAuthorizer);
}
}
if (parameters.LocalAssembly != null)
{
foreach (object error in manager.Errors)
{
if (error is WorkflowMarkupSerializationException)
{
results.Errors.Add(new WorkflowCompilerError(fileName, (WorkflowMarkupSerializationException)error));
}
else
{
results.Errors.Add(new WorkflowCompilerError(fileName, -1, -1, ErrorNumbers.Error_SerializationError.ToString(CultureInfo.InvariantCulture), error.ToString()));
}
}
}
}
}
catch (WorkflowMarkupSerializationException xomlSerializationException)
{
results.Errors.Add(new WorkflowCompilerError(fileName, xomlSerializationException));
continue;
}
catch (Exception e)
{
results.Errors.Add(new WorkflowCompilerError(fileName, -1, -1, ErrorNumbers.Error_SerializationError.ToString(CultureInfo.InvariantCulture), SR.GetString(SR.Error_CompilationFailed, e.Message)));
continue;
}
if (rootActivity == null)
{
results.Errors.Add(new WorkflowCompilerError(fileName, 1, 1, ErrorNumbers.Error_SerializationError.ToString(CultureInfo.InvariantCulture), SR.GetString(SR.Error_RootActivityTypeInvalid)));
continue;
}
bool createNewClass = (!string.IsNullOrEmpty(rootActivity.GetValue(WorkflowMarkupSerializer.XClassProperty) as string));
if (!createNewClass)
{
results.Errors.Add(new WorkflowCompilerError(fileName, 1, 1, ErrorNumbers.Error_SerializationError.ToString(CultureInfo.InvariantCulture), SR.GetString(SR.Error_CannotCompile_No_XClass)));
continue;
}
//NOTE: CompileWithNoCode is meaningless now. It means no x:Code in a XOML file. It exists until the FP migration is done
//Ideally FP should just use XOML files w/o X:Class and run them w/o ever compiling them
if ((parameters.CompileWithNoCode) && XomlCompilerHelper.HasCodeWithin(rootActivity))
{
ValidationError error = new ValidationError(SR.GetString(SR.Error_CodeWithinNotAllowed), ErrorNumbers.Error_CodeWithinNotAllowed);
error.UserData[typeof(Activity)] = rootActivity;
results.Errors.Add(XomlCompilerHelper.CreateXomlCompilerError(error, parameters));
}
ValidationErrorCollection errors = new ValidationErrorCollection();
errors = ValidateIdentifiers(context.ServiceProvider, rootActivity);
foreach (ValidationError error in errors)
results.Errors.Add(XomlCompilerHelper.CreateXomlCompilerError(error, parameters));
if (results.Errors.HasErrors)
continue;
codeCompileUnit.Namespaces.AddRange(WorkflowMarkupSerializationHelpers.GenerateCodeFromXomlDocument(rootActivity, fileName, context.RootNamespace, CompilerHelpers.GetSupportedLanguage(context.Language), context.ServiceProvider));
}
WorkflowMarkupSerializationHelpers.FixStandardNamespacesAndRootNamespace(codeCompileUnit.Namespaces, context.RootNamespace, CompilerHelpers.GetSupportedLanguage(context.Language));
return codeCompileUnit;
}
#endregion
}
#endregion
}
|