Пример #1
0
        /// <summary>
        /// 输出类定义开始段代码
        /// </summary>
        /// <param name="language">代码生成语言</param>
        /// <param name="isOutDefinition">是否输出类定义</param>
        /// <returns>类定义</returns>
        protected bool outStart(CodeLanguage language, bool isOutDefinition)
        {
            _definition_ = null;
            _language_   = language;
            if (isOutDefinition)
            {
                _code_.Length = 0;
                if (Coder.Add(GetType(), Type.Type))
                {
                    switch (_language_)
                    {
                    case CodeLanguage.JavaScript:
                    case CodeLanguage.TypeScript:
                        _definition_ = new JavaScriptTypeDefinition(Type);
                        break;

                    default: _definition_ = new CSharpTypeDefinition(Type, true, false); break;
                    }
                    _code_.Add(_definition_.Start);
                    return(true);
                }
                return(false);
            }
            return(true);
        }
        Evaluate(
            IRegExCommandLineArgument realArg)
        {
            if (null != realArg.ShortName)
            {
                throw new Exception("The command line argument '{0}' does not support short names", realArg.GetType().ToString());
            }
            var reg     = new System.Text.RegularExpressions.Regex(realArg.LongName);
            var results = new Array <StringArray>();

            foreach (var arg in Arguments)
            {
                var matches = reg.Match(arg);
                if (!matches.Success)
                {
                    continue;
                }

                var thisResult = new StringArray();
                foreach (var group in matches.Groups)
                {
                    if (group.ToString() == arg)
                    {
                        continue;
                    }
                    thisResult.Add(group.ToString());
                }
                results.Add(thisResult);
            }
            return(results);
        }
Пример #3
0
            /// <summary>
            /// 安装下一个类型
            /// </summary>
            protected override void nextCreate()
            {
                PathMembers.Clear();
                object    pathValue = typeof(AutoCSer.Emit.Constructor <>).MakeGenericType(Type).GetMethod("Default", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, NullValue <Type> .Array, null).Invoke(null, null);
                string    queryName = (Attribute.QueryName ?? (Type.Type.Name + "Id")), query;
                FieldInfo idField = Type.Type.GetField("Id", BindingFlags.Instance | BindingFlags.Public);

                if (idField == null || idField.FieldType != typeof(int))
                {
                    query = queryName + "=0";
                }
                else
                {
                    idField.SetValue(pathValue, 1);
                    query = queryName + "=1";
                }
                foreach (AutoCSer.CodeGenerator.Metadata.MemberIndex member in AutoCSer.CodeGenerator.Metadata.MethodIndex.GetMembers <AutoCSer.WebView.PathMemberAttribute>(Type, Attribute.MemberFilters, Attribute.IsAttribute, Attribute.IsBaseTypeAttribute))
                {
                    if (member.MemberSystemType == typeof(string))
                    {
                        string url = (string)(member.Member as PropertyInfo).GetValue(pathValue, null);
                        if (url.EndsWith(query, StringComparison.Ordinal))
                        {
                            PathMembers.Add(new PathMember {
                                Member = member, Path = url.Substring(0, url.Length - query.Length), QueryName = queryName, IsHash = false, IsIdentity = true
                            });
                        }
                        else
                        {
                            PathMembers.Add(new PathMember {
                                Member = member, Path = url
                            });
                        }
                    }
                    else if (member.MemberSystemType == typeof(AutoCSer.WebView.HashUrl))
                    {
                        AutoCSer.WebView.HashUrl url = (AutoCSer.WebView.HashUrl)(member.Member as PropertyInfo).GetValue(pathValue, null);
                        if (url.Query == query)
                        {
                            PathMembers.Add(new PathMember {
                                Member = member, Path = url.Path, QueryName = queryName, IsHash = true, IsIdentity = true
                            });
                        }
                        else if (url.Query.EndsWith(query, StringComparison.Ordinal))
                        {
                            PathMembers.Add(new PathMember {
                                Member = member, Path = url.Path, OtherQuery = url.Query.Substring(0, url.Query.Length - query.Length), QueryName = queryName, IsHash = true, IsIdentity = true
                            });
                        }
                    }
                }
                if (PathMembers.Length != 0)
                {
                    _code_.Length = 0;
                    create(false);
                    code.Add(_code_);
                }
            }
Пример #4
0
    public static void FulfillArray(StringArray array)
    {
        Console.WriteLine("Введите строки через запятую");
        char[] separator = { ',' };
        var    elements  = Console.ReadLine().Split(separator, 256, StringSplitOptions.None);

        foreach (var element in elements)
        {
            array.Add(element);
        }
    }
Пример #5
0
        /// <summary>
        /// 创建请求数据
        /// </summary>
        /// <param name="requestString"></param>
        /// <param name="pipeline"></param>
        /// <returns></returns>
        private static byte[] createRequestData(string requestString, int pipeline)
        {
            if (pipeline == 1)
            {
                return(Encoding.ASCII.GetBytes(requestString));
            }
            StringArray strings = new StringArray();

            for (int index = pipeline; index != 0; --index)
            {
                strings.Add(requestString);
            }
            return(Encoding.ASCII.GetBytes(strings.ToString()));
        }
Пример #6
0
        public static StringArray splitAtNewline(string source)
        {
            StringArray result        = new StringArray();
            int         source_length = source.Length;
            int         start_pos     = 0;

            for (int i = 0; i < source_length; ++i)
            {
                // If we find a \r or \n, chop out the string
                if ('\r' == source[i])
                {
                    result.Add(source.Substring(start_pos, i - start_pos));
                    start_pos = i + 1;

                    // If \r is followed by \n ignore the \n
                    if (start_pos < source_length && '\n' == source[start_pos])
                    {
                        ++i;
                        ++start_pos;
                    }
                }

                else if ('\n' == source[i])
                {
                    result.Add(source.Substring(start_pos, i - start_pos));
                    start_pos = i + 1;
                }
            }

            // Add in the last item
            if (start_pos < source_length)
            {
                result.Add(source.Substring(start_pos, source_length - start_pos));
            }

            return(result);
        }
Пример #7
0
            /// <summary>
            /// 创建代码
            /// </summary>
            /// <param name="parameter"></param>
            /// <param name="type"></param>
            /// <param name="methodIndexs"></param>
            public void Create(ProjectParameter parameter, ExtensionType type, AjaxMethod[] methodIndexs)
            {
                AutoParameter = parameter;
                Type          = type;
                Methods       = methodIndexs;

                Namespace = type.Type.Namespace;
                if (Namespace == AutoParameter.DefaultNamespace)
                {
                    Namespace = AutoCSerAPI;
                }
                else
                {
                    Namespace = Namespace.StartsWith(AutoParameter.DefaultNamespace, StringComparison.Ordinal) && Namespace[AutoParameter.DefaultNamespace.Length] == '.' ? AutoCSerAPI + Namespace.Substring(AutoParameter.DefaultNamespace.Length) : Namespace;
                }

                _code_.Length = 0;
                create(false);
                code.Add(_code_);
            }
Пример #8
0
        internal int AddString(string stringValue)
        {
            if (StringDictionary.ContainsKey(stringValue))
            {
                return(StringDictionary[stringValue]);
            }
            else
            {
                PendingChanges = true;
                StringDictionary.Add(stringValue, StringDictionary.Count);

                // Clear String Array used for retrieval
                if (ReadWriteMode && StringArray != null)
                {
                    StringArray.Add(StringDictionary.Count - 1, stringValue);
                }
                else
                {
                    StringArray = null;
                }

                return(StringDictionary.Count - 1);
            }
        }
Пример #9
0
 private string javaScript()
 {
     codeBuilder.Add(coder.Code);
     return(end());
 }
Пример #10
0
            /// <summary>
            /// 安装完成处理
            /// </summary>
            protected unsafe override void onCreated()
            {
                StringArray           clientCallCode = new StringArray();
                LeftArray <TcpMethod> methods        = new LeftArray <TcpMethod>();

                TcpMethod[]      methodIndexs;
                ParameterBuilder parameterBuilder = new ParameterBuilder();
                int staticMethodIndex             = 0;

                foreach (Server server in servers.Values)
                {
                    if (server.IsMethod)
                    {
                        IsAllType = false;
                        TcpServerAttributeType = server.AttributeType == null || server.AttributeType.Type == null ? null : server.AttributeType.FullName;
                        ServiceAttribute       = server.Attribute;
                        foreach (ServerType serverType in server.Types)
                        {
                            methods.Add(serverType.Methods);
                        }
                        methodIndexs   = methods.ToArray();
                        methods.Length = 0;
                        methodIndexs   = TcpMethod.CheckIdentity(methodIndexs, getRememberIdentityName(), method => method.Method.MethodKeyFullName);
                        if (methodIndexs == null)
                        {
                            return;
                        }
                        int index = 0;
                        IsVerifyMethod = IsCallQueue = false;
                        parameterBuilder.Clear(ServiceAttribute.IsSimpleSerialize);
                        foreach (TcpMethod method in methodIndexs)
                        {
                            method.MethodIndex       = index++;
                            method.StaticMethodIndex = ++staticMethodIndex;
                            if (!method.IsNullMethod)
                            {
                                if (IsVerifyMethod)
                                {
                                    method.Attribute.IsVerifyMethod = false;
                                }
                                else if (method.IsVerifyMethod)
                                {
                                    IsVerifyMethod = true;
                                    if (method.MethodType == server.AttributeType && server.IsTimeVerify)
                                    {
                                        TimeVerifyMethod = method;
                                    }
                                }
                                parameterBuilder.Add(method);

                                IsCallQueue |= method.Attribute.ServerTaskType == Net.TcpServer.ServerTaskType.Queue;
                            }
                        }
                        ParameterTypes = parameterBuilder.Get();
                        foreach (ServerType serverType in server.Types)
                        {
                            if (serverType.Methods.Length != 0)
                            {
                                Type = serverType.Type;
                                //TimeVerifyType = Type == server.AttributeType && server.IsTimeVerify ? Type : ExtensionType.Null;
                                Attribute    = serverType.Attribute ?? server.Attribute;
                                MethodIndexs = serverType.Methods.ToArray();
                                CSharpTypeDefinition definition = new CSharpTypeDefinition(Type, true, false);
                                _code_.Length = 0;
                                create(false);
                                Coder.Add(definition.Start + _partCodes_["SERVERCALL"] + definition.End);
                                if (ServiceAttribute.IsSegmentation)
                                {
                                    clientCallCode.Add(definition.Start + _partCodes_["CLIENTCALL"] + definition.End);
                                }
                                else
                                {
                                    Coder.Add(definition.Start + _partCodes_["CLIENTCALL"] + definition.End);
                                }
                            }
                        }
                        Type           = server.AttributeType;
                        Attribute      = server.Attribute;
                        IsAllType      = true;
                        MethodIndexs   = methodIndexs;
                        methods.Length = 0;
                        _code_.Length  = 0;
                        create(false);
                        Coder.Add(@"
namespace " + AutoParameter.DefaultNamespace + "." + serverPart + @"
{
" + _partCodes_["SERVER"] + @"
}");
                        string clientCode = @"
namespace " + AutoParameter.DefaultNamespace + "." + SimpleClientPart + @"
{
" + _partCodes_["CLIENT"] + @"
}";
                        if (ServiceAttribute.IsSegmentation)
                        {
                            clientCallCode.Add(clientCode);
                            string fileName = AutoParameter.ProjectPath + "{" + AutoParameter.DefaultNamespace + "}.TcpStaticSimpleServer." + ServiceAttribute.ServerName + ".Client.cs";
                            clientCode = Coder.WarningCode + clientCallCode.ToString() + Coder.FileEndCode;
                            if (Coder.WriteFile(fileName, clientCode))
                            {
                                if (ServiceAttribute.ClientSegmentationCopyPath != null)
                                {
                                    string copyFileName = ServiceAttribute.ClientSegmentationCopyPath + "{" + AutoParameter.DefaultNamespace + "}.TcpStaticSimpleServer." + ServiceAttribute.ServerName + ".Client.cs";
                                    if (Coder.WriteFile(copyFileName, clientCode))
                                    {
                                        Messages.Message(copyFileName + " 被修改");
                                    }
                                }
                                Messages.Message(fileName + " 被修改");
                            }
                            clientCallCode.Length = 0;
                        }
                        else
                        {
                            Coder.Add(clientCode);
                        }
                    }
                }
            }
Пример #11
0
            /// <summary>
            /// 安装完成处理
            /// </summary>
            protected unsafe override void onCreated()
            {
                foreach (ClientCode code in clientCodes.Values)
                {
                    Server server;
                    if (servers.TryGetValue(code.Attribute.ServerName, out server))
                    {
                        if (server.Attribute.GetIsSegmentation)
                        {
                            server.ClientCodes.Add(code.SegmentationCode);
                        }
                        else
                        {
                            Coder.Add(code.Code);
                        }
                    }
                }
                if (clientCodes.Count != 0)
                {
                    clientCodes = DictionaryCreator.CreateOnly <Type, ClientCode>();
                }

                StringArray           clientCallCode = new StringArray();
                LeftArray <TcpMethod> methods        = new LeftArray <TcpMethod>(0);

                TcpMethod[]      methodIndexs;
                ParameterBuilder parameterBuilder = new ParameterBuilder();
                int staticMethodIndex             = 0;

                foreach (Server server in servers.Values)
                {
                    if (server.IsMethod || server.RemoteLinkTypes.Length != 0 || server.ClientCodes.Length != 0)
                    {
                        Attribute = server.Attribute;
                        TcpServerAttributeType = server.AttributeType == null || server.AttributeType.Type == null ? null : server.AttributeType.FullName;

                        Part = PartType.RemoteLink;
                        foreach (RemoteLinkType remoteLinkType in server.RemoteLinkTypes)
                        {
                            if (remoteLinkType.IsRemoteLink)
                            {
                                Type = remoteLinkType.Type;
                                CurrentRemoteLinkType         = remoteLinkType;
                                remoteLinkType.IsRemoteMember = remoteLinkType.RemoteMethods.Length != 0 && RemoteMemberTypes.Add(Type);
                                CSharpTypeDefinition definition = new CSharpTypeDefinition(Type, true, false);
                                _code_.Length = 0;
                                create(false);
                                Coder.Add(definition.Start + _partCodes_["SERVERREMOTE"] + definition.End);
                                if (ServiceAttribute.GetIsSegmentation)
                                {
                                    clientCallCode.Add(definition.Start + _partCodes_["CLIENTREMOTE"] + definition.End);
                                }
                                else
                                {
                                    Coder.Add(definition.Start + _partCodes_["CLIENTREMOTE"] + definition.End);
                                }
                            }
                        }
                        string clientCode = null;
                        if (server.IsMethod)
                        {
                            Part = PartType.CallType;
                            foreach (ServerType serverType in server.Types)
                            {
                                methods.Add(serverType.Methods);
                            }
                            methodIndexs   = methods.ToArray();
                            methods.Length = 0;
                            methodIndexs   = TcpMethod.CheckIdentity(methodIndexs, null, getRememberIdentityName(), method => method.Method.MethodKeyFullName);
                            if (methodIndexs == null)
                            {
                                return;
                            }
                            int index = CallQueueCount = 0;
                            IsVerifyMethod  = false;
                            IsCallQueueLink = ServiceAttribute.GetRemoteExpressionServerTask == Net.TcpServer.ServerTaskType.QueueLink;
                            if (ServiceAttribute.GetRemoteExpressionServerTask == Net.TcpServer.ServerTaskType.Queue || ServiceAttribute.GetRemoteExpressionServerTask == Net.TcpServer.ServerTaskType.QueueLink)
                            {
                                CallQueueCount = (int)ServiceAttribute.GetRemoteExpressionCallQueueIndex + 1;
                            }
                            parameterBuilder.Clear(ServiceAttribute.IsSimpleSerialize);
                            QueueTypeBuilder queueTypeBuilder = new QueueTypeBuilder();
                            foreach (TcpMethod method in methodIndexs)
                            {
                                method.MethodIndex       = index++;
                                method.StaticMethodIndex = ++staticMethodIndex;
                                if (!method.IsNullMethod)
                                {
                                    if (IsVerifyMethod)
                                    {
                                        method.Attribute.IsVerifyMethod = false;
                                    }
                                    else if (method.IsVerifyMethod)
                                    {
                                        IsVerifyMethod            = true;
                                        IsSynchronousVerifyMethod = method.Attribute.ServerTaskType == AutoCSer.Net.TcpServer.ServerTaskType.Synchronous && !method.IsAsynchronousCallback;
                                        if (method.MethodType == server.AttributeType && server.IsTimeVerify)
                                        {
                                            TimeVerifyMethod = method;
                                        }
                                        //method.Attribute.ServerTaskType = Net.TcpServer.ServerTaskType.Synchronous;
                                    }
                                    parameterBuilder.Add(method);
                                    queueTypeBuilder.Add(method);

                                    IsCallQueueLink |= method.Attribute.ServerTaskType == Net.TcpServer.ServerTaskType.QueueLink;
                                    if (method.Attribute.ServerTaskType == Net.TcpServer.ServerTaskType.Queue || method.Attribute.ServerTaskType == Net.TcpServer.ServerTaskType.QueueLink)
                                    {
                                        CallQueueCount = Math.Max((int)method.Attribute.GetServerQueueIndex + 1, CallQueueCount);
                                    }
                                    MaxTimeoutSeconds = Math.Max(MaxTimeoutSeconds, method.Attribute.GetClientTimeoutSeconds);

                                    //if (method.IsAsynchronousCallback && method.Attribute.ServerTaskType != Net.TcpServer.ServerTaskType.Synchronous)
                                    //{
                                    //    Messages.Message("异步函数警告" + method.MemberFullName);
                                    //}
                                }
                            }
                            ParameterTypes       = parameterBuilder.Get();
                            ServerCallQueueTypes = queueTypeBuilder.Get();
                            foreach (ServerType serverType in server.Types)
                            {
                                if (serverType.Methods.Array.Length != 0)
                                {
                                    Type = serverType.Type;
                                    //TimeVerifyType = Type == server.AttributeType && server.IsTimeVerify ? Type : ExtensionType.Null;
                                    Attribute    = serverType.Attribute ?? server.Attribute;
                                    MethodIndexs = serverType.Methods.Array.ToArray();
                                    CSharpTypeDefinition definition = new CSharpTypeDefinition(Type, true, false);
                                    _code_.Length = 0;
                                    create(false);
                                    Coder.Add(definition.Start + _partCodes_["SERVERCALL"] + definition.End);
                                    if (ServiceAttribute.GetIsSegmentation)
                                    {
                                        clientCallCode.Add(definition.Start + _partCodes_["CLIENTCALL"] + definition.End);
                                    }
                                    else
                                    {
                                        Coder.Add(definition.Start + _partCodes_["CLIENTCALL"] + definition.End);
                                    }
                                }
                            }

                            Part           = PartType.ServerType;
                            Type           = server.AttributeType;
                            Attribute      = server.Attribute;
                            MethodIndexs   = methodIndexs;
                            methods.Length = 0;
                            _code_.Length  = 0;
                            create(false);
                            Coder.Add(@"
namespace " + AutoParameter.DefaultNamespace + "." + serverPart + @"
{
" + _partCodes_["SERVER"] + @"
}");
                            clientCode = @"
namespace " + AutoParameter.DefaultNamespace + "." + ClientPart + @"
{
" + _partCodes_["CLIENT"] + @"
}";
                        }
                        if (ServiceAttribute.GetIsSegmentation)
                        {
                            if (clientCode != null)
                            {
                                clientCallCode.Add(clientCode);
                            }
                            clientCallCode.Append(ref server.ClientCodes);
                            string fileName = AutoParameter.ProjectPath + "{" + AutoParameter.DefaultNamespace + "}.TcpStaticServer." + ServiceAttribute.ServerName + ".Client.cs";
                            clientCode = Coder.WarningCode + clientCallCode.ToString() + Coder.FileEndCode;
                            if (Coder.WriteFile(fileName, clientCode))
                            {
                                if (ServiceAttribute.ClientSegmentationCopyPath != null)
                                {
                                    string copyFileName = ServiceAttribute.ClientSegmentationCopyPath + "{" + AutoParameter.DefaultNamespace + "}.TcpStaticServer." + ServiceAttribute.ServerName + ".Client.cs";
                                    if (Coder.WriteFile(copyFileName, clientCode))
                                    {
                                        Messages.Message(copyFileName + " 被修改");
                                    }
                                }
                                Messages.Message(fileName + " 被修改");
                            }
                            clientCallCode.Length = 0;
                        }
                        else if (clientCode != null)
                        {
                            Coder.Add(clientCode);
                        }
                    }
                }
            }
Пример #12
0
        /// <summary>
        /// Get the array of files to compile from all packages.
        /// </summary>
        /// <returns>The script files.</returns>
        /// <param name="allBuilders">If set to <c>true</c> all builders.</param>
        public StringArray GetScriptFiles(
            bool allBuilders = false)
        {
            var bamDir = this.GetBamDirectory();
            var scriptDir = System.IO.Path.Combine(bamDir, PackageUtilities.ScriptsSubFolder);
            var scripts = new StringArray(System.IO.Directory.GetFiles(scriptDir, "*.cs", System.IO.SearchOption.AllDirectories));

            var builderNames = new StringArray();
            if (allBuilders)
            {
                foreach (var package in Graph.Instance.Packages)
                {
                    if (!BuildModeUtilities.IsBuildModePackage(package.Name))
                    {
                        continue;
                    }
                    builderNames.Add(package.Name);
                }
            }
            else
            {
                builderNames.AddUnique(System.String.Format("{0}Builder", Graph.Instance.Mode));
            }
            foreach (var builderName in builderNames)
            {
                var builderScriptDir = System.IO.Path.Combine(bamDir, builderName);
                if (System.IO.Directory.Exists(builderScriptDir))
                {
                    scripts.AddRange(System.IO.Directory.GetFiles(builderScriptDir, "*.cs", System.IO.SearchOption.AllDirectories));
                }
            }
            return scripts;
        }
Пример #13
0
        Evaluate(
            IRegExCommandLineArgument realArg)
        {
            if (null != realArg.ShortName)
            {
                throw new Exception("The command line argument '{0}' does not support short names", realArg.GetType().ToString());
            }
            var reg = new System.Text.RegularExpressions.Regex(realArg.LongName);
            var results = new Array<StringArray>();
            foreach (var arg in Arguments)
            {
                var matches = reg.Match(arg);
                if (!matches.Success)
                {
                    continue;
                }

                var thisResult = new StringArray();
                foreach (var group in matches.Groups)
                {
                    if (group.ToString() == arg)
                    {
                        continue;
                    }
                    thisResult.Add(group.ToString());
                }
                results.Add(thisResult);
            }
            return results;
        }
Пример #14
0
        public void initWithDefaults()
        {
            string param_WithDefault =
            "dd";
            WithDefault = param_WithDefault;
            long param_WithIntDef =
            120;
            WithIntDef = param_WithIntDef;
            WithSeqDefSequenceType param_WithSeqDef =

                new WithSeqDefSequenceType();
                {

                    param_WithSeqDef.Name =
                        "Name"
                    ;

                    param_WithSeqDef.Email =
                        "Email"
                    ;

                }
            ;
            WithSeqDef = param_WithSeqDef;
            TestOCT param_WithOctDef =
            new TestOCT (CoderUtils.defStringToOctetString("'01101100'B"));
            WithOctDef = param_WithOctDef;
            byte[] param_WithOctDef2 =
            CoderUtils.defStringToOctetString("'FFEEAA'H").Value;
            WithOctDef2 = param_WithOctDef2;
            System.Collections.Generic.ICollection<string> param_WithSeqOf =

                new System.Collections.Generic.List<string>();

                {

                    param_WithSeqOf.Add(
                        "aa"
                    );

                    param_WithSeqOf.Add(
                        "dd"
                    );

                }
            ;
            WithSeqOf = param_WithSeqOf;
            System.Collections.Generic.ICollection<TestPRN> param_WithSeqOf2 =

                new System.Collections.Generic.List<TestPRN>();

                {

                    param_WithSeqOf2.Add(
                        new TestPRN ("cc")
                    );

                    param_WithSeqOf2.Add(
                        new TestPRN ("ee")
                    );

                }
            ;
            WithSeqOf2 = param_WithSeqOf2;
            StringArray param_WithSeqOf3 =

                new StringArray();

                    param_WithSeqOf3.initValue();

                {

                    param_WithSeqOf3.Add(
                        "fff"
                    );

                    param_WithSeqOf3.Add(
                        "ggg"
                    );

                }
            ;
            WithSeqOf3 = param_WithSeqOf3;
        }
Пример #15
0
        CompilePackageAssembly(
            bool enforceBamAssemblyVersions = true,
            bool enableClean = true)
        {
            // validate build root
            if (null == Graph.Instance.BuildRoot)
            {
                throw new Exception("Build root has not been specified");
            }

            var gatherSourceProfile = new TimeProfile(ETimingProfiles.GatherSource);
            gatherSourceProfile.StartProfile();

            IdentifyAllPackages(enforceBamAssemblyVersions: enforceBamAssemblyVersions);

            var cleanFirst = CommandLineProcessor.Evaluate(new Options.CleanFirst());
            if (enableClean && cleanFirst && System.IO.Directory.Exists(Graph.Instance.BuildRoot))
            {
                Log.Info("Deleting build root '{0}'", Graph.Instance.BuildRoot);
                try
                {
                    System.IO.Directory.Delete(Graph.Instance.BuildRoot, true);
                }
                catch (System.IO.IOException ex)
                {
                    Log.Info("Failed to delete build root, because {0}. Continuing", ex.Message);
                }
            }

            if (!System.IO.Directory.Exists(Graph.Instance.BuildRoot))
            {
                System.IO.Directory.CreateDirectory(Graph.Instance.BuildRoot);
            }

            BuildModeUtilities.ValidateBuildModePackage();

            var definitions = new StringArray();

            // gather source files
            var sourceCode = new StringArray();
            int packageIndex = 0;
            foreach (var package in Graph.Instance.Packages)
            {
                Log.DebugMessage("{0}: '{1}' @ '{2}'", packageIndex, package.Version, (package.PackageRepositories.Count > 0) ? package.PackageRepositories[0] : "Not in a repository");

                // to compile with debug information, you must compile the files
                // to compile without, we need to file contents to hash the source
                if (Graph.Instance.CompileWithDebugSymbols)
                {
                    var scripts = package.GetScriptFiles();
                    sourceCode.AddRange(scripts);
                    Log.DebugMessage(scripts.ToString("\n\t"));
                }
                else
                {
                    foreach (var scriptFile in package.GetScriptFiles())
                    {
                        using (var reader = new System.IO.StreamReader(scriptFile))
                        {
                            sourceCode.Add(reader.ReadToEnd());
                        }
                        Log.DebugMessage("\t'{0}'", scriptFile);
                    }
                }

                foreach (var define in package.Definitions)
                {
                    if (!definitions.Contains(define))
                    {
                        definitions.Add(define);
                    }
                }

                ++packageIndex;
            }

            // add/remove other definitions
            definitions.Add(VersionDefineForCompiler);
            definitions.Add(HostPlatformDefineForCompiler);
            definitions.Sort();

            gatherSourceProfile.StopProfile();

            var assemblyCompileProfile = new TimeProfile(ETimingProfiles.AssemblyCompilation);
            assemblyCompileProfile.StartProfile();

            // assembly is written to the build root
            var cachedAssemblyPathname = System.IO.Path.Combine(Graph.Instance.BuildRoot, "CachedPackageAssembly");
            cachedAssemblyPathname = System.IO.Path.Combine(cachedAssemblyPathname, Graph.Instance.MasterPackage.Name) + ".dll";
            var hashPathName = System.IO.Path.ChangeExtension(cachedAssemblyPathname, "hash");
            string thisHashCode = null;

            var cacheAssembly = !CommandLineProcessor.Evaluate(new Options.DisableCacheAssembly());

            string compileReason = null;
            if (Graph.Instance.CompileWithDebugSymbols)
            {
                compileReason = "debug symbols were enabled";
            }
            else
            {
                // can an existing assembly be reused?
                thisHashCode = GetPackageHash(sourceCode, definitions, Graph.Instance.MasterPackage.BamAssemblies);
                if (cacheAssembly)
                {
                    if (System.IO.File.Exists(hashPathName))
                    {
                        using (var reader = new System.IO.StreamReader(hashPathName))
                        {
                            var diskHashCode = reader.ReadLine();
                            if (diskHashCode.Equals(thisHashCode))
                            {
                                Log.DebugMessage("Cached assembly used '{0}', with hash {1}", cachedAssemblyPathname, diskHashCode);
                                Log.Detail("Re-using existing package assembly");
                                Graph.Instance.ScriptAssemblyPathname = cachedAssemblyPathname;

                                assemblyCompileProfile.StopProfile();

                                return true;
                            }
                            else
                            {
                                compileReason = "package source has changed since the last compile";
                            }
                        }
                    }
                    else
                    {
                        compileReason = "no previously compiled package assembly exists";
                    }
                }
                else
                {
                    compileReason = "user has disabled package assembly caching";
                }
            }

            // use the compiler in the current runtime version to build the assembly of packages
            var clrVersion = System.Environment.Version;
            var compilerVersion = System.String.Format("v{0}.{1}", clrVersion.Major, clrVersion.Minor);

            Log.Detail("Compiling package assembly (C# compiler {0}{1}), because {2}.",
                compilerVersion,
                Graph.Instance.ProcessState.TargetFrameworkVersion != null ? (", targetting " + Graph.Instance.ProcessState.TargetFrameworkVersion) : string.Empty,
                compileReason);

            var providerOptions = new System.Collections.Generic.Dictionary<string, string>();
            providerOptions.Add("CompilerVersion", compilerVersion);

            if (Graph.Instance.ProcessState.RunningMono)
            {
                Log.DebugMessage("Compiling assembly for Mono");
            }

            using (var provider = new Microsoft.CSharp.CSharpCodeProvider(providerOptions))
            {
                var compilerParameters = new System.CodeDom.Compiler.CompilerParameters();
                compilerParameters.TreatWarningsAsErrors = true;
                compilerParameters.WarningLevel = 4;
                compilerParameters.GenerateExecutable = false;
                compilerParameters.GenerateInMemory = false;

                if (Graph.Instance.CompileWithDebugSymbols)
                {
                    compilerParameters.OutputAssembly = System.IO.Path.Combine(System.IO.Path.GetTempPath(), Graph.Instance.MasterPackage.Name) + ".dll";
                }
                else
                {
                    compilerParameters.OutputAssembly = cachedAssemblyPathname;
                }

                var compilerOptions = "/checked+ /unsafe-";
                if (Graph.Instance.CompileWithDebugSymbols)
                {
                    compilerParameters.IncludeDebugInformation = true;
                    compilerOptions += " /optimize-";
                }
                else
                {
                    compilerOptions += " /optimize+";
                }
                compilerOptions += " /platform:anycpu";

                // define strings
                compilerOptions += " /define:" + definitions.ToString(';');

                compilerParameters.CompilerOptions = compilerOptions;

                if (provider.Supports(System.CodeDom.Compiler.GeneratorSupport.Resources))
                {
                    // Bam assembly
                    // TODO: Q: why is it only for the master package? Why not all of them, which may have additional dependencies?
                    foreach (var assembly in Graph.Instance.MasterPackage.BamAssemblies)
                    {
                        var assemblyFileName = System.String.Format("{0}.dll", assembly.Name);
                        var assemblyPathName = System.IO.Path.Combine(Graph.Instance.ProcessState.ExecutableDirectory, assemblyFileName);
                        compilerParameters.ReferencedAssemblies.Add(assemblyPathName);
                    }

                    // DotNet assembly
                    foreach (var desc in Graph.Instance.MasterPackage.DotNetAssemblies)
                    {
                        var assemblyFileName = System.String.Format("{0}.dll", desc.Name);
                        compilerParameters.ReferencedAssemblies.Add(assemblyFileName);
                    }

                    if (Graph.Instance.ProcessState.RunningMono)
                    {
                        compilerParameters.ReferencedAssemblies.Add("Mono.Posix.dll");
                    }
                }
                else
                {
                    throw new Exception("C# compiler does not support Resources");
                }

                System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(compilerParameters.OutputAssembly));

                var results = Graph.Instance.CompileWithDebugSymbols ?
                    provider.CompileAssemblyFromFile(compilerParameters, sourceCode.ToArray()) :
                    provider.CompileAssemblyFromSource(compilerParameters, sourceCode.ToArray());

                if (results.Errors.HasErrors || results.Errors.HasWarnings)
                {
                    Log.ErrorMessage("Failed to compile package '{0}'. There are {1} errors.", Graph.Instance.MasterPackage.FullName, results.Errors.Count);
                    foreach (System.CodeDom.Compiler.CompilerError error in results.Errors)
                    {
                        Log.ErrorMessage("\t{0}({1}): {2} {3}", error.FileName, error.Line, error.ErrorNumber, error.ErrorText);
                    }
                    return false;
                }

                if (!Graph.Instance.CompileWithDebugSymbols)
                {
                    if (cacheAssembly)
                    {
                        using (var writer = new System.IO.StreamWriter(hashPathName))
                        {
                            writer.WriteLine(thisHashCode);
                        }
                    }
                    else
                    {
                        // will not throw if the file doesn't exist
                        System.IO.File.Delete(hashPathName);
                    }
                }

                Log.DebugMessage("Written assembly to '{0}'", compilerParameters.OutputAssembly);
                Graph.Instance.ScriptAssemblyPathname = compilerParameters.OutputAssembly;
            }

            assemblyCompileProfile.StopProfile();

            return true;
        }