[mcs] extend API for loading types and consuming source file from a stream (#4905)
authorBernhard Urban <bernhard.urban@xamarin.com>
Mon, 22 May 2017 10:40:19 +0000 (12:40 +0200)
committerMarek Safar <marek.safar@gmail.com>
Mon, 22 May 2017 10:40:19 +0000 (12:40 +0200)
mcs/mcs/driver.cs
mcs/mcs/eval.cs
mcs/mcs/import.cs
mcs/mcs/location.cs
mcs/mcs/support.cs

index 0a11914328ae79629b356b78bd879de1942f3b69..4db99f7e5fe7ceff533fc010e89ff078d489f9e0 100644 (file)
@@ -44,31 +44,45 @@ namespace Mono.CSharp
 
                void tokenize_file (SourceFile sourceFile, ModuleContainer module, ParserSession session)
                {
-                       Stream input;
+                       Stream input = null;
+                       SeekableStreamReader reader = null;
 
                        try {
-                               input = File.OpenRead (sourceFile.Name);
+                               if (sourceFile.GetInputStream != null) {
+                                       reader = sourceFile.GetInputStream (sourceFile);
+                                       if (reader == null) {
+                                               throw new FileNotFoundException ("Delegate returned null", sourceFile.Name);
+                                       }
+                               } else {
+                                       input = File.OpenRead (sourceFile.Name);
+                               }
                        } catch {
                                Report.Error (2001, "Source file `" + sourceFile.Name + "' could not be found");
                                return;
                        }
 
-                       using (input){
-                               SeekableStreamReader reader = new SeekableStreamReader (input, ctx.Settings.Encoding);
-                               var file = new CompilationSourceFile (module, sourceFile);
+                       if (reader == null) {
+                               using (input) {
+                                       reader = new SeekableStreamReader (input, ctx.Settings.Encoding);
+                                       DoTokenize (sourceFile, module, session, reader);
+                               }
+                       } else {
+                               DoTokenize (sourceFile, module, session, reader);
+                       }
+               }
+
+               void DoTokenize (SourceFile sourceFile, ModuleContainer module, ParserSession session, SeekableStreamReader reader) {
+                       var file = new CompilationSourceFile (module, sourceFile);
 
-                               Tokenizer lexer = new Tokenizer (reader, file, session, ctx.Report);
-                               int token, tokens = 0, errors = 0;
+                       Tokenizer lexer = new Tokenizer (reader, file, session, ctx.Report);
+                       int token, tokens = 0, errors = 0;
 
-                               while ((token = lexer.token ()) != Token.EOF){
-                                       tokens++;
-                                       if (token == Token.ERROR)
-                                               errors++;
-                               }
-                               Console.WriteLine ("Tokenized: " + tokens + " found " + errors + " errors");
+                       while ((token = lexer.token ()) != Token.EOF) {
+                               tokens++;
+                               if (token == Token.ERROR)
+                                       errors++;
                        }
-                       
-                       return;
+                       Console.WriteLine ("Tokenized: " + tokens + " found " + errors + " errors");
                }
 
                void Parse (ModuleContainer module)
@@ -129,36 +143,50 @@ namespace Mono.CSharp
 
                public void Parse (SourceFile file, ModuleContainer module, ParserSession session, Report report)
                {
-                       Stream input;
+                       Stream input = null;
+                       SeekableStreamReader reader = null;
 
                        try {
-                               input = File.OpenRead (file.Name);
+                               if (file.GetInputStream != null) {
+                                       reader = file.GetInputStream (file);
+                                       if (reader == null) {
+                                               throw new FileNotFoundException ("Delegate returned null", file.Name);
+                                       }
+                               } else {
+                                       input = File.OpenRead (file.Name);
+                               }
                        } catch {
                                report.Error (2001, "Source file `{0}' could not be found", file.Name);
                                return;
                        }
 
-                       // Check 'MZ' header
-                       if (input.ReadByte () == 77 && input.ReadByte () == 90) {
+                       if (reader == null) {
+                               using (input) {
+                                       // Check 'MZ' header
+                                       if (input.ReadByte () == 77 && input.ReadByte () == 90) {
 
-                               report.Error (2015, "Source file `{0}' is a binary file and not a text file", file.Name);
-                               input.Close ();
-                               return;
-                       }
+                                               report.Error (2015, "Source file `{0}' is a binary file and not a text file", file.Name);
+                                               return;
+                                       }
 
-                       input.Position = 0;
-                       SeekableStreamReader reader = new SeekableStreamReader (input, ctx.Settings.Encoding, session.StreamReaderBuffer);
+                                       input.Position = 0;
+                                       reader = new SeekableStreamReader (input, ctx.Settings.Encoding, session.StreamReaderBuffer);
 
+                                       DoParse (file, module, session, report, reader);
+                               }
+                       } else {
+                               DoParse (file, module, session, report, reader);
+                       }
+               }
+
+               void DoParse (SourceFile file, ModuleContainer module, ParserSession session, Report report, SeekableStreamReader reader) {
                        Parse (reader, file, module, session, report);
 
                        if (ctx.Settings.GenerateDebugInfo && report.Errors == 0 && !file.HasChecksum) {
-                               input.Position = 0;
+                               reader.Stream.Position = 0;
                                var checksum = session.GetChecksumAlgorithm ();
-                               file.SetChecksum (checksum.ComputeHash (input));
+                               file.SetChecksum (checksum.ComputeHash (reader.Stream));
                        }
-
-                       reader.Dispose ();
-                       input.Close ();
                }
 
                public static void Parse (SeekableStreamReader reader, SourceFile sourceFile, ModuleContainer module, ParserSession session, Report report)
index d4e83a506a0fcfbf1d1b00d8522173ca92f15462..60e0c6d64a05de757fecad7d838f71415d8545af 100644 (file)
@@ -958,6 +958,12 @@ namespace Mono.CSharp
                                importer.ImportAssembly (a, module.GlobalRootNamespace);
                        }
                }
+
+               public void ImportTypes (bool importExtensionTypes, params Type[] types) {
+#if !STATIC
+                       importer.ImportTypes (types, module.GlobalRootNamespace, importExtensionTypes);
+#endif
+               }
        }
 
        
index d73bc4578df0dd5f0aa2c65e3b0bfb97bd0825dd..2c315752b770d5de8ba3c054ca4d8204f250e0bc 100644 (file)
@@ -1092,7 +1092,7 @@ namespace Mono.CSharp
                        }
                }
 
-               protected void ImportTypes (MetaType[] types, Namespace targetNamespace, bool importExtensionTypes)
+               public void ImportTypes (MetaType[] types, Namespace targetNamespace, bool importExtensionTypes)
                {
                        Namespace ns = targetNamespace;
                        string prev_namespace = null;
index 658f3b765fa4f48f4e9e1bce1787cca9a387e215..287aac0797a375b222d27470769e692f0dabefe7 100644 (file)
@@ -59,6 +59,7 @@ namespace Mono.CSharp
                public readonly string OriginalFullPathName;
                public readonly int Index;
                public bool AutoGenerated;
+               public Func<SourceFile, SeekableStreamReader> GetInputStream;
 
                SourceFileEntry file;
                byte[] algGuid, checksum;
@@ -71,6 +72,11 @@ namespace Mono.CSharp
                        this.OriginalFullPathName = path;
                }
 
+               public SourceFile (string name, string path, int index, Func<SourceFile, SeekableStreamReader> inputStreamDelegate) : this (name, path, index)
+               {
+                       this.GetInputStream = inputStreamDelegate;
+               }
+
                public byte[] Checksum {
                        get {
                                return checksum;
index ab3cc5c1492bc3f62be5b9c7e77600a4047d8104..fe6343a814db2f0136d48500c484d376491fbd30 100644 (file)
@@ -73,7 +73,7 @@ namespace Mono.CSharp {
 #endif
 
                StreamReader reader;
-               Stream stream;
+               public readonly Stream Stream;
 
                char[] buffer;
                int read_ahead_length;  // the length of read buffer
@@ -83,7 +83,7 @@ namespace Mono.CSharp {
 
                public SeekableStreamReader (Stream stream, Encoding encoding, char[] sharedBuffer = null)
                {
-                       this.stream = stream;
+                       this.Stream = stream;
                        this.buffer = sharedBuffer;
 
                        InitializeStream (DefaultReadAheadSize);
@@ -105,7 +105,7 @@ namespace Mono.CSharp {
                        if (buffer == null || buffer.Length < required_buffer_size)
                                buffer = new char [required_buffer_size];
 
-                       stream.Position = 0;
+                       Stream.Position = 0;
                        buffer_start = char_count = pos = 0;
                }
 
@@ -134,7 +134,7 @@ namespace Mono.CSharp {
                                        // Cannot use handy reader.DiscardBufferedData () because it for
                                        // some strange reason resets encoding as well
                                        //
-                                       reader = new StreamReader (stream, reader.CurrentEncoding, true);
+                                       reader = new StreamReader (Stream, reader.CurrentEncoding, true);
                                }
 
                                while (value > buffer_start + char_count) {