Exemplo n.º 1
0
        //
        // This is used when we encounter a #line preprocessing directive during parsing
        // to register additional source file names
        //
        public SourceFile LookupFile(CompilationSourceFile comp_unit, string name)
        {
            if (all_source_files == null)
            {
                all_source_files = new Dictionary <string, SourceFile> ();
                foreach (var source in SourceFiles)
                {
                    all_source_files[source.FullPathName] = source;
                }
            }

            string path;

            if (!Path.IsPathRooted(name))
            {
                var    loc  = comp_unit.SourceFile;
                string root = Path.GetDirectoryName(loc.FullPathName);
                path = Path.GetFullPath(Path.Combine(root, name));
                var dir = Path.GetDirectoryName(loc.Name);
                if (!string.IsNullOrEmpty(dir))
                {
                    name = Path.Combine(dir, name);
                }
            }
            else
            {
                path = name;
            }

            SourceFile retval;

            if (all_source_files.TryGetValue(path, out retval))
            {
                return(retval);
            }

            retval = new SourceFile(name, path, all_source_files.Count + 1);
            Location.AddFile(retval);
            all_source_files.Add(path, retval);
            return(retval);
        }
Exemplo n.º 2
0
        public SourceFile LookupFile(CompilationSourceFile comp_unit, string name)
        {
            if (all_source_files == null)
            {
                all_source_files = new List <SourceFile>();
            }


            string path;

            if (!Path.IsPathRooted(name))
            {
                var    loc  = comp_unit.SourceFile;
                string root = Path.GetDirectoryName(loc.FullPathName);
                path = Path.GetFullPath(Path.Combine(root, name));
                var dir = Path.GetDirectoryName(loc.Name);
                if (!string.IsNullOrEmpty(dir))
                {
                    name = Path.Combine(dir, name);
                }
            }
            else
            {
                path = name;
            }


            foreach (var src in all_source_files)
            {
                if (src.FullPathName == name)
                {
                    return(src);
                }
            }

            SourceFile retval = new SourceFile(name, path, all_source_files.Count + 1);

            all_source_files.Add(retval);
            return(retval);
        }
Exemplo n.º 3
0
        public bool IsConditionallyExcluded(IMemberContext ctx)
        {
            if ((Kind & (MemberKind.Class | MemberKind.Method)) == 0)
            {
                return(false);
            }

            var conditions = MemberDefinition.ConditionalConditions();

            if (conditions == null)
            {
                return(false);
            }

            var m = ctx.CurrentMemberDefinition;
            CompilationSourceFile unit = null;

            while (m != null && unit == null)
            {
                unit = m as CompilationSourceFile;
                m    = m.Parent;
            }

            if (unit != null)
            {
                foreach (var condition in conditions)
                {
                    if (unit.IsConditionalDefined(condition))
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
Exemplo n.º 4
0
        // Mimicked from https://github.com/kkdevs/Patchwork/blob/master/Patchwork/MonoScript.cs#L124
        public static Assembly Compile(Dictionary <string, byte[]> sources, TextWriter logger = null)
        {
            ReportPrinter reporter = logger == null ? new ConsoleReportPrinter() : new StreamReportPrinter(logger);

            Location.Reset();

            var dllName = $"compiled_{DateTime.Now.Ticks}";

            compiledAssemblies.Add(dllName);

            var ctx = CreateContext(reporter);

            ctx.Settings.SourceFiles.Clear();

            var i = 0;

            SeekableStreamReader GetFile(SourceFile file)
            {
                return(new SeekableStreamReader(new MemoryStream(sources[file.OriginalFullPathName]), Encoding.UTF8));
            }

            foreach (var source in sources)
            {
                ctx.Settings.SourceFiles.Add(new SourceFile(Path.GetFileName(source.Key), source.Key, i, GetFile));
                i++;
            }

            var container = new ModuleContainer(ctx);

            RootContext.ToplevelTypes = container;
            Location.Initialize(ctx.Settings.SourceFiles);

            var session = new ParserSession {
                UseJayGlobalArrays = true, LocatedTokens = new LocatedToken[15000]
            };

            container.EnableRedefinition();

            foreach (var sourceFile in ctx.Settings.SourceFiles)
            {
                var stream = sourceFile.GetInputStream(sourceFile);
                var source = new CompilationSourceFile(container, sourceFile);
                source.EnableRedefinition();
                container.AddTypeContainer(source);
                var parser = new CSharpParser(stream, source, session);
                parser.parse();
            }

            var ass = new AssemblyDefinitionDynamic(container, dllName, $"{dllName}.dll");

            container.SetDeclaringAssembly(ass);

            var importer = new ReflectionImporter(container, ctx.BuiltinTypes);

            ass.Importer = importer;

            var loader = new DynamicLoader(importer, ctx);

            ImportAppdomainAssemblies(a => importer.ImportAssembly(a, container.GlobalRootNamespace));

            loader.LoadReferences(container);
            ass.Create(AppDomain.CurrentDomain, AssemblyBuilderAccess.RunAndSave);
            container.CreateContainer();
            loader.LoadModules(ass, container.GlobalRootNamespace);
            container.InitializePredefinedTypes();
            container.Define();

            if (ctx.Report.Errors > 0)
            {
                logger?.WriteLine("Found errors! Aborting compilation...");
                return(null);
            }

            try
            {
                ass.Resolve();
                ass.Emit();
                container.CloseContainer();
                ass.EmbedResources();
            }
            catch (Exception e)
            {
                logger?.WriteLine($"Failed to compile because {e}");
                return(null);
            }

            return(ass.Builder);
        }
Exemplo n.º 5
0
        //
        // Processes "see" or "seealso" elements from cref attribute.
        //
        void HandleXrefCommon(MemberCore mc, XmlElement xref)
        {
            string cref = xref.GetAttribute("cref");

            // when, XmlReader, "if (cref == null)"
            if (!xref.HasAttribute("cref"))
            {
                return;
            }

            // Nothing to be resolved the reference is marked explicitly
            if (cref.Length > 2 && cref [1] == ':')
            {
                return;
            }

            // Additional symbols for < and > are allowed for easier XML typing
            cref = cref.Replace('{', '<').Replace('}', '>');

            var encoding = module.Compiler.Settings.Encoding;
            var s        = new MemoryStream(encoding.GetBytes(cref));

            var source_file = new CompilationSourceFile(doc_module, mc.Location.SourceFile);
            var report      = new Report(doc_module.Compiler, new NullReportPrinter());

            if (session == null)
            {
                session = new ParserSession {
                    UseJayGlobalArrays = true
                }
            }
            ;

            SeekableStreamReader seekable = new SeekableStreamReader(s, encoding, session.StreamReaderBuffer);

            var parser = new CSharpParser(seekable, source_file, report, session);

            ParsedParameters          = null;
            ParsedName                = null;
            ParsedBuiltinType         = null;
            ParsedOperator            = null;
            parser.Lexer.putback_char = Tokenizer.DocumentationXref;
            parser.Lexer.parsing_generic_declaration_doc = true;
            parser.parse();
            if (report.Errors > 0)
            {
                Report.Warning(1584, 1, mc.Location, "XML comment on `{0}' has syntactically incorrect cref attribute `{1}'",
                               mc.GetSignatureForError(), cref);

                xref.SetAttribute("cref", "!:" + cref);
                return;
            }

            MemberSpec          member;
            string              prefix = null;
            FullNamedExpression fne    = null;

            //
            // Try built-in type first because we are using ParsedName as identifier of
            // member names on built-in types
            //
            if (ParsedBuiltinType != null && (ParsedParameters == null || ParsedName != null))
            {
                member = ParsedBuiltinType.Type;
            }
            else
            {
                member = null;
            }

            if (ParsedName != null || ParsedOperator.HasValue)
            {
                TypeSpec type        = null;
                string   member_name = null;

                if (member == null)
                {
                    if (ParsedOperator.HasValue)
                    {
                        type = mc.CurrentType;
                    }
                    else if (ParsedName.Left != null)
                    {
                        fne = ResolveMemberName(mc, ParsedName.Left);
                        if (fne != null)
                        {
                            var ns = fne as NamespaceExpression;
                            if (ns != null)
                            {
                                fne = ns.LookupTypeOrNamespace(mc, ParsedName.Name, ParsedName.Arity, LookupMode.Probing, Location.Null);
                                if (fne != null)
                                {
                                    member = fne.Type;
                                }
                            }
                            else
                            {
                                type = fne.Type;
                            }
                        }
                    }
                    else
                    {
                        fne = ResolveMemberName(mc, ParsedName);
                        if (fne == null)
                        {
                            type = mc.CurrentType;
                        }
                        else if (ParsedParameters == null)
                        {
                            member = fne.Type;
                        }
                        else if (fne.Type.MemberDefinition == mc.CurrentType.MemberDefinition)
                        {
                            member_name = Constructor.ConstructorName;
                            type        = fne.Type;
                        }
                    }
                }
                else
                {
                    type   = (TypeSpec)member;
                    member = null;
                }

                if (ParsedParameters != null)
                {
                    var old_printer = mc.Module.Compiler.Report.SetPrinter(new NullReportPrinter());
                    try {
                        var context = new DocumentationMemberContext(mc, ParsedName ?? MemberName.Null);

                        foreach (var pp in ParsedParameters)
                        {
                            pp.Resolve(context);
                        }
                    } finally {
                        mc.Module.Compiler.Report.SetPrinter(old_printer);
                    }
                }

                if (type != null)
                {
                    if (member_name == null)
                    {
                        member_name = ParsedOperator.HasValue ?
                                      Operator.GetMetadataName(ParsedOperator.Value) : ParsedName.Name;
                    }

                    int parsed_param_count;
                    if (ParsedOperator == Operator.OpType.Explicit || ParsedOperator == Operator.OpType.Implicit)
                    {
                        parsed_param_count = ParsedParameters.Count - 1;
                    }
                    else if (ParsedParameters != null)
                    {
                        parsed_param_count = ParsedParameters.Count;
                    }
                    else
                    {
                        parsed_param_count = 0;
                    }

                    int parameters_match = -1;
                    do
                    {
                        var members = MemberCache.FindMembers(type, member_name, true);
                        if (members != null)
                        {
                            foreach (var m in members)
                            {
                                if (ParsedName != null && m.Arity != ParsedName.Arity)
                                {
                                    continue;
                                }

                                if (ParsedParameters != null)
                                {
                                    IParametersMember pm = m as IParametersMember;
                                    if (pm == null)
                                    {
                                        continue;
                                    }

                                    if (m.Kind == MemberKind.Operator && !ParsedOperator.HasValue)
                                    {
                                        continue;
                                    }

                                    var pm_params = pm.Parameters;

                                    int i;
                                    for (i = 0; i < parsed_param_count; ++i)
                                    {
                                        var pparam = ParsedParameters[i];

                                        if (i >= pm_params.Count || pparam == null || pparam.TypeSpec == null ||
                                            !TypeSpecComparer.Override.IsEqual(pparam.TypeSpec, pm_params.Types[i]) ||
                                            (pparam.Modifier & Parameter.Modifier.RefOutMask) != (pm_params.FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask))
                                        {
                                            if (i > parameters_match)
                                            {
                                                parameters_match = i;
                                            }

                                            i = -1;
                                            break;
                                        }
                                    }

                                    if (i < 0)
                                    {
                                        continue;
                                    }

                                    if (ParsedOperator == Operator.OpType.Explicit || ParsedOperator == Operator.OpType.Implicit)
                                    {
                                        if (pm.MemberType != ParsedParameters[parsed_param_count].TypeSpec)
                                        {
                                            parameters_match = parsed_param_count + 1;
                                            continue;
                                        }
                                    }
                                    else
                                    {
                                        if (parsed_param_count != pm_params.Count)
                                        {
                                            continue;
                                        }
                                    }
                                }

                                if (member != null)
                                {
                                    Report.Warning(419, 3, mc.Location,
                                                   "Ambiguous reference in cref attribute `{0}'. Assuming `{1}' but other overloads including `{2}' have also matched",
                                                   cref, member.GetSignatureForError(), m.GetSignatureForError());

                                    break;
                                }

                                member = m;
                            }
                        }

                        // Continue with parent type for nested types
                        if (member == null)
                        {
                            type = type.DeclaringType;
                        }
                        else
                        {
                            type = null;
                        }
                    } while (type != null);

                    if (member == null && parameters_match >= 0)
                    {
                        for (int i = parameters_match; i < parsed_param_count; ++i)
                        {
                            Report.Warning(1580, 1, mc.Location, "Invalid type for parameter `{0}' in XML comment cref attribute `{1}'",
                                           (i + 1).ToString(), cref);
                        }

                        if (parameters_match == parsed_param_count + 1)
                        {
                            Report.Warning(1581, 1, mc.Location, "Invalid return type in XML comment cref attribute `{0}'", cref);
                        }
                    }
                }
            }

            if (member == null)
            {
                Report.Warning(1574, 1, mc.Location, "XML comment on `{0}' has cref attribute `{1}' that could not be resolved",
                               mc.GetSignatureForError(), cref);
                cref = "!:" + cref;
            }
            else if (member == InternalType.Namespace)
            {
                cref = "N:" + fne.GetSignatureForError();
            }
            else
            {
                prefix = GetMemberDocHead(member);
                cref   = prefix + member.GetSignatureForDocumentation();
            }

            xref.SetAttribute("cref", cref);
        }
Exemplo n.º 6
0
 public virtual void Visit(CompilationSourceFile csf)
 {
 }
Exemplo n.º 7
0
    public Assembly DoStaticCompile(IEnumerable <object> sources, string prefix = "compiled_")
    {
        reporter.Reset();
        Location.Reset();
        var ctx = BuildContext(reporter);

        ctx.Settings.SourceFiles.Clear();
        int             i        = 0;
        var             allBytes = new MemoryStream();
        List <Assembly> imports  = new List <Assembly>();

        foreach (var fo in sources)
        {
            Assembly impass = fo as Assembly;
            if (impass != null)
            {
                imports.Add(impass);
                continue;
            }
            var    f    = fo as string;
            byte[] fbuf = fo as byte[];
            if (f != null)
            {
                if (!f.EndsWith(".cs"))
                {
                    continue;
                }
                var bname = (f + "\n").ToBytes();
                allBytes.Write(bname, 0, bname.Length);
                fbuf = File.ReadAllBytes(f);
                allBytes.Write(fbuf, 0, fbuf.Length);
            }
            else
            {
                allBytes.Write(fbuf, 0, fbuf.Length);
                f = null;
            }
            i++;
            ctx.Settings.SourceFiles.Add(new SourceFile(f == null ? "<eval>" : Path.GetFileName(f), f ?? "<eval>", i, (o) =>
            {
                return(new SeekableStreamReader(new MemoryStream(fbuf), Encoding.UTF8));
            }));
        }
        string dllname = prefix + (counter++) + ".dll";

        if (tempdir != null)
        {
            if (hashkey != null)
            {
                var hb = hashkey.ToBytes();
                allBytes.Write(hb, 0, hb.Length);
            }

            var hash = prefix + Ext.HashToString(allBytes.ToArray()).Substring(0, 12).ToLower() + ".dll";
            if (hashkey == null)
            {
                hashkey = hash;
            }

            dllname = Path.Combine(tempdir, hash);
            if (File.Exists(dllname))
            {
                var nam = AssemblyName.GetAssemblyName(dllname);
                unloaded.Remove(nam.Name.ToLower());
                return(Assembly.Load(nam));
            }
        }

        var mod = new ModuleContainer(ctx);

        RootContext.ToplevelTypes = mod;
        Location.Initialize(ctx.Settings.SourceFiles);
        var session = new ParserSession()
        {
            UseJayGlobalArrays = true,
            LocatedTokens      = new LocatedToken[15000]
        };

        mod.EnableRedefinition();
        foreach (var finfo in ctx.Settings.SourceFiles)
        {
            var fs   = finfo.GetInputStream(finfo);
            var csrc = new CompilationSourceFile(mod, finfo);
            csrc.EnableRedefinition();
            mod.AddTypeContainer(csrc);
            var parser = new CSharpParser(fs, csrc, session);
            parser.parse();
        }
        Debug.Log("Defining new assembly " + dllname);
        var ass = new AssemblyDefinitionDynamic(mod, Path.GetFileNameWithoutExtension(dllname), dllname);

        mod.SetDeclaringAssembly(ass);
        var importer = new ReflectionImporter(mod, ctx.BuiltinTypes);

        ass.Importer = importer;
        var loader = new DynamicLoader(importer, ctx);

        ImportAssemblies((a) => importer.ImportAssembly(a, mod.GlobalRootNamespace), prefix);
        foreach (var impa in imports)
        {
            importer.ImportAssembly(impa, mod.GlobalRootNamespace);
        }
        loader.LoadReferences(mod);
        ass.Create(AppDomain.CurrentDomain, AssemblyBuilderAccess.RunAndSave);
        mod.CreateContainer();
        loader.LoadModules(ass, mod.GlobalRootNamespace);
        mod.InitializePredefinedTypes();
        mod.Define();
        if (ctx.Report.Errors > 0)
        {
            tw.WriteLine($"{ctx.Report.Errors} errors, aborting.");
            return(null);
        }
        try
        {
            ass.Resolve();
            ass.Emit();
            mod.CloseContainer();
            ass.EmbedResources();
        }
        catch (Exception ex)
        {
            tw.WriteLine($"Link error: " + ex.ToString());
            return(null);
        }
        if (tempdir != null)
        {
            ass.Save();
        }
        return(ass.Builder);
    }