示例#1
0
文件: ErrorSink.cs 项目: stantoxt/dlr
 public ErrorCounter(ErrorSink /*!*/ sink)
 {
     ContractUtils.RequiresNotNull(sink, "sink");
     _sink = sink;
 }
        internal SourceStringContentProvider(string code)
        {
            ContractUtils.RequiresNotNull(code, nameof(code));

            _code = code;
        }
示例#3
0
文件: ScriptCode.cs 项目: kerwon/dlr
        protected ScriptCode(SourceUnit sourceUnit)
        {
            ContractUtils.RequiresNotNull(sourceUnit, nameof(sourceUnit));

            _sourceUnit = sourceUnit;
        }
        /// <summary>
        /// This takes an assembly name including extension and saves the provided ScriptCode objects into the assembly.
        ///
        /// The provided script codes can constitute code from multiple languages.  The assemblyName can be either a fully qualified
        /// or a relative path.  The DLR will simply save the assembly to the desired location.  The assembly is created by the DLR and
        /// if a file already exists than an exception is raised.
        ///
        /// The DLR determines the internal format of the ScriptCode and the DLR can feel free to rev this as appropriate.
        /// </summary>
        public static void SaveToAssembly(string assemblyName, params SavableScriptCode[] codes)
        {
            ContractUtils.RequiresNotNull(assemblyName, "assemblyName");
            ContractUtils.RequiresNotNullItems(codes, "codes");

            // break the assemblyName into it's dir/name/extension
            string dir = Path.GetDirectoryName(assemblyName);

            if (String.IsNullOrEmpty(dir))
            {
                dir = Environment.CurrentDirectory;
            }

            string name = Path.GetFileNameWithoutExtension(assemblyName);
            string ext  = Path.GetExtension(assemblyName);

            // build the assembly & type gen that all the script codes will live in...
            AssemblyGen ag = new AssemblyGen(new AssemblyName(name), dir, ext, /*emitSymbols*/ false);
            TypeBuilder tb = ag.DefinePublicType("DLRCachedCode", typeof(object), true);
            TypeGen     tg = new TypeGen(ag, tb);
            // then compile all of the code

            Dictionary <Type, List <CodeInfo> > langCtxBuilders = new Dictionary <Type, List <CodeInfo> >();

            foreach (SavableScriptCode sc in codes)
            {
                List <CodeInfo> builders;
                if (!langCtxBuilders.TryGetValue(sc.LanguageContext.GetType(), out builders))
                {
                    langCtxBuilders[sc.LanguageContext.GetType()] = builders = new List <CodeInfo>();
                }

                KeyValuePair <MethodBuilder, Type> compInfo = sc.CompileForSave(tg);

                builders.Add(new CodeInfo(compInfo.Key, sc, compInfo.Value));
            }

            MethodBuilder mb = tb.DefineMethod(
                "GetScriptCodeInfo",
                MethodAttributes.SpecialName | MethodAttributes.Public | MethodAttributes.Static,
                typeof(MutableTuple <Type[], Delegate[][], string[][], string[][]>),
                ReflectionUtils.EmptyTypes);

            ILGen ilgen = new ILGen(mb.GetILGenerator());

            var langsWithBuilders = langCtxBuilders.ToArray();

            // lang ctx array
            ilgen.EmitArray(typeof(Type), langsWithBuilders.Length, (index) => {
                ilgen.Emit(OpCodes.Ldtoken, langsWithBuilders[index].Key);
                ilgen.EmitCall(typeof(Type).GetMethod("GetTypeFromHandle", new[] { typeof(RuntimeTypeHandle) }));
            });

            // builders array of array
            ilgen.EmitArray(typeof(Delegate[]), langsWithBuilders.Length, (index) => {
                List <CodeInfo> builders = langsWithBuilders[index].Value;

                ilgen.EmitArray(typeof(Delegate), builders.Count, (innerIndex) => {
                    ilgen.EmitNull();
                    ilgen.Emit(OpCodes.Ldftn, builders[innerIndex].Builder);
                    ilgen.EmitNew(
                        builders[innerIndex].DelegateType,
                        new[] { typeof(object), typeof(IntPtr) }
                        );
                });
            });

            // paths array of array
            ilgen.EmitArray(typeof(string[]), langsWithBuilders.Length, (index) => {
                List <CodeInfo> builders = langsWithBuilders[index].Value;

                ilgen.EmitArray(typeof(string), builders.Count, (innerIndex) => {
                    ilgen.EmitString(builders[innerIndex].Code.SourceUnit.Path);
                });
            });

            // 4th element in tuple - custom per-language data
            ilgen.EmitArray(typeof(string[]), langsWithBuilders.Length, (index) => {
                List <CodeInfo> builders = langsWithBuilders[index].Value;

                ilgen.EmitArray(typeof(string), builders.Count, (innerIndex) => {
                    ICustomScriptCodeData data = builders[innerIndex].Code as ICustomScriptCodeData;
                    if (data != null)
                    {
                        ilgen.EmitString(data.GetCustomScriptCodeData());
                    }
                    else
                    {
                        ilgen.Emit(OpCodes.Ldnull);
                    }
                });
            });

            ilgen.EmitNew(
                typeof(MutableTuple <Type[], Delegate[][], string[][], string[][]>),
                new[] { typeof(Type[]), typeof(Delegate[][]), typeof(string[][]), typeof(string[][]) }
                );
            ilgen.Emit(OpCodes.Ret);

            mb.SetCustomAttribute(new CustomAttributeBuilder(
                                      typeof(DlrCachedCodeAttribute).GetConstructor(ReflectionUtils.EmptyTypes),
                                      ArrayUtils.EmptyObjects
                                      ));

            tg.FinishType();
            ag.SaveAssembly();
        }