}
//
- // This class has to be used in the parser only, it reuses token
- // details after each parse
+ // This class has to be used by parser only, it reuses token
+ // details after each file parse completion
//
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 Location Location {
- get { return new Location (row, column); }
+ get { return new Location (file, row, column); }
}
public string Value {
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
++pos;
}
entry.value = value;
+ entry.file = file;
entry.row = row;
entry.column = column;
return entry;
// 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);
}
}
doc_processing = context.Settings.DocumentationFile != null;
tab_size = context.Settings.TabSize;
-
- Mono.CSharp.Location.Push (current_source);
}
public void PushPosition ()
PushPosition ();
xtoken ();
if (xtoken () != Token.ARROW)
- res = -1;
+ 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;
}
public Location Location {
get {
- return new Location (ref_line, col);
+ return new Location (current_source, ref_line, col);
}
}
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 ();
case Token.OPEN_BRACKET:
case Token.OP_GENERICS_GT:
case Token.INTERR:
+ case Token.OP_COALESCING:
next_token = Token.INTERR_NULLABLE;
break;
}
ref_line = line;
- Location.Push (current_source);
return true;
}
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) {
}
Report.Warning (1634, 1, Location, "Expected disable or restore");
+
+ // Eat any remaining characters on the line
+ while (c != '\n' && c != -1)
+ c = get_char ();
+
return;
}
#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);
if (c == '\n') {
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) {
int surrogate;
c = escape (c, out surrogate);
} else if (c == -1) {
Report.Error (1039, Location, "Unterminated string literal");
return Token.EOF;
+ } else {
+ ++col;
}
if (pos == value_builder.Length)
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);
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;
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
//
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 == '='){
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;
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;
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;
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 ();
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 ();
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 ();
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;
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;
}
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;
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;
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;
if (d >= '0' && d <= '9')
return is_number (c);
- ltb.CreateOptional (ref_line, col, ref val);
+ ltb.CreateOptional (current_source, ref_line, col, ref val);
return Token.DOT;
case '#':