TypeContainer current_container;
DeclSpace current_class;
- IIteratorContainer iterator_container;
+ IAnonymousHost anonymous_host;
/// <summary>
/// Current block is used to add statements as we find
Delegate current_delegate;
+ GenericMethod current_generic_method;
+ AnonymousMethodExpression current_anonymous_method;
+
/// <summary>
/// This is used by the unary_expression code to resolve
/// a name against a parameter.
/// Hack to help create non-typed array initializer
/// </summary>
public static Expression current_array_type;
+ Expression pushed_current_array_type;
/// <summary>
/// Used to determine if we are parsing the get/set pair
/// of an indexer or a property
/// </summmary>
- bool parsing_indexer;
+ bool parsing_indexer;
+
+ bool parsing_anonymous_method;
///
/// An out-of-band stack.
current_namespace = new NamespaceEntry (
current_namespace, file, name.GetName ());
+ current_class = current_namespace.SlaveDeclSpace;
+ current_container = current_class.PartialContainer;
}
namespace_body opt_semicolon
{
current_namespace = current_namespace.Parent;
+ current_class = current_namespace.SlaveDeclSpace;
+ current_container = current_class.PartialContainer;
}
;
method_declaration
: method_header {
- iterator_container = (IIteratorContainer) $1;
+ anonymous_host = (IAnonymousHost) $1;
if (RootContext.Documentation != null)
Lexer.doc_state = XmlCommentState.NotAllowed;
}
method.Block = (ToplevelBlock) $3;
current_container.AddMethod (method);
+ anonymous_host = null;
+ current_generic_method = null;
current_local_parameters = null;
- iterator_container = null;
if (RootContext.Documentation != null)
Lexer.doc_state = XmlCommentState.Allowed;
method = new Method (current_class, generic, (Expression) $3, (int) $2, false,
name, (Parameters) $6, (Attributes) $1);
+ anonymous_host = method;
current_local_parameters = (Parameters) $6;
+ current_generic_method = generic;
if (RootContext.Documentation != null)
method.DocComment = Lexer.consume_doc_comment ();
method = new Method (current_class, generic, TypeManager.system_void_expr,
(int) $2, false, name, (Parameters) $6, (Attributes) $1);
+ anonymous_host = method;
current_local_parameters = (Parameters) $6;
+ current_generic_method = generic;
if (RootContext.Documentation != null)
method.DocComment = Lexer.consume_doc_comment ();
current_local_parameters = indexer_parameters;
lexer.PropertyParsing = false;
- iterator_container = SimpleIteratorContainer.GetSimple ();
+ anonymous_host = SimpleAnonymousHost.GetSimple ();
}
accessor_body
{
current_local_parameters = null;
lexer.PropertyParsing = true;
- if (SimpleIteratorContainer.Simple.Yields)
- accessor.SetYields ();
-
- iterator_container = null;
+ SimpleAnonymousHost.Simple.Propagate (accessor);
+ anonymous_host = null;
if (RootContext.Documentation != null)
if (Lexer.doc_state == XmlCommentState.Error)
lexer.PropertyParsing = false;
- iterator_container = SimpleIteratorContainer.GetSimple ();
+ anonymous_host = SimpleAnonymousHost.GetSimple ();
}
accessor_body
{
current_local_parameters = null;
lexer.PropertyParsing = true;
- if (SimpleIteratorContainer.Simple.Yields)
- accessor.SetYields ();
-
- iterator_container = null;
+ SimpleAnonymousHost.Simple.Propagate (accessor);
+ anonymous_host = null;
if (RootContext.Documentation != null
&& Lexer.doc_state == XmlCommentState.Error)
operator_declaration
: opt_attributes opt_modifiers operator_declarator
{
- iterator_container = SimpleIteratorContainer.GetSimple ();
+ anonymous_host = SimpleAnonymousHost.GetSimple ();
}
operator_body
{
Lexer.doc_state = XmlCommentState.Allowed;
}
- if (SimpleIteratorContainer.Simple.Yields)
- op.SetYields ();
+ SimpleAnonymousHost.Simple.Propagate (op);
+ anonymous_host = null;
// Note again, checking is done in semantic analysis
current_container.AddOperator (op);
current_local_parameters = null;
- iterator_container = null;
}
;
LocatedToken lt = (LocatedToken) $1;
$$ = new Constructor (current_class, lt.Value, 0, (Parameters) $4,
(ConstructorInitializer) $7, lt.Location);
+
+ anonymous_host = (IAnonymousHost) $$;
}
;
parsing_indexer = true;
indexer_parameters = decl.param_list;
- iterator_container = SimpleIteratorContainer.GetSimple ();
+ anonymous_host = SimpleAnonymousHost.GetSimple ();
}
accessor_declarations
{
: OPEN_PARENS expression CLOSE_PARENS
{
$$ = $2;
- lexer.Deambiguate_CloseParens ();
+ lexer.Deambiguate_CloseParens ($$);
// After this, the next token returned is one of
- // CLOSE_PARENS_CAST, CLOSE_PARENS_NO_CAST, CLOSE_PARENS_OPEN_PARENS
+ // CLOSE_PARENS_CAST, CLOSE_PARENS_NO_CAST (CLOSE_PARENS), CLOSE_PARENS_OPEN_PARENS
// or CLOSE_PARENS_MINUS.
}
| OPEN_PARENS expression error { CheckToken (1026, yyToken, "Expecting ')'", lexer.Location); }
: parenthesized_expression_0 CLOSE_PARENS_NO_CAST
{
$$ = $1;
- }
+ }
+ | parenthesized_expression_0 CLOSE_PARENS
+ {
+ $$ = $1;
+ }
| parenthesized_expression_0 CLOSE_PARENS_MINUS
{
// If a parenthesized expression is followed by a minus, we need to wrap
: primary_expression DOT IDENTIFIER opt_type_argument_list
{
LocatedToken lt = (LocatedToken) $3;
- $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4);
+ $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location);
}
| predefined_type DOT IDENTIFIER opt_type_argument_list
{
LocatedToken lt = (LocatedToken) $3;
- $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4);
+ // TODO: Location is wrong as some predefined types doesn't hold a location
+ $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location);
}
;
}
;
-void_pointer_expression
- : void_pointer_expression STAR
- {
- $$ = new ComposedCast ((Expression) $1, "*", lexer.Location);
- }
- | VOID STAR
- {
- $$ = new ComposedCast (TypeManager.system_void_expr, "*", lexer.Location);;
- }
- ;
-
typeof_expression
- : TYPEOF OPEN_PARENS VOID CLOSE_PARENS
- {
- $$ = new TypeOfVoid ((Location) $1);
+ : TYPEOF
+ {
+ pushed_current_array_type = current_array_type;
+ lexer.TypeOfParsing = true;
}
- | TYPEOF OPEN_PARENS void_pointer_expression CLOSE_PARENS
+ OPEN_PARENS type CLOSE_PARENS
{
- $$ = new TypeOf ((Expression) $3, (Location) $1);
- }
- | TYPEOF OPEN_PARENS
- {
- lexer.TypeOfParsing = true;
- }
- type CLOSE_PARENS
- {
- lexer.TypeOfParsing = false;
- $$ = new TypeOf ((Expression) $4, lexer.Location);
+ lexer.TypeOfParsing = false;
+ Expression type = (Expression)$4;
+ if (type == TypeManager.system_void_expr)
+ $$ = new TypeOfVoid ((Location) $1);
+ else
+ $$ = new TypeOf (type, (Location) $1);
+ current_array_type = pushed_current_array_type;
}
;
if (oob_stack == null)
oob_stack = new Stack (6);
+ oob_stack.Push (current_anonymous_method);
oob_stack.Push (current_local_parameters);
current_local_parameters = (Parameters)$2;
// Force the next block to be created as a ToplevelBlock
oob_stack.Push (current_block);
oob_stack.Push (top_current_block);
- current_block = null;
- }
+
+ Location loc = (Location) $1;
+ current_anonymous_method = new AnonymousMethodExpression (
+ current_anonymous_method, current_generic_method, current_container,
+ (Parameters) $2, (ToplevelBlock) top_current_block, loc);
+
+ parsing_anonymous_method = true;
+ }
block
{
Location loc = (Location) $1;
top_current_block = (Block) oob_stack.Pop ();
current_block = (Block) oob_stack.Pop ();
+
if (RootContext.Version == LanguageVersion.ISO_1){
Report.FeatureIsNotStandardized (loc, "anonymous methods");
$$ = null;
ToplevelBlock anon_block = (ToplevelBlock) $4;
anon_block.Parent = current_block;
- $$ = new AnonymousMethod (current_container, (Parameters) $2, (ToplevelBlock) top_current_block,
- anon_block, loc);
- }
- current_local_parameters = (Parameters) oob_stack.Pop ();
+
+ current_anonymous_method.Block = anon_block;
+ if ((anonymous_host != null) && (current_anonymous_method.Parent == null))
+ anonymous_host.AddAnonymousMethod (current_anonymous_method);
+
+ $$ = current_anonymous_method;
}
+
+ current_local_parameters = (Parameters) oob_stack.Pop ();
+ current_anonymous_method = (AnonymousMethodExpression) oob_stack.Pop ();
+ }
;
opt_anonymous_method_signature
{
$$ = new Cast ((Expression) $1, (Expression) $3);
}
+ | parenthesized_expression_0 CLOSE_PARENS_NO_CAST default_value_expression
+ {
+ $$ = new Cast ((Expression) $1, (Expression) $3);
+ }
| parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS cast_expression
{
$$ = new Cast ((Expression) $1, (Expression) $3);
}
| type_parameter_constraints_clauses type_parameter_constraints_clause {
ArrayList constraints = (ArrayList) $1;
+ Constraints new_constraint = (Constraints)$2;
+
+ foreach (Constraints c in constraints) {
+ if (new_constraint.TypeParameter == c.TypeParameter) {
+ Report.Error (409, new_constraint.Location, "A constraint clause has already been specified for type parameter `{0}'",
+ new_constraint.TypeParameter);
+ }
+ }
- constraints.Add ($2);
+ constraints.Add (new_constraint);
$$ = constraints;
}
;
block
: OPEN_BRACE
{
- if (current_block == null){
- current_block = new ToplevelBlock ((ToplevelBlock) top_current_block, current_local_parameters, (Location) $1);
+ if (parsing_anonymous_method) {
+ top_current_block = new ToplevelBlock (
+ current_block, current_local_parameters, current_generic_method,
+ (Location) $1);
+ if (current_block != null)
+ current_block.AddAnonymousChild ((ToplevelBlock) top_current_block);
+ current_block = top_current_block;
+ parsing_anonymous_method = false;
+ } else if (current_block == null) {
+ current_block = new ToplevelBlock (
+ (ToplevelBlock) top_current_block, current_local_parameters,
+ current_generic_method, (Location) $1);
top_current_block = current_block;
} else {
current_block = new Block (current_block, (Location) $1, Location.Null);
opt_switch_sections
: /* empty */
{
- Report.Error (1522, lexer.Location, "Empty switch block");
+ Report.Warning (1522, 1, lexer.Location, "Empty switch block");
+ $$ = new ArrayList ();
}
| switch_sections
;
Report.FeatureIsNotStandardized (lt.Location, "yield statement");
$$ = null;
}
- if (iterator_container == null){
+ if (anonymous_host == null){
Report.Error (204, lt.Location, "yield statement can only be used within a method, operator or property");
$$ = null;
} else {
- iterator_container.SetYields ();
+ anonymous_host.SetYields ();
$$ = new Yield ((Expression) $3, lt.Location);
}
}
Report.FeatureIsNotStandardized (lt.Location, "yield statement");
$$ = null;
}
- if (iterator_container == null){
+ if (anonymous_host == null){
Report.Error (204, lt.Location, "yield statement can only be used within a method, operator or property");
$$ = null;
} else {
- iterator_container.SetYields ();
+ anonymous_host.SetYields ();
$$ = new YieldBreak (lt.Location);
}
}
}
//
-// We use this when we do not have an object in advance that is an IIteratorContainer
+// We use this when we do not have an object in advance that is an IAnonymousHost
//
-public class SimpleIteratorContainer : IIteratorContainer {
- public bool Yields;
+public class SimpleAnonymousHost : IAnonymousHost {
+ public static readonly SimpleAnonymousHost Simple = new SimpleAnonymousHost ();
- public static SimpleIteratorContainer Simple = new SimpleIteratorContainer ();
+ bool yields;
+ ArrayList anonymous_methods;
- //
- // Reset and return
- //
- public static SimpleIteratorContainer GetSimple () {
- Simple.Yields = false;
+ public static SimpleAnonymousHost GetSimple () {
+ Simple.yields = false;
+ Simple.anonymous_methods = null;
return Simple;
}
- public void SetYields () { Yields = true; }
+ public void SetYields ()
+ {
+ yields = true;
+ }
+
+ public void AddAnonymousMethod (AnonymousMethodExpression anonymous)
+ {
+ if (anonymous_methods == null)
+ anonymous_methods = new ArrayList ();
+ anonymous_methods.Add (anonymous);
+ }
+
+ public void Propagate (IAnonymousHost real_host)
+ {
+ if (yields)
+ real_host.SetYields ();
+ if (anonymous_methods != null) {
+ foreach (AnonymousMethodExpression ame in anonymous_methods)
+ real_host.AddAnonymousMethod (ame);
+ }
+ }
}
// <summary>
public CSharpParser (SeekableStreamReader reader, SourceFile file, ArrayList defines)
{
- current_namespace = new NamespaceEntry (null, file, null);
this.name = file.Name;
this.file = file;
- current_container = RootContext.ToplevelTypes;
- // TODO: Make RootContext.ToplevelTypes a PartialContainer.
- current_class = current_container;
- current_container.NamespaceEntry = current_namespace;
+ current_namespace = new NamespaceEntry (null, file, null);
+ current_class = current_namespace.SlaveDeclSpace;
+ current_container = current_class.PartialContainer; // == RootContest.ToplevelTypes
lexer = new Tokenizer (reader, file, defines);
}
Console.WriteLine (e);
}
- RootContext.ToplevelTypes.NamespaceEntry = null;
+ if (RootContext.ToplevelTypes.NamespaceEntry != null)
+ throw new InternalErrorException ("who set it?");
}
static void CheckToken (int error, int yyToken, string msg, Location loc)