Delegate current_delegate;
- GenericMethod current_generic_method;
AnonymousMethodExpression current_anonymous_method;
/// <summary>
Report.Error (531, method.Location, "`{0}': interface members cannot have a definition", method.GetSignatureForError ());
}
- current_generic_method = null;
current_local_parameters = null;
if (RootContext.Documentation != null)
method.GetSignatureForError ());
}
- current_generic_method = generic;
-
if (RootContext.Documentation != null)
method.DocComment = Lexer.consume_doc_comment ();
method = new Method (current_class, generic, TypeManager.system_void_expr,
modifiers, name, current_local_parameters, (Attributes) $1);
- current_generic_method = generic;
-
if (RootContext.Documentation != null)
method.DocComment = Lexer.consume_doc_comment ();
first_from_clause
: FROM_FIRST IDENTIFIER IN expression
{
- $$ = new Linq.QueryExpression (current_block, new Linq.QueryStartClause ((Expression)$4));
- var lt = (Tokenizer.LocatedToken) $2;
- current_block = new Linq.QueryBlock (compiler, current_block, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1));
+ current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
+
+ var lt = (Tokenizer.LocatedToken) $2;
+ $$ = new Linq.QueryExpression (new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$4, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1)));
}
| FROM_FIRST type IDENTIFIER IN expression
{
+ current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
+
var lt = (Tokenizer.LocatedToken) $3;
- $$ = new Linq.QueryExpression (current_block, new Linq.Cast ((FullNamedExpression)$2, (Expression)$5));
- current_block = new Linq.QueryBlock (compiler, current_block, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1));
+ $$ = new Linq.QueryExpression (
+ new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$5, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1)) {
+ IdentifierType = (FullNamedExpression)$2
+ }
+ );
}
;
nested_from_clause
: FROM IDENTIFIER IN expression
{
- $$ = new Linq.QueryExpression (current_block, new Linq.QueryStartClause ((Expression)$4));
- var lt = (Tokenizer.LocatedToken) $2;
- current_block = new Linq.QueryBlock (compiler, current_block, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1));
+ current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
+
+ var lt = (Tokenizer.LocatedToken) $2;
+ $$ = new Linq.QueryExpression (new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$4, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1)));
}
| FROM type IDENTIFIER IN expression
{
- $$ = new Linq.QueryExpression (current_block, new Linq.Cast ((FullNamedExpression)$2, (Expression)$5));
+ current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
+
var lt = (Tokenizer.LocatedToken) $3;
- current_block = new Linq.QueryBlock (compiler, current_block, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1));
+ $$ = new Linq.QueryExpression (
+ new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$5, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1)) {
+ IdentifierType = (FullNamedExpression)$2
+ }
+ );
}
;
current_block.SetEndLocation (lexer.Location);
current_block = current_block.Parent;
- ((Linq.QueryBlock)current_block).AddTransparentParameter (compiler, sn);
+ ((Linq.QueryBlock)current_block).AddRangeVariable (sn);
}
| FROM type IDENTIFIER IN
{
var lt = (Tokenizer.LocatedToken) $3;
var sn = new SimpleMemberName (lt.Value, lt.Location);
- FullNamedExpression type = (FullNamedExpression)$2;
-
- $$ = new Linq.SelectMany ((Linq.QueryBlock)current_block, sn, new Linq.Cast (type, (Expression)$6), GetLocation ($1));
+ $$ = new Linq.SelectMany ((Linq.QueryBlock)current_block, sn, (Expression)$6, GetLocation ($1)) {
+ IdentifierType = (FullNamedExpression)$2
+ };
current_block.SetEndLocation (lexer.Location);
current_block = current_block.Parent;
- ((Linq.QueryBlock)current_block).AddTransparentParameter (compiler, sn);
+ ((Linq.QueryBlock)current_block).AddRangeVariable (sn);
}
;
{
var lt = (Tokenizer.LocatedToken) $2;
var sn = new SimpleMemberName (lt.Value, lt.Location);
- $$ = new Linq.Let ((Linq.QueryBlock) current_block, current_container, sn, (Expression)$5, GetLocation ($1));
+ $$ = new Linq.Let ((Linq.QueryBlock) current_block, sn, (Expression)$5, GetLocation ($1));
current_block.SetEndLocation (lexer.Location);
current_block = current_block.Parent;
- ((Linq.QueryBlock)current_block).AddTransparentParameter (compiler, sn);
+ ((Linq.QueryBlock)current_block).AddRangeVariable (sn);
}
;
current_block.SetEndLocation (lexer.Location);
current_block = current_block.Parent;
- var lt = (Tokenizer.LocatedToken) $2;
- current_block = new Linq.QueryBlock (compiler, current_block, new SimpleMemberName (lt.Value, lt.Location), lexer.Location);
+ current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
}
expression opt_join_into
{
var sn = new SimpleMemberName (lt.Value, lt.Location);
SimpleMemberName sn2 = null;
- ToplevelBlock outer_selector = linq_clause_blocks.Pop ();
- ToplevelBlock block = linq_clause_blocks.Pop ();
+ var outer_selector = linq_clause_blocks.Pop ();
+ var block = linq_clause_blocks.Pop ();
if ($12 == null) {
- $$ = new Linq.Join (block, sn, (Expression)$5, outer_selector, current_block.Toplevel, GetLocation ($1));
+ $$ = new Linq.Join (block, sn, (Expression)$5, outer_selector, (Linq.QueryBlock) current_block, GetLocation ($1));
} else {
var lt2 = (Tokenizer.LocatedToken) $12;
sn2 = new SimpleMemberName (lt2.Value, lt2.Location);
- $$ = new Linq.GroupJoin (block, sn, (Expression)$5, outer_selector, current_block.Toplevel,
+ $$ = new Linq.GroupJoin (block, sn, (Expression)$5, outer_selector, (Linq.QueryBlock) current_block,
sn2, GetLocation ($1));
}
current_block.SetEndLocation (lexer.Location);
current_block = current_block.Parent;
- if (sn2 == null)
- ((Linq.QueryBlock)current_block).AddTransparentParameter (compiler, sn);
- else
- ((Linq.QueryBlock)current_block).AddTransparentParameter (compiler, sn2);
+ ((Linq.QueryBlock)current_block).AddRangeVariable (sn2 ?? sn);
}
| JOIN type IDENTIFIER IN
{
current_block.SetEndLocation (lexer.Location);
current_block = current_block.Parent;
- var lt = (Tokenizer.LocatedToken) $3;
- current_block = new Linq.QueryBlock (compiler, current_block, new SimpleMemberName (lt.Value, lt.Location), lexer.Location);
+ current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
}
expression opt_join_into
{
var lt = (Tokenizer.LocatedToken) $3;
var sn = new SimpleMemberName (lt.Value, lt.Location);
SimpleMemberName sn2 = null;
- ToplevelBlock outer_selector = linq_clause_blocks.Pop ();
- ToplevelBlock block = linq_clause_blocks.Pop ();
+ var outer_selector = linq_clause_blocks.Pop ();
+ var block = linq_clause_blocks.Pop ();
- Linq.Cast cast = new Linq.Cast ((FullNamedExpression)$2, (Expression)$6);
if ($13 == null) {
- $$ = new Linq.Join (block, sn, cast, outer_selector, current_block.Toplevel, GetLocation ($1));
+ $$ = new Linq.Join (block, sn, (Expression)$6, outer_selector, (Linq.QueryBlock) current_block, GetLocation ($1)) {
+ IdentifierType = (FullNamedExpression)$2
+ };
} else {
var lt2 = (Tokenizer.LocatedToken) $13;
sn2 = new SimpleMemberName (lt2.Value, lt2.Location);
- $$ = new Linq.GroupJoin (block, sn, cast, outer_selector, current_block.Toplevel,
- sn2, GetLocation ($1));
+ $$ = new Linq.GroupJoin (block, sn, (Expression)$6, outer_selector, (Linq.QueryBlock) current_block, sn2, GetLocation ($1)) {
+ IdentifierType = (FullNamedExpression)$2
+ };
}
current_block.AddStatement (new ContextualReturn ((Expression) $12));
current_block.SetEndLocation (lexer.Location);
current_block = current_block.Parent;
- if (sn2 == null)
- ((Linq.QueryBlock)current_block).AddTransparentParameter (compiler, sn);
- else
- ((Linq.QueryBlock)current_block).AddTransparentParameter (compiler, sn2);
+ ((Linq.QueryBlock)current_block).AddRangeVariable (sn2 ?? sn);
}
;
current_block.SetEndLocation (lexer.Location);
current_block = current_block.Parent;
- current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
+ current_block = new Linq.QueryBlock (compiler, (Linq.QueryBlock) current_block, lexer.Location);
}
then_by
{
- ((Linq.AQueryClause)$1).Tail.Next = (Linq.AQueryClause)$3;
+ ((Linq.AQueryClause)$1).Tail.Next = (Linq.AQueryClause)$4;
$$ = $1;
}
;
order_by
: expression
{
- $$ = new Linq.OrderByAscending (current_block.Toplevel, (Expression)$1);
+ $$ = new Linq.OrderByAscending ((Linq.QueryBlock) current_block, (Expression)$1);
}
| expression ASCENDING
{
- $$ = new Linq.OrderByAscending (current_block.Toplevel, (Expression)$1);
+ $$ = new Linq.OrderByAscending ((Linq.QueryBlock) current_block, (Expression)$1);
}
| expression DESCENDING
{
- $$ = new Linq.OrderByDescending (current_block.Toplevel, (Expression)$1);
+ $$ = new Linq.OrderByDescending ((Linq.QueryBlock) current_block, (Expression)$1);
}
;
then_by
: expression
{
- $$ = new Linq.ThenByAscending (current_block.Toplevel, (Expression)$1);
+ $$ = new Linq.ThenByAscending ((Linq.QueryBlock) current_block, (Expression)$1);
}
| expression ASCENDING
{
- $$ = new Linq.ThenByAscending (current_block.Toplevel, (Expression)$1);
+ $$ = new Linq.ThenByAscending ((Linq.QueryBlock) current_block, (Expression)$1);
}
| expression DESCENDING
{
- $$ = new Linq.ThenByDescending (current_block.Toplevel, (Expression)$1);
+ $$ = new Linq.ThenByDescending ((Linq.QueryBlock) current_block, (Expression)$1);
}
;
current_block.SetEndLocation (GetLocation ($1));
current_block = current_block.Parent;
-
- var lt = (Tokenizer.LocatedToken) $2;
+
+ current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
- current_block = new Linq.QueryBlock (compiler, current_block, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1));
+ if (linq_clause_blocks == null)
+ linq_clause_blocks = new Stack<Linq.QueryBlock> ();
+
+ linq_clause_blocks.Push ((Linq.QueryBlock) current_block);
}
query_body
{
- $$ = new Linq.QueryExpression (current_block, (Linq.AQueryClause)$4);
+ var current_block = linq_clause_blocks.Pop ();
+ var lt = (Tokenizer.LocatedToken) $2;
+ $$ = new Linq.QueryStartClause ((Linq.QueryBlock)current_block, null, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1)) {
+ next = (Linq.AQueryClause)$4
+ };
}
;
void start_block (Location loc)
{
if (current_block == null || parsing_anonymous_method) {
- current_block = new ToplevelBlock (compiler, current_block, current_local_parameters, current_generic_method, loc);
+ current_block = new ToplevelBlock (compiler, current_block, current_local_parameters, loc);
parsing_anonymous_method = false;
} else {
current_block = new ExplicitBlock (current_block, loc, Location.Null);
namespace Mono.CSharp.Linq
{
- // NOTES:
- // Expression should be IExpression to save some memory and make a few things
- // easier to read
- //
- //
-
public class QueryExpression : AQueryClause
{
- public QueryExpression (Block block, AQueryClause query)
- : base (null, null, query.Location)
+ public QueryExpression (AQueryClause start)
+ : base (null, null, Location.Null)
{
- this.next = query;
+ this.next = start;
}
- public override Expression BuildQueryClause (ResolveContext ec, Expression lSide)
+ public override Expression BuildQueryClause (ResolveContext ec, Expression lSide, Parameter parentParameter)
{
- return next.BuildQueryClause (ec, lSide);
+ return next.BuildQueryClause (ec, lSide, parentParameter);
}
protected override Expression DoResolve (ResolveContext ec)
{
int counter = QueryBlock.TransparentParameter.Counter;
- Expression e = BuildQueryClause (ec, null);
+ Expression e = BuildQueryClause (ec, null, null);
if (e != null)
e = e.Resolve (ec);
public abstract class AQueryClause : ShimExpression
{
- class QueryExpressionAccess : MemberAccess
+ protected class QueryExpressionAccess : MemberAccess
{
public QueryExpressionAccess (Expression expr, string methodName, Location loc)
: base (expr, methodName, loc)
}
}
- class QueryExpressionInvocation : Invocation, MethodGroupExpr.IErrorHandler
+ protected class QueryExpressionInvocation : Invocation, MethodGroupExpr.IErrorHandler
{
public QueryExpressionInvocation (QueryExpressionAccess expr, Arguments arguments)
: base (expr, arguments)
}
}
- // TODO: protected
public AQueryClause next;
- protected ToplevelBlock block;
+ public QueryBlock block;
- protected AQueryClause (ToplevelBlock block, Expression expr, Location loc)
+ protected AQueryClause (QueryBlock block, Expression expr, Location loc)
: base (expr)
{
this.block = block;
AQueryClause t = (AQueryClause) target;
if (block != null)
- t.block = (ToplevelBlock) block.Clone (clonectx);
+ t.block = (QueryBlock) clonectx.LookupBlock (block);
if (next != null)
t.next = (AQueryClause) next.Clone (clonectx);
return expr.Resolve (ec);
}
- public virtual Expression BuildQueryClause (ResolveContext ec, Expression lSide)
+ public virtual Expression BuildQueryClause (ResolveContext ec, Expression lSide, Parameter parameter)
{
- Arguments args;
- CreateArguments (ec, out args);
+ Arguments args = null;
+ CreateArguments (ec, parameter, ref args);
lSide = CreateQueryExpression (lSide, args);
if (next != null) {
+ parameter = CreateChildrenParameters (parameter);
+
Select s = next as Select;
- if (s == null || s.IsRequired)
- return next.BuildQueryClause (ec, lSide);
+ if (s == null || s.IsRequired (parameter))
+ return next.BuildQueryClause (ec, lSide, parameter);
// Skip transparent select clause if any clause follows
if (next.next != null)
- return next.next.BuildQueryClause (ec, lSide);
+ return next.next.BuildQueryClause (ec, lSide, parameter);
}
return lSide;
}
- protected virtual void CreateArguments (ResolveContext ec, out Arguments args)
+ protected virtual Parameter CreateChildrenParameters (Parameter parameter)
+ {
+ return parameter;
+ }
+
+ protected virtual void CreateArguments (ResolveContext ec, Parameter parameter, ref Arguments args)
{
args = new Arguments (2);
LambdaExpression selector = new LambdaExpression (loc);
+
+ block.SetParameter (parameter.Clone ());
selector.Block = block;
selector.Block.AddStatement (new ContextualReturn (expr));
new QueryExpressionAccess (lSide, MethodName, loc), arguments);
}
- protected Invocation CreateQueryExpression (Expression lSide, TypeArguments typeArguments, Arguments arguments)
- {
- return new QueryExpressionInvocation (
- new QueryExpressionAccess (lSide, MethodName, typeArguments, loc), arguments);
- }
-
protected abstract string MethodName { get; }
- public virtual AQueryClause Next {
+ public AQueryClause Next {
set {
next = value;
}
}
}
- protected ARangeVariableQueryClause (ToplevelBlock block, Expression expr, Location loc)
+ protected SimpleMemberName range_variable;
+
+ protected ARangeVariableQueryClause (QueryBlock block, SimpleMemberName identifier, Expression expr, Location loc)
: base (block, expr, loc)
{
+ range_variable = identifier;
}
- protected static Expression CreateRangeVariableType (ToplevelBlock block, TypeContainer container, SimpleMemberName name, Expression init)
+ public FullNamedExpression IdentifierType { get; set; }
+
+ protected Invocation CreateCastExpression (Expression lSide)
+ {
+ return new QueryExpressionInvocation (
+ new QueryExpressionAccess (lSide, "Cast", new TypeArguments (IdentifierType), loc), null);
+ }
+
+ protected override Parameter CreateChildrenParameters (Parameter parameter)
+ {
+ return new QueryBlock.TransparentParameter (parameter, GetIntoVariable ());
+ }
+
+ protected static Expression CreateRangeVariableType (ResolveContext rc, Parameter parameter, SimpleMemberName name, Expression init)
{
var args = new List<AnonymousTypeParameter> (2);
- args.Add (new AnonymousTypeParameter (block.Parameters [0]));
+ args.Add (new AnonymousTypeParameter (parameter));
args.Add (new RangeAnonymousTypeParameter (init, name));
- return new NewAnonymousType (args, container, name.Location);
+ return new NewAnonymousType (args, rc.MemberContext.CurrentMemberDefinition.Parent, name.Location);
+ }
+
+ protected virtual SimpleMemberName GetIntoVariable ()
+ {
+ return range_variable;
}
}
- class QueryStartClause : AQueryClause
+ class QueryStartClause : ARangeVariableQueryClause
{
- public QueryStartClause (Expression expr)
- : base (null, expr, expr.Location)
+ public QueryStartClause (QueryBlock block, Expression expr, SimpleMemberName identifier, Location loc)
+ : base (block, identifier, expr, loc)
{
+ block.AddRangeVariable (identifier);
}
- public override Expression BuildQueryClause (ResolveContext ec, Expression lSide)
+ public override Expression BuildQueryClause (ResolveContext ec, Expression lSide, Parameter parameter)
{
+/*
expr = expr.Resolve (ec);
if (expr == null)
return null;
TypeManager.CSharpName (expr.Type));
return null;
}
+*/
- return next.BuildQueryClause (ec, expr);
+ if (IdentifierType != null)
+ expr = CreateCastExpression (expr);
+
+ if (parameter == null)
+ lSide = expr;
+
+ return next.BuildQueryClause (ec, lSide, new ImplicitLambdaParameter (range_variable.Value, range_variable.Location));
}
protected override Expression DoResolve (ResolveContext ec)
{
- Expression e = BuildQueryClause (ec, null);
+ Expression e = BuildQueryClause (ec, null, null);
return e.Resolve (ec);
}
}
}
- class Cast : QueryStartClause
- {
- // We don't have to clone cast type
- readonly FullNamedExpression type_expr;
-
- public Cast (FullNamedExpression type, Expression expr)
- : base (expr)
- {
- this.type_expr = type;
- }
-
- public override Expression BuildQueryClause (ResolveContext ec, Expression lSide)
- {
- lSide = CreateQueryExpression (expr, new TypeArguments (type_expr), null);
- if (next != null)
- return next.BuildQueryClause (ec, lSide);
-
- return lSide;
- }
-
- protected override string MethodName {
- get { return "Cast"; }
- }
- }
-
public class GroupBy : AQueryClause
{
Expression element_selector;
- ToplevelBlock element_block;
-
- public GroupBy (ToplevelBlock block, Expression elementSelector, ToplevelBlock elementBlock, Expression keySelector, Location loc)
+ QueryBlock element_block;
+
+ public GroupBy (QueryBlock block, Expression elementSelector, QueryBlock elementBlock, Expression keySelector, Location loc)
: base (block, keySelector, loc)
{
//
}
}
- protected override void CreateArguments (ResolveContext ec, out Arguments args)
+ protected override void CreateArguments (ResolveContext ec, Parameter parameter, ref Arguments args)
{
- base.CreateArguments (ec, out args);
+ base.CreateArguments (ec, parameter, ref args);
if (element_selector != null) {
LambdaExpression lambda = new LambdaExpression (element_selector.Location);
+
+ element_block.SetParameter (parameter.Clone ());
lambda.Block = element_block;
lambda.Block.AddStatement (new ContextualReturn (element_selector));
args.Add (new Argument (lambda));
GroupBy t = (GroupBy) target;
if (element_selector != null) {
t.element_selector = element_selector.Clone (clonectx);
- t.element_block = (ToplevelBlock) element_block.Clone (clonectx);
+ t.element_block = (QueryBlock) element_block.Clone (clonectx);
}
base.CloneTo (clonectx, t);
}
}
- public class Join : ARangeVariableQueryClause
+ public class Join : SelectMany
{
- readonly SimpleMemberName lt;
- ToplevelBlock inner_selector, outer_selector;
+ QueryBlock inner_selector, outer_selector;
- public Join (ToplevelBlock block, SimpleMemberName lt, Expression inner, ToplevelBlock outerSelector, ToplevelBlock innerSelector, Location loc)
- : base (block, inner, loc)
+ public Join (QueryBlock block, SimpleMemberName lt, Expression inner, QueryBlock outerSelector, QueryBlock innerSelector, Location loc)
+ : base (block, lt, inner, loc)
{
- this.lt = lt;
this.outer_selector = outerSelector;
this.inner_selector = innerSelector;
}
- protected override void CreateArguments (ResolveContext ec, out Arguments args)
+ protected override void CreateArguments (ResolveContext ec, Parameter parameter, ref Arguments args)
{
args = new Arguments (4);
+ if (IdentifierType != null)
+ expr = CreateCastExpression (expr);
+
args.Add (new Argument (expr));
- LambdaExpression lambda = new LambdaExpression (outer_selector.StartLocation);
+ outer_selector.SetParameter (parameter.Clone ());
+ var lambda = new LambdaExpression (outer_selector.StartLocation);
lambda.Block = outer_selector;
args.Add (new Argument (lambda));
+ inner_selector.SetParameter (new ImplicitLambdaParameter (range_variable.Value, range_variable.Location));
lambda = new LambdaExpression (inner_selector.StartLocation);
lambda.Block = inner_selector;
args.Add (new Argument (lambda));
- Expression result_selector_expr;
- SimpleMemberName into_variable = GetIntoVariable ();
- //
- // When select follows use is as result selector
- //
- if (next is Select) {
- result_selector_expr = next.Expr;
- next = next.next;
- } else {
- result_selector_expr = CreateRangeVariableType (block, ec.MemberContext.CurrentMemberDefinition.Parent, into_variable,
- new SimpleName (into_variable.Value, into_variable.Location));
- }
-
- LambdaExpression result_selector = new LambdaExpression (lt.Location);
- result_selector.Block = new QueryBlock (ec.Compiler, block.Parent, block.Parameters, into_variable, block.StartLocation);
- result_selector.Block.AddStatement (new ContextualReturn (result_selector_expr));
-
- args.Add (new Argument (result_selector));
- }
-
- protected virtual SimpleMemberName GetIntoVariable ()
- {
- return lt;
+ base.CreateArguments (ec, parameter, ref args);
}
protected override void CloneTo (CloneContext clonectx, Expression target)
{
Join t = (Join) target;
- t.inner_selector = (ToplevelBlock) inner_selector.Clone (clonectx);
- t.outer_selector = (ToplevelBlock) outer_selector.Clone (clonectx);
+ t.inner_selector = (QueryBlock) inner_selector.Clone (clonectx);
+ t.outer_selector = (QueryBlock) outer_selector.Clone (clonectx);
base.CloneTo (clonectx, t);
}
{
readonly SimpleMemberName into;
- public GroupJoin (ToplevelBlock block, SimpleMemberName lt, Expression inner,
- ToplevelBlock outerSelector, ToplevelBlock innerSelector, SimpleMemberName into, Location loc)
+ public GroupJoin (QueryBlock block, SimpleMemberName lt, Expression inner,
+ QueryBlock outerSelector, QueryBlock innerSelector, SimpleMemberName into, Location loc)
: base (block, lt, inner, outerSelector, innerSelector, loc)
{
this.into = into;
public class Let : ARangeVariableQueryClause
{
- public Let (ToplevelBlock block, TypeContainer container, SimpleMemberName identifier, Expression expr, Location loc)
- : base (block, CreateRangeVariableType (block, container, identifier, expr), loc)
+ public Let (QueryBlock block, SimpleMemberName identifier, Expression expr, Location loc)
+ : base (block, identifier, expr, loc)
{
}
+ protected override void CreateArguments (ResolveContext ec, Parameter parameter, ref Arguments args)
+ {
+ expr = CreateRangeVariableType (ec, parameter, range_variable, expr);
+ base.CreateArguments (ec, parameter, ref args);
+ }
+
protected override string MethodName {
get { return "Select"; }
}
public class Select : AQueryClause
{
- public Select (ToplevelBlock block, Expression expr, Location loc)
+ public Select (QueryBlock block, Expression expr, Location loc)
: base (block, expr, loc)
{
}
// For queries like `from a orderby a select a'
// the projection is transparent and select clause can be safely removed
//
- public bool IsRequired {
- get {
- SimpleName sn = expr as SimpleName;
- if (sn == null)
- return true;
+ public bool IsRequired (Parameter parameter)
+ {
+ SimpleName sn = expr as SimpleName;
+ if (sn == null)
+ return true;
- return sn.Name != block.Parameters.FixedParameters [0].Name;
- }
+ return sn.Name != parameter.Name;
}
protected override string MethodName {
public class SelectMany : ARangeVariableQueryClause
{
- SimpleMemberName lt;
-
- public SelectMany (ToplevelBlock block, SimpleMemberName lt, Expression expr, Location loc)
- : base (block, expr, loc)
+ public SelectMany (QueryBlock block, SimpleMemberName identifier, Expression expr, Location loc)
+ : base (block, identifier, expr, loc)
{
- this.lt = lt;
}
- protected override void CreateArguments (ResolveContext ec, out Arguments args)
+ protected override void CreateArguments (ResolveContext ec, Parameter parameter, ref Arguments args)
{
- base.CreateArguments (ec, out args);
+ if (args == null) {
+ if (IdentifierType != null)
+ expr = CreateCastExpression (expr);
+
+ base.CreateArguments (ec, parameter, ref args);
+ }
Expression result_selector_expr;
+ QueryBlock result_block;
+
+ var target = GetIntoVariable ();
+ var target_param = new ImplicitLambdaParameter (target.Value, target.Location);
+
//
- // When select follow use is as result selector
+ // When select follows use it as a result selector
//
if (next is Select) {
result_selector_expr = next.Expr;
+
+ result_block = next.block;
+ result_block.SetParameters (parameter, target_param);
+
next = next.next;
} else {
- result_selector_expr = CreateRangeVariableType (block, ec.MemberContext.CurrentMemberDefinition.Parent, lt, new SimpleName (lt.Value, lt.Location));
+ result_selector_expr = CreateRangeVariableType (ec, parameter, target, new SimpleName (target.Value, target.Location));
+
+ result_block = new QueryBlock (ec.Compiler, block.Parent, block.StartLocation);
+ result_block.SetParameters (parameter, target_param);
}
- LambdaExpression result_selector = new LambdaExpression (lt.Location);
- result_selector.Block = new QueryBlock (ec.Compiler, block.Parent, block.Parameters, lt, block.StartLocation);
+ LambdaExpression result_selector = new LambdaExpression (Location);
+ result_selector.Block = result_block;
result_selector.Block.AddStatement (new ContextualReturn (result_selector_expr));
args.Add (new Argument (result_selector));
public class Where : AQueryClause
{
- public Where (ToplevelBlock block, BooleanExpression expr, Location loc)
+ public Where (QueryBlock block, BooleanExpression expr, Location loc)
: base (block, expr, loc)
{
}
protected override string MethodName {
get { return "Where"; }
}
+
+ protected override void CreateArguments (ResolveContext ec, Parameter parameter, ref Arguments args)
+ {
+ base.CreateArguments (ec, parameter, ref args);
+ }
}
public class OrderByAscending : AQueryClause
{
- public OrderByAscending (ToplevelBlock block,Expression expr)
+ public OrderByAscending (QueryBlock block, Expression expr)
: base (block, expr, expr.Location)
{
}
public class OrderByDescending : AQueryClause
{
- public OrderByDescending (ToplevelBlock block, Expression expr)
+ public OrderByDescending (QueryBlock block, Expression expr)
: base (block, expr, expr.Location)
{
}
public class ThenByAscending : OrderByAscending
{
- public ThenByAscending (ToplevelBlock block, Expression expr)
+ public ThenByAscending (QueryBlock block, Expression expr)
: base (block, expr)
{
}
public class ThenByDescending : OrderByDescending
{
- public ThenByDescending (ToplevelBlock block, Expression expr)
+ public ThenByDescending (QueryBlock block, Expression expr)
: base (block, expr)
{
}
//
// Implicit query block
//
- class QueryBlock : ToplevelBlock
+ public class QueryBlock : ToplevelBlock
{
//
// Transparent parameters are used to package up the intermediate results
public static int Counter;
const string ParameterNamePrefix = "<>__TranspIdent";
- public readonly ParametersCompiled Parent;
+ public readonly Parameter Parent;
public readonly string Identifier;
- public TransparentParameter (ParametersCompiled parent, SimpleMemberName identifier)
+ public TransparentParameter (Parameter parent, SimpleMemberName identifier)
: base (ParameterNamePrefix + Counter++, identifier.Location)
{
Parent = parent;
}
}
- public sealed class ImplicitQueryParameter : ImplicitLambdaParameter
+ sealed class RangeVariable : IKnownVariable
{
- public ImplicitQueryParameter (string name, Location loc)
- : base (name, loc)
+ public RangeVariable (QueryBlock block, Location loc)
{
+ Block = block;
+ Location = loc;
}
- }
- public QueryBlock (CompilerContext ctx, Block parent, SimpleMemberName lt, Location start)
- : base (ctx, parent, new ParametersCompiled (ctx, new ImplicitQueryParameter (lt.Value, lt.Location)), start)
- {
- if (parent != null)
- base.CheckParentConflictName (parent.Toplevel, lt.Value, lt.Location);
- }
+ public Block Block { get; private set; }
- public QueryBlock (CompilerContext ctx, Block parent, ParametersCompiled parameters, SimpleMemberName lt, Location start)
- : base (ctx, parent, new ParametersCompiled (ctx, parameters [0].Clone (), new ImplicitQueryParameter (lt.Value, lt.Location)), start)
- {
+ public Location Location { get; private set; }
}
+ List<SimpleMemberName> range_variables;
+
public QueryBlock (CompilerContext ctx, Block parent, Location start)
- : base (ctx, parent, parent.Toplevel.Parameters.Clone (), start)
+ : base (ctx, parent, ParametersCompiled.EmptyReadOnlyParameters, start)
{
}
- public void AddTransparentParameter (CompilerContext ctx, SimpleMemberName name)
+ public void AddRangeVariable (SimpleMemberName name)
{
- base.CheckParentConflictName (this, name.Value, name.Location);
+ if (!CheckParentConflictName (this, name.Value, name.Location))
+ return;
- parameters = new ParametersCompiled (ctx, new TransparentParameter (parameters, name));
- }
+ if (range_variables == null)
+ range_variables = new List<SimpleMemberName> ();
- protected override bool CheckParentConflictName (ToplevelBlock block, string name, Location l)
- {
- return true;
+ range_variables.Add (name);
+ AddKnownVariable (name.Value, new RangeVariable (this, name.Location));
}
//
if (tp.Identifier == name)
break;
- TransparentParameter tp_next = tp.Parent [0] as TransparentParameter;
- if (tp_next == null) {
- if (tp.Parent.GetParameterIndexByName (name) >= 0)
- break;
- }
+ TransparentParameter tp_next = tp.Parent as TransparentParameter;
+ if (tp_next == null && tp.Parent.Name == name)
+ break;
tp = tp_next;
}
expr = new SimpleName (parameters[0].Name, loc);
TransparentParameter tp_cursor = (TransparentParameter) parameters[0];
while (tp_cursor != tp) {
- tp_cursor = (TransparentParameter) tp_cursor.Parent[0];
+ tp_cursor = (TransparentParameter) tp_cursor.Parent;
expr = new MemberAccess (expr, tp_cursor.Name);
}
return null;
}
+ protected override bool HasParameterWithName (string name)
+ {
+ return range_variables != null && range_variables.Exists (l => l.Value == name);
+ }
+
protected override void Error_AlreadyDeclared (Location loc, string var, string reason)
{
Report.Error (1931, loc, "A range variable `{0}' conflicts with a previous declaration of `{0}'",
var);
}
- public override void Error_AlreadyDeclaredTypeParameter (Report r, Location loc, string name, string conflict)
+ public override void Error_AlreadyDeclaredTypeParameter (Location loc, string name, string conflict)
{
- r.Error (1948, loc, "A range variable `{0}' conflicts with a method type parameter",
+ Report.Error (1948, loc, "A range variable `{0}' conflicts with a method type parameter",
name);
}
+
+ public void SetParameter (Parameter parameter)
+ {
+ base.parameters = new ParametersCompiled (null, parameter);
+ base.parameter_info = new ToplevelParameterInfo [] {
+ new ToplevelParameterInfo (this, 0)
+ };
+ }
+
+ public void SetParameters (Parameter first, Parameter second)
+ {
+ base.parameters = new ParametersCompiled (null, first, second);
+ base.parameter_info = new ToplevelParameterInfo[] {
+ new ToplevelParameterInfo (this, 0),
+ new ToplevelParameterInfo (this, 1)
+ };
+ }
}
}
return false;
}
- protected virtual bool CheckParentConflictName (ToplevelBlock block, string name, Location l)
+ protected bool CheckParentConflictName (ToplevelBlock block, string name, Location l)
{
LocalInfo vi = GetLocalInfo (name);
if (vi != null) {
}
if (block != null) {
- Expression e = block.GetParameterReference (name, Location.Null);
- if (e != null) {
- ParameterReference pr = e as ParameterReference;
- if (this is Linq.QueryBlock && (pr != null && pr.Parameter is Linq.QueryBlock.ImplicitQueryParameter || e is MemberAccess))
+ var tblock = block.CheckParameterNameConflict (name);
+ if (tblock != null) {
+ if (block == tblock && block is Linq.QueryBlock)
Error_AlreadyDeclared (loc, name);
else
Error_AlreadyDeclared (loc, name, "parent or current");
+
return false;
}
}
if (!CheckParentConflictName (Toplevel, name, l))
return null;
- if (Toplevel.GenericMethod != null) {
- foreach (TypeParameter tp in Toplevel.GenericMethod.CurrentTypeParameters) {
- if (tp.Name == name) {
- Toplevel.Report.SymbolRelatedToPreviousError (tp);
- Error_AlreadyDeclaredTypeParameter (Toplevel.Report, loc, name, "local variable");
- return null;
- }
- }
- }
-
IKnownVariable kvi = Explicit.GetKnownVariable (name);
if (kvi != null) {
Toplevel.Report.SymbolRelatedToPreviousError (kvi.Location, name);
"A local variable named `{0}' is already defined in this scope", name);
}
- public virtual void Error_AlreadyDeclaredTypeParameter (Report r, Location loc, string name, string conflict)
+ public virtual void Error_AlreadyDeclaredTypeParameter (Location loc, string name, string conflict)
{
- r.Error (412, loc, "The type parameter name `{0}' is the same as `{1}'",
+ Toplevel.Report.Error (412, loc, "The type parameter name `{0}' is the same as `{1}'",
name, conflict);
}
{
LocalInfo ret;
for (Block b = this; b != null; b = b.Parent) {
- if (b.variables != null) {
- if (b.variables.TryGetValue (name, out ret))
- return ret;
+ if (b.variables != null && b.variables.TryGetValue (name, out ret)) {
+ return ret;
}
}
public override string ToString ()
{
- return String.Format ("{0} ({1}:{2})", GetType (),ID, StartLocation);
+ return String.Format ("{0} ({1}:{2})", GetType (), this_id, StartLocation);
}
protected override void CloneTo (CloneContext clonectx, Statement t)
clonectx.AddBlockMap (this, target);
- //target.Toplevel = (ToplevelBlock) clonectx.LookupBlock (Toplevel);
+ target.Toplevel = (ToplevelBlock) clonectx.LookupBlock (Toplevel);
target.Explicit = (ExplicitBlock) clonectx.LookupBlock (Explicit);
if (Parent != null)
target.Parent = clonectx.RemapBlockCopy (Parent);
base.EmitMeta (ec);
}
- internal IKnownVariable GetKnownVariable (string name)
+ public IKnownVariable GetKnownVariable (string name)
{
if (known_variables == null)
return null;
IKnownVariable kw;
- if (!known_variables.TryGetValue (name, out kw))
- return null;
-
+ known_variables.TryGetValue (name, out kw);
return kw;
}
}
}
- GenericMethod generic;
protected ParametersCompiled parameters;
- ToplevelParameterInfo[] parameter_info;
+ protected ToplevelParameterInfo[] parameter_info;
LocalInfo this_variable;
bool resolved;
bool unreachable;
get { return compiler.Report; }
}
- public GenericMethod GenericMethod {
- get { return generic; }
- }
-
public ToplevelBlock Container {
get { return Parent == null ? null : Parent.Toplevel; }
}
{
}
- public ToplevelBlock (CompilerContext ctx, Block parent, ParametersCompiled parameters, GenericMethod generic, Location start) :
- this (ctx, parent, parameters, start)
- {
- this.generic = generic;
- }
-
public ToplevelBlock (CompilerContext ctx, ParametersCompiled parameters, Location start) :
this (ctx, null, (Flags) 0, parameters, start)
{
ToplevelBlock target = (ToplevelBlock) t;
base.CloneTo (clonectx, t);
- if (parameters.Count != 0)
- target.parameter_info = new ToplevelParameterInfo [parameters.Count];
- for (int i = 0; i < parameters.Count; ++i)
- target.parameter_info [i] = new ToplevelParameterInfo (target, i);
+ if (parameters.Count != 0) {
+ target.parameter_info = new ToplevelParameterInfo[parameters.Count];
+ for (int i = 0; i < parameters.Count; ++i)
+ target.parameter_info[i] = new ToplevelParameterInfo (target, i);
+ }
}
public bool CheckError158 (string name, Location loc)
public Expression GetParameterReference (string name, Location loc)
{
for (ToplevelBlock t = this; t != null; t = t.Container) {
+ if (t.parameters.IsEmpty)
+ continue;
+
Expression expr = t.GetParameterReferenceExpression (name, loc);
if (expr != null)
return expr;
null : new ParameterReference (parameter_info [idx], loc);
}
+ public ToplevelBlock CheckParameterNameConflict (string name)
+ {
+ for (ToplevelBlock t = this; t != null; t = t.Container) {
+ if (t.HasParameterWithName (name))
+ return t;
+ }
+
+ return null;
+ }
+
+ protected virtual bool HasParameterWithName (string name)
+ {
+ return parameters.GetParameterIndexByName (name) >= 0;
+ }
+
// <summary>
// Returns the "this" instance variable of this block.
// See AddThisVariable() for more information.