Add clone for error expression. Fixes #13443
[mono.git] / mcs / mcs / cs-tokenizer.cs
index 4ec1bd9088113a4e25841ef29a188fa2c2773277..37447f6df9b474f548b0f7c708b3f66ef719d6fe 100644 (file)
@@ -21,10 +21,47 @@ using System.Collections;
 
 namespace Mono.CSharp
 {
+       //
+       // This class has to be used by parser only, it reuses token
+       // details once a file is parsed
+       //
+       public class LocatedToken
+       {
+               public int row, column;
+               public string value;
+               public SourceFile file;
+
+               public LocatedToken ()
+               {
+               }
+
+               public LocatedToken (string value, Location loc)
+               {
+                       this.value = value;
+                       file = loc.SourceFile;
+                       row = loc.Row;
+                       column = loc.Column;
+               }
+
+               public override string ToString ()
+               {
+                       return string.Format ("Token '{0}' at {1},{2}", Value, row, column);
+               }
+
+               public Location Location
+               {
+                       get { return new Location (file, row, column); }
+               }
+
+               public string Value
+               {
+                       get { return value; }
+               }
+       }
+
        /// <summary>
        ///    Tokenizer for C# source code. 
        /// </summary>
-
        public class Tokenizer : yyParser.yyInput
        {
                class KeywordEntry<T>
@@ -68,40 +105,6 @@ namespace Mono.CSharp
                        }
                }
 
-               //
-               // This class has to be used in the parser only, it reuses token
-               // details after each parse
-               //
-               public class LocatedToken
-               {
-                       public int row, column;
-                       public string value;
-
-                       public LocatedToken ()
-                       {
-                       }
-
-                       public LocatedToken (string value, Location loc)
-                       {
-                               this.value = value;
-                               row = loc.Row;
-                               column = loc.Column;
-                       }
-
-                       public override string ToString ()
-                       {
-                               return string.Format ("Token '{0}' at {1},{2}", Value, row, column);
-                       }
-                       
-                       public Location Location {
-                               get { return new Location (row, column); }
-                       }
-
-                       public string Value {
-                               get { return value; }
-                       }
-               }
-
                public class LocatedTokenBuffer
                {
                        readonly LocatedToken[] buffer;
@@ -117,17 +120,12 @@ namespace Mono.CSharp
                                this.buffer = buffer ?? new LocatedToken[0];
                        }
 
-                       public LocatedToken Create (int row, int column)
+                       public LocatedToken Create (SourceFile file, int row, int column)
                        {
-                               return Create (null, row, column);
+                               return Create (null, file, row, column);
                        }
 
-                       public LocatedToken Create (string value, Location loc)
-                       {
-                               return Create (value, loc.Row, loc.Column);
-                       }
-
-                       public LocatedToken Create (string value, int row, int column)
+                       public LocatedToken Create (string value, SourceFile file, int row, int column)
                        {
                                //
                                // TODO: I am not very happy about the logic but it's the best
@@ -150,6 +148,7 @@ namespace Mono.CSharp
                                        ++pos;
                                }
                                entry.value = value;
+                               entry.file = file;
                                entry.row = row;
                                entry.column = column;
                                return entry;
@@ -159,9 +158,9 @@ namespace Mono.CSharp
                        // Used for token not required by expression evaluator
                        //
                        [Conditional ("FULL_AST")]
-                       public void CreateOptional (int row, int col, ref object token)
+                       public void CreateOptional (SourceFile file, int row, int col, ref object token)
                        {
-                               token = Create (row, col);
+                               token = Create (file, row, col);
                        }
                }
 
@@ -200,7 +199,7 @@ namespace Mono.CSharp
                readonly int tab_size;
                bool handle_get_set = false;
                bool handle_remove_add = false;
-               bool handle_where = false;
+               bool handle_where;
                bool handle_typeof = false;
                bool lambda_arguments_parsing;
                List<Location> escaped_identifiers;
@@ -251,6 +250,9 @@ namespace Mono.CSharp
                public const int EvalCompilationUnitParserCharacter = 0x100001;
                public const int EvalUsingDeclarationsParserCharacter = 0x100002;
                public const int DocumentationXref = 0x100003;
+
+               const int UnicodeLS = 0x2028;
+               const int UnicodePS = 0x2029;
                
                //
                // XML documentation buffer. The save point is used to divide
@@ -446,8 +448,6 @@ namespace Mono.CSharp
                        doc_processing = context.Settings.DocumentationFile != null;
 
                        tab_size = context.Settings.TabSize;
-
-                       Mono.CSharp.Location.Push (current_source);
                }
                
                public void PushPosition ()
@@ -701,7 +701,7 @@ namespace Mono.CSharp
                                }
                                break;
                        case Token.WHERE:
-                               if (!handle_where && !query_parsing)
+                               if (!(handle_where && current_token != Token.COLON) && !query_parsing)
                                        res = -1;
                                break;
                        case Token.FROM:
@@ -710,7 +710,7 @@ namespace Mono.CSharp
                                // followed by any token except ; , =
                                // 
                                if (!query_parsing) {
-                                       if (lambda_arguments_parsing) {
+                                       if (lambda_arguments_parsing || parsing_block == 0) {
                                                res = -1;
                                                break;
                                        }
@@ -733,7 +733,7 @@ namespace Mono.CSharp
                                        case Token.UINT:
                                        case Token.ULONG:
                                                next_token = xtoken ();
-                                               if (next_token == Token.SEMICOLON || next_token == Token.COMMA || next_token == Token.EQUALS)
+                                               if (next_token == Token.SEMICOLON || next_token == Token.COMMA || next_token == Token.EQUALS || next_token == Token.ASSIGN)
                                                        goto default;
                                                
                                                res = Token.FROM_FIRST;
@@ -773,6 +773,7 @@ namespace Mono.CSharp
                        case Token.NAMESPACE:
                                // TODO: some explanation needed
                                check_incorrect_doc_comment ();
+                               parsing_modifiers = false;
                                break;
                                
                        case Token.PARTIAL:
@@ -806,8 +807,17 @@ namespace Mono.CSharp
                                        Report.Error (267, Location,
                                                "The `partial' modifier can be used only immediately before `class', `struct', `interface', or `void' keyword");
                                        return token ();
-                               }                                       
+                               }
 
+                               // HACK: A token is not a keyword so we need to restore identifiers buffer
+                               // which has been overwritten before we grabbed the identifier
+                               id_builder[0] = 'p';
+                               id_builder[1] = 'a';
+                               id_builder[2] = 'r';
+                               id_builder[3] = 't';
+                               id_builder[4] = 'i';
+                               id_builder[5] = 'a';
+                               id_builder[6] = 'l';
                                res = -1;
                                break;
 
@@ -830,12 +840,16 @@ namespace Mono.CSharp
                                        case Token.IDENTIFIER:
                                                PushPosition ();
                                                xtoken ();
-                                               if (xtoken () != Token.ARROW)
-                                                       res = -1;
+                                               if (xtoken () != Token.ARROW) {
+                                                       PopPosition ();
+                                                       goto default;
+                                               }
 
                                                PopPosition ();
                                                break;
                                        default:
+                                               // peek_token could overwrite id_buffer
+                                               id_builder [0] = 'a'; id_builder [1] = 's'; id_builder [2] = 'y'; id_builder [3] = 'n'; id_builder [4] = 'c';
                                                res = -1;
                                                break;
                                        }
@@ -894,7 +908,7 @@ namespace Mono.CSharp
 
                public Location Location {
                        get {
-                               return new Location (ref_line, col);
+                               return new Location (current_source, ref_line, col);
                        }
                }
 
@@ -954,8 +968,12 @@ namespace Mono.CSharp
                                        //
                                        // Expression inside parens is single type, (int[])
                                        //
-                                       if (is_type)
+                                       if (is_type) {
+                                               if (current_token == Token.SEMICOLON)
+                                                       return Token.OPEN_PARENS;
+
                                                return Token.OPEN_PARENS_CAST;
+                                       }
 
                                        //
                                        // Expression is possible cast, look at next token, (T)null
@@ -1012,6 +1030,7 @@ namespace Mono.CSharp
                                        continue;
 
                                case Token.IDENTIFIER:
+                               case Token.AWAIT:
                                        switch (ptoken) {
                                        case Token.DOT:
                                                if (bracket_level == 0) {
@@ -1107,9 +1126,14 @@ namespace Mono.CSharp
                start:
                        int the_token = token ();
                        if (the_token == Token.OPEN_BRACKET) {
-                               do {
+                               while (true) {
                                        the_token = token ();
-                               } while (the_token != Token.CLOSE_BRACKET);
+                                       if (the_token == Token.EOF)
+                                               return true;
+
+                                       if (the_token == Token.CLOSE_BRACKET)
+                                               break;
+                               }
                                the_token = token ();
                        } else if (the_token == Token.IN || the_token == Token.OUT) {
                                the_token = token ();
@@ -1248,6 +1272,8 @@ namespace Mono.CSharp
                        case Token.OPEN_BRACKET:
                        case Token.OP_GENERICS_GT:
                        case Token.INTERR:
+                       case Token.OP_COALESCING:
+                       case Token.COLON:
                                next_token = Token.INTERR_NULLABLE;
                                break;
                                
@@ -1386,7 +1412,7 @@ namespace Mono.CSharp
                                                        // if we have not seen anything in between
                                                        // report this error
                                                        //
-                                                       Report.Warning (78, 4, Location, "The 'l' suffix is easily confused with the digit '1' (use 'L' for clarity)");
+                                                       Report.Warning (78, 4, Location, "The `l' suffix is easily confused with the digit `1' (use `L' for clarity)");
                                                }
 
                                                goto case 'L';
@@ -1542,13 +1568,13 @@ namespace Mono.CSharp
                //
                // Invoked if we know we have .digits or digits
                //
-               int is_number (int c)
+               int is_number (int c, bool dotLead)
                {
                        ILiteralConstant res;
 
 #if FULL_AST
                        int read_start = reader.Position - 1;
-                       if (c == '.') {
+                       if (dotLead) {
                                //
                                // Caller did peek_char
                                //
@@ -1558,7 +1584,7 @@ namespace Mono.CSharp
                        number_pos = 0;
                        var loc = Location;
 
-                       if (c >= '0' && c <= '9'){
+                       if (!dotLead){
                                if (c == '0'){
                                        int peek = peek_char ();
 
@@ -1572,7 +1598,7 @@ namespace Mono.CSharp
                                        }
                                }
                                decimal_digits (c);
-                               c = get_char ();
+                               c = peek_char ();
                        }
 
                        //
@@ -1581,9 +1607,12 @@ namespace Mono.CSharp
                        //
                        bool is_real = false;
                        if (c == '.'){
+                               if (!dotLead)
+                                       get_char ();
+
                                if (decimal_digits ('.')){
                                        is_real = true;
-                                       c = get_char ();
+                                       c = peek_char ();
                                } else {
                                        putback ('.');
                                        number_pos--;
@@ -1598,6 +1627,7 @@ namespace Mono.CSharp
                        
                        if (c == 'e' || c == 'E'){
                                is_real = true;
+                               get_char ();
                                if (number_pos == MaxNumberLength)
                                        Error_NumericConstantTooLong ();
                                number_builder [number_pos++] = (char) c;
@@ -1620,18 +1650,17 @@ namespace Mono.CSharp
                                }
                                        
                                decimal_digits (c);
-                               c = get_char ();
+                               c = peek_char ();
                        }
 
                        var type = real_type_suffix (c);
                        if (type == TypeCode.Empty && !is_real) {
-                               putback (c);
                                res = adjust_int (c, loc);
                        } else {
                                is_real = true;
 
-                               if (type == TypeCode.Empty) {
-                                       putback (c);
+                               if (type != TypeCode.Empty) {
+                                       get_char ();
                                }
 
                                res = adjust_real (type, loc);
@@ -1780,18 +1809,25 @@ namespace Mono.CSharp
                                x = reader.Read ();
                        }
                        
-                       if (x == '\r') {
-                               if (peek_char () == '\n') {
-                                       putback_char = -1;
-                               }
+                       if (x <= 13) {
+                               if (x == '\r') {
+                                       if (peek_char () == '\n') {
+                                               putback_char = -1;
+                                       }
 
-                               x = '\n';
-                               advance_line ();
-                       } else if (x == '\n') {
+                                       x = '\n';
+                                       advance_line ();
+                               } else if (x == '\n') {
+                                       advance_line ();
+                               } else {
+                                       col++;
+                               }
+                       } else if (x >= UnicodeLS && x <= UnicodePS) {
                                advance_line ();
                        } else {
                                col++;
                        }
+
                        return x;
                }
 
@@ -1823,7 +1859,7 @@ namespace Mono.CSharp
                                throw new InternalErrorException (string.Format ("Secondary putback [{0}] putting back [{1}] is not allowed", (char)putback_char, (char) c), Location);
                        }
 
-                       if (c == '\n' || col == 0) {
+                       if (c == '\n' || col == 0 || (c >= UnicodeLS && c <= UnicodePS)) {
                                // It won't happen though.
                                line--;
                                ref_line--;
@@ -1905,7 +1941,7 @@ namespace Mono.CSharp
                        int has_identifier_argument = (int)(cmd & PreprocessorDirective.RequiresArgument);
                        int pos = 0;
 
-                       while (c != -1 && c != '\n') {
+                       while (c != -1 && c != '\n' && c != UnicodeLS && c != UnicodePS) {
                                if (c == '\\' && has_identifier_argument >= 0) {
                                        if (has_identifier_argument != 0) {
                                                has_identifier_argument = 1;
@@ -1932,10 +1968,7 @@ namespace Mono.CSharp
                                        // Eat single-line comments
                                        //
                                        get_char ();
-                                       do {
-                                               c = get_char ();
-                                       } while (c != -1 && c != '\n');
-
+                                       ReadToEndOfLine ();
                                        break;
                                }
 
@@ -1980,7 +2013,6 @@ namespace Mono.CSharp
                                }
 
                                ref_line = line;
-                               Location.Push (current_source);
                                return true;
                        }
 
@@ -1998,10 +2030,7 @@ namespace Mono.CSharp
                                //
                                // Eat any remaining characters to continue parsing on next line
                                //
-                               while (c != -1 && c != '\n') {
-                                       c = get_char ();
-                               }
-
+                               ReadToEndOfLine ();
                                return false;
                        }
 
@@ -2010,10 +2039,7 @@ namespace Mono.CSharp
                                //
                                // Eat any remaining characters to continue parsing on next line
                                //
-                               while (c != -1 && c != '\n') {
-                                       c = get_char ();
-                               }
-
+                               ReadToEndOfLine ();
                                return new_line != 0;
                        }
 
@@ -2027,13 +2053,11 @@ namespace Mono.CSharp
                                c = 0;
                        }
 
-                       if (c != '\n' && c != '/' && c != '"') {
+                       if (c != '\n' && c != '/' && c != '"' && c != UnicodeLS && c != UnicodePS) {
                                //
                                // Eat any remaining characters to continue parsing on next line
                                //
-                               while (c != -1 && c != '\n') {
-                                       c = get_char ();
-                               }
+                               ReadToEndOfLine ();
 
                                Report.Error (1578, loc, "Filename, single-line comment or end-of-line expected");
                                return true;
@@ -2049,16 +2073,15 @@ namespace Mono.CSharp
                                }
                        }
 
-                       if (c == '\n') {
+                       if (c == '\n' || c == UnicodeLS || c == UnicodePS) {
+
                        } else if (c == '/') {
                                ReadSingleLineComment ();
                        } else {
                                //
                                // Eat any remaining characters to continue parsing on next line
                                //
-                               while (c != -1 && c != '\n') {
-                                       c = get_char ();
-                               }
+                               ReadToEndOfLine ();
 
                                Error_EndLineExpected ();
                                return true;
@@ -2067,7 +2090,6 @@ namespace Mono.CSharp
                        if (new_file_name != null) {
                                current_source = context.LookupFile (source_file, new_file_name);
                                source_file.AddIncludeFile (current_source);
-                               Location.Push (current_source);
                        }
 
                        if (!hidden_block_start.IsNull) {
@@ -2294,7 +2316,7 @@ namespace Mono.CSharp
                string TokenizeFileName (ref int c)
                {
                        var string_builder = new StringBuilder ();
-                       while (c != -1 && c != '\n') {
+                       while (c != -1 && c != '\n' && c != UnicodeLS && c != UnicodePS) {
                                c = get_char ();
                                if (c == '"') {
                                        c = get_char ();
@@ -2342,25 +2364,28 @@ namespace Mono.CSharp
                                        Report.Warning (1692, 1, Location, "Invalid number");
 
                                        // Read everything till the end of the line or file
-                                       do {
-                                               c = get_char ();
-                                       } while (c != -1 && c != '\n');
+                                       ReadToEndOfLine ();
                                }
                        }
 
                        return number;
                }
 
+               void ReadToEndOfLine ()
+               {
+                       int c;
+                       do {
+                               c = get_char ();
+                       } while (c != -1 && c != '\n' && c != UnicodeLS && c != UnicodePS);
+               }
+
                void ReadSingleLineComment ()
                {
                        if (peek_char () != '/')
                                Report.Warning (1696, 1, Location, "Single-line comment or end-of-line expected");
 
                        // Read everything till the end of the line or file
-                       int c;
-                       do {
-                               c = get_char ();
-                       } while (c != -1 && c != '\n');
+                       ReadToEndOfLine ();
                }
 
                /// <summary>
@@ -2386,7 +2411,7 @@ namespace Mono.CSharp
 
                                                var loc = Location;
 
-                                               if (c == '\n' || c == '/') {
+                                               if (c == '\n' || c == '/' || c == UnicodeLS || c == UnicodePS) {
                                                        if (c == '/')
                                                                ReadSingleLineComment ();
 
@@ -2412,7 +2437,7 @@ namespace Mono.CSharp
                                                                                Report.RegisterWarningRegion (loc).WarningEnable (loc, code, context);
                                                                        }
                                                                }
-                                                       } while (code >= 0 && c != '\n' && c != -1);
+                                                       } while (code >= 0 && c != '\n' && c != -1 && c != UnicodeLS && c != UnicodePS);
                                                }
 
                                                return;
@@ -2420,6 +2445,10 @@ namespace Mono.CSharp
                                }
 
                                Report.Warning (1634, 1, Location, "Expected disable or restore");
+
+                               // Eat any remaining characters on the line
+                               ReadToEndOfLine ();
+
                                return;
                        }
 
@@ -2791,7 +2820,8 @@ namespace Mono.CSharp
                                }
                        case PreprocessorDirective.Define:
                                if (any_token_seen){
-                                       Error_TokensSeen ();
+                                       if (caller_is_taking)
+                                               Error_TokensSeen ();
                                        return caller_is_taking;
                                }
                                PreProcessDefinition (true, arg, caller_is_taking);
@@ -2799,7 +2829,8 @@ namespace Mono.CSharp
 
                        case PreprocessorDirective.Undef:
                                if (any_token_seen){
-                                       Error_TokensSeen ();
+                                       if (caller_is_taking)
+                                               Error_TokensSeen ();
                                        return caller_is_taking;
                                }
                                PreProcessDefinition (false, arg, caller_is_taking);
@@ -2857,8 +2888,17 @@ namespace Mono.CSharp
 #endif
 
                        while (true){
-                               c = get_char ();
+                               // Cannot use get_char because of \r in quoted strings
+                               if (putback_char != -1) {
+                                       c = putback_char;
+                                       putback_char = -1;
+                               } else {
+                                       c = reader.Read ();
+                               }
+
                                if (c == '"') {
+                                       ++col;
+
                                        if (quoted && peek_char () == '"') {
                                                if (pos == value_builder.Length)
                                                        Array.Resize (ref value_builder, pos * 2);
@@ -2887,13 +2927,23 @@ namespace Mono.CSharp
                                        return Token.LITERAL;
                                }
 
-                               if (c == '\n') {
+                               if (c == '\n' || c == UnicodeLS || c == UnicodePS) {
                                        if (!quoted) {
                                                Report.Error (1010, Location, "Newline in constant");
+
+                                               advance_line ();
+
+                                               // Don't add \r to string literal
+                                               if (pos > 1 && value_builder [pos - 1] == '\r')
+                                                       --pos;
+
                                                val = new StringLiteral (context.BuiltinTypes, new string (value_builder, 0, pos), start_location);
                                                return Token.LITERAL;
                                        }
+
+                                       advance_line ();
                                } else if (c == '\\' && !quoted) {
+                                       ++col;
                                        int surrogate;
                                        c = escape (c, out surrogate);
                                        if (c == -1)
@@ -2908,6 +2958,8 @@ namespace Mono.CSharp
                                } else if (c == -1) {
                                        Report.Error (1039, Location, "Unterminated string literal");
                                        return Token.EOF;
+                               } else {
+                                       ++col;
                                }
 
                                if (pos == value_builder.Length)
@@ -2995,13 +3047,13 @@ namespace Mono.CSharp
                        if (id_builder [0] >= '_' && !quoted) {
                                int keyword = GetKeyword (id_builder, pos);
                                if (keyword != -1) {
-                                       val = ltb.Create (keyword == Token.AWAIT ? "await" : null, ref_line, column);
+                                       val = ltb.Create (keyword == Token.AWAIT ? "await" : null, current_source, ref_line, column);
                                        return keyword;
                                }
                        }
 
                        string s = InternIdentifier (id_builder, pos);
-                       val = ltb.Create (s, ref_line, column);
+                       val = ltb.Create (s, current_source, ref_line, column);
                        if (quoted && parsing_attribute_section)
                                AddEscapedIdentifier (((LocatedToken) val).Location);
 
@@ -3072,17 +3124,17 @@ namespace Mono.CSharp
                                        return consume_identifier (c);
 
                                case '{':
-                                       val = ltb.Create (ref_line, col);
+                                       val = ltb.Create (current_source, ref_line, col);
                                        return Token.OPEN_BRACE;
                                case '}':
-                                       val = ltb.Create (ref_line, col);
+                                       val = ltb.Create (current_source, ref_line, col);
                                        return Token.CLOSE_BRACE;
                                case '[':
                                        // To block doccomment inside attribute declaration.
                                        if (doc_state == XmlCommentState.Allowed)
                                                doc_state = XmlCommentState.NotAllowed;
 
-                                       val = ltb.Create (ref_line, col);
+                                       val = ltb.Create (current_source, ref_line, col);
 
                                        if (parsing_block == 0 || lambda_arguments_parsing)
                                                return Token.OPEN_BRACKET;
@@ -3098,6 +3150,8 @@ namespace Mono.CSharp
                                        case '\v':
                                        case '\r':
                                        case '\n':
+                                       case UnicodeLS:
+                                       case UnicodePS:
                                        case '/':
                                                next = peek_token ();
                                                if (next == Token.COMMA || next == Token.CLOSE_BRACKET)
@@ -3108,10 +3162,10 @@ namespace Mono.CSharp
                                                return Token.OPEN_BRACKET_EXPR;
                                        }
                                case ']':
-                                       ltb.CreateOptional (ref_line, col, ref val);
+                                       ltb.CreateOptional (current_source, ref_line, col, ref val);
                                        return Token.CLOSE_BRACKET;
                                case '(':
-                                       val = ltb.Create (ref_line, col);
+                                       val = ltb.Create (current_source, ref_line, col);
                                        //
                                        // An expression versions of parens can appear in block context only
                                        //
@@ -3128,6 +3182,7 @@ namespace Mono.CSharp
                                                case Token.FOREACH:
                                                case Token.TYPEOF:
                                                case Token.WHILE:
+                                               case Token.SWITCH:
                                                case Token.USING:
                                                case Token.DEFAULT:
                                                case Token.DELEGATE:
@@ -3156,29 +3211,29 @@ namespace Mono.CSharp
 
                                        return Token.OPEN_PARENS;
                                case ')':
-                                       ltb.CreateOptional (ref_line, col, ref val);
+                                       ltb.CreateOptional (current_source, ref_line, col, ref val);
                                        return Token.CLOSE_PARENS;
                                case ',':
-                                       ltb.CreateOptional (ref_line, col, ref val);
+                                       ltb.CreateOptional (current_source, ref_line, col, ref val);
                                        return Token.COMMA;
                                case ';':
-                                       ltb.CreateOptional (ref_line, col, ref val);
+                                       ltb.CreateOptional (current_source, ref_line, col, ref val);
                                        return Token.SEMICOLON;
                                case '~':
-                                       val = ltb.Create (ref_line, col);
+                                       val = ltb.Create (current_source, ref_line, col);
                                        return Token.TILDE;
                                case '?':
-                                       val = ltb.Create (ref_line, col);
+                                       val = ltb.Create (current_source, ref_line, col);
                                        return TokenizePossibleNullableType ();
                                case '<':
-                                       val = ltb.Create (ref_line, col);
+                                       val = ltb.Create (current_source, ref_line, col);
                                        if (parsing_generic_less_than++ > 0)
                                                return Token.OP_GENERICS_LT;
 
                                        return TokenizeLessThan ();
 
                                case '>':
-                                       val = ltb.Create (ref_line, col);
+                                       val = ltb.Create (current_source, ref_line, col);
                                        d = peek_char ();
 
                                        if (d == '='){
@@ -3205,7 +3260,7 @@ namespace Mono.CSharp
                                        return Token.OP_GT;
 
                                case '+':
-                                       val = ltb.Create (ref_line, col);
+                                       val = ltb.Create (current_source, ref_line, col);
                                        d = peek_char ();
                                        if (d == '+') {
                                                d = Token.OP_INC;
@@ -3218,7 +3273,7 @@ namespace Mono.CSharp
                                        return d;
 
                                case '-':
-                                       val = ltb.Create (ref_line, col);
+                                       val = ltb.Create (current_source, ref_line, col);
                                        d = peek_char ();
                                        if (d == '-') {
                                                d = Token.OP_DEC;
@@ -3233,7 +3288,7 @@ namespace Mono.CSharp
                                        return d;
 
                                case '!':
-                                       val = ltb.Create (ref_line, col);
+                                       val = ltb.Create (current_source, ref_line, col);
                                        if (peek_char () == '='){
                                                get_char ();
                                                return Token.OP_NE;
@@ -3241,7 +3296,7 @@ namespace Mono.CSharp
                                        return Token.BANG;
 
                                case '=':
-                                       val = ltb.Create (ref_line, col);
+                                       val = ltb.Create (current_source, ref_line, col);
                                        d = peek_char ();
                                        if (d == '='){
                                                get_char ();
@@ -3255,7 +3310,7 @@ namespace Mono.CSharp
                                        return Token.ASSIGN;
 
                                case '&':
-                                       val = ltb.Create (ref_line, col);
+                                       val = ltb.Create (current_source, ref_line, col);
                                        d = peek_char ();
                                        if (d == '&'){
                                                get_char ();
@@ -3268,7 +3323,7 @@ namespace Mono.CSharp
                                        return Token.BITWISE_AND;
 
                                case '|':
-                                       val = ltb.Create (ref_line, col);
+                                       val = ltb.Create (current_source, ref_line, col);
                                        d = peek_char ();
                                        if (d == '|'){
                                                get_char ();
@@ -3281,7 +3336,7 @@ namespace Mono.CSharp
                                        return Token.BITWISE_OR;
 
                                case '*':
-                                       val = ltb.Create (ref_line, col);
+                                       val = ltb.Create (current_source, ref_line, col);
                                        if (peek_char () == '='){
                                                get_char ();
                                                return Token.OP_MULT_ASSIGN;
@@ -3291,7 +3346,7 @@ namespace Mono.CSharp
                                case '/':
                                        d = peek_char ();
                                        if (d == '='){
-                                               val = ltb.Create (ref_line, col);
+                                               val = ltb.Create (current_source, ref_line, col);
                                                get_char ();
                                                return Token.OP_DIV_ASSIGN;
                                        }
@@ -3315,7 +3370,7 @@ namespace Mono.CSharp
                                                        }
                                                }
 
-                                               while ((d = get_char ()) != -1 && d != '\n');
+                                               ReadToEndOfLine ();
 
                                                any_token_seen |= tokens_seen;
                                                tokens_seen = false;
@@ -3353,7 +3408,7 @@ namespace Mono.CSharp
                                                        if (docAppend)
                                                                xml_comment_buffer.Append ((char) d);
                                                        
-                                                       if (d == '\n'){
+                                                       if (d == '\n' || d == UnicodeLS || d == UnicodePS){
                                                                any_token_seen |= tokens_seen;
                                                                tokens_seen = false;
                                                                // 
@@ -3370,11 +3425,11 @@ namespace Mono.CSharp
                                                        update_formatted_doc_comment (current_comment_start);
                                                continue;
                                        }
-                                       val = ltb.Create (ref_line, col);
+                                       val = ltb.Create (current_source, ref_line, col);
                                        return Token.DIV;
 
                                case '%':
-                                       val = ltb.Create (ref_line, col);
+                                       val = ltb.Create (current_source, ref_line, col);
                                        if (peek_char () == '='){
                                                get_char ();
                                                return Token.OP_MOD_ASSIGN;
@@ -3382,7 +3437,7 @@ namespace Mono.CSharp
                                        return Token.PERCENT;
 
                                case '^':
-                                       val = ltb.Create (ref_line, col);
+                                       val = ltb.Create (current_source, ref_line, col);
                                        if (peek_char () == '='){
                                                get_char ();
                                                return Token.OP_XOR_ASSIGN;
@@ -3390,7 +3445,7 @@ namespace Mono.CSharp
                                        return Token.CARRET;
 
                                case ':':
-                                       val = ltb.Create (ref_line, col);
+                                       val = ltb.Create (current_source, ref_line, col);
                                        if (peek_char () == ':') {
                                                get_char ();
                                                return Token.DOUBLE_COLON;
@@ -3400,9 +3455,11 @@ namespace Mono.CSharp
                                case '0': case '1': case '2': case '3': case '4':
                                case '5': case '6': case '7': case '8': case '9':
                                        tokens_seen = true;
-                                       return is_number (c);
+                                       return is_number (c, false);
 
                                case '\n': // white space
+                               case UnicodeLS:
+                               case UnicodePS:
                                        any_token_seen |= tokens_seen;
                                        tokens_seen = false;
                                        comments_seen = false;
@@ -3412,9 +3469,9 @@ namespace Mono.CSharp
                                        tokens_seen = true;
                                        d = peek_char ();
                                        if (d >= '0' && d <= '9')
-                                               return is_number (c);
+                                               return is_number (c, true);
 
-                                       ltb.CreateOptional (ref_line, col, ref val);
+                                       ltb.CreateOptional (current_source, ref_line, col, ref val);
                                        return Token.DOT;
                                
                                case '#':
@@ -3439,7 +3496,7 @@ namespace Mono.CSharp
                                                        continue;
                                                }
 
-                                               if (c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '\v' )
+                                               if (c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '\v' || c == UnicodeLS || c == UnicodePS)
                                                        continue;
 
                                                if (c == '#') {
@@ -3523,7 +3580,7 @@ namespace Mono.CSharp
                                return Token.LITERAL;
                        }
 
-                       if (c == '\n') {
+                       if (c == '\n' || c == UnicodeLS || c == UnicodePS) {
                                Report.Error (1010, start_location, "Newline in constant");
                                return Token.ERROR;
                        }
@@ -3544,7 +3601,7 @@ namespace Mono.CSharp
 
                                // Try to recover, read until newline or next "'"
                                while ((c = get_char ()) != -1) {
-                                       if (c == '\n' || c == '\'')
+                                       if (c == '\n' || c == '\'' || c == UnicodeLS || c == UnicodePS)
                                                break;
                                }
                        }