+2005-04-29 Satya Sudha K <ksathyasudha@novell.com>
+ * argument.cs
+ * statement.cs
+ * expression.cs
+ * assign.cs
+ * mb-parser.jay:
+ Support for 'LateSet', 'LateIndexGet', 'LateIndexSet'
+
+ * ecore.cs :
+ Minor fixes in conversions
+
2005-04-26 Manjula GHM <mmanjula@novell.com>
*statement.cs
"out" is not supported as Parameter Modifier in VB.NET
+
2005-04-26 Manjula GHM <mmanjula@novell.com>
*support.cs
*parameter.cs
public Argument (Expression expr, AType type)
{
+ expr = Parser.SetValueRequiredFlag (expr);
this.Expr = expr;
this.ArgType = type;
}
public Assign (Expression target, Expression source, Location l)
{
+ source = Parser.SetValueRequiredFlag (source);
+ target = Parser.SetLeftHandFlag (target);
+ if (target is MemberAccess)
+ ((MemberAccess) target).IsLeftHand = true;
this.target = target;
this.source = this.real_source = source;
this.loc = l;
return e;
}
}
-
}
- target = target.ResolveLValue (ec, source);
- if (target == null)
+ Expression tmpTarget = target.ResolveLValue (ec, source);
+ if (tmpTarget == null) {
+ // Case of LateBinding.
+ // Get the appropriate arguments, add the source as the last argument
+ Expression lateBindingExpr = null;
+ ArrayList arguments = null;
+ if (target is Invocation) {
+ lateBindingExpr = ((Invocation) target).Expr;
+ arguments = ((Invocation) target).Arguments;
+ }
+ if (target is MemberAccess) {
+ lateBindingExpr = target;
+ }
+ if (arguments == null)
+ arguments = new ArrayList ();
+
+ arguments.Add (new Argument (source, Argument.AType.Expression));
+
+ Expression etmp = lateBindingExpr;
+ Type exprType = lateBindingExpr.Type;
+ // Get the target of the invocation/memberAccess
+ if (exprType == null) {
+ if (etmp is Invocation)
+ etmp = ((Invocation) etmp).Expr;
+ if (etmp is MemberAccess)
+ etmp = ((MemberAccess) etmp).Expr;
+ exprType = etmp.Type;
+ }
+
+ if (exprType == TypeManager.object_type) {
+ StatementSequence tmp = new StatementSequence (ec.CurrentBlock, loc, lateBindingExpr,
+ arguments, false, true);
+ tmp.GenerateLateBindingStatements ();
+ return tmp.Resolve (ec);
+ }
+
return null;
+ }
+
+ target = tmpTarget;
Type target_type = target.Type;
Type source_type = real_source.Type;
}
if ((expr_type != TypeManager.char_type) &&
- (expr_type != TypeManager.string_type))
+ (expr_type != TypeManager.string_type) &&
+ (expr_type != TypeManager.object_type))
return new NumericToBoolCast (expr, expr.Type);
}
public class BoolToNumericCast : EmptyCast
{
- Expression src;
Type target_type;
OpCode conv;
return this;
}
+ if (expr_type == TypeManager.object_type) {
+ Expression etmp = Parser.DecomposeQI ("Microsoft.VisualBasic.CompilerServices.ObjectType.NotObj", Location.Null);
+ ArrayList arguments = new ArrayList ();
+ arguments.Add (new Argument (Expr, Argument.AType.Expression));
+ Expression e = new Invocation (etmp, arguments, loc);
+ return e.Resolve (ec);
+ }
+
break;
case Operator.AddressOf:
// Not required in VB ??
public Binary (Operator oper, Expression left, Expression right, Location loc)
{
+ left = Parser.SetValueRequiredFlag (left);
+ right = Parser.SetValueRequiredFlag (right);
this.oper = oper;
this.left = left;
this.right = right;
// one from the other, then we catch the error there.
// If other type is a value type, convert it to object
- if (l.IsValueType && r == TypeManager.object_type)
+ if (r == TypeManager.object_type &&
+ (l.IsValueType || l == TypeManager.string_type))
left = ConvertImplicit (ec, left, TypeManager.object_type, loc);
- if (r.IsValueType && l == TypeManager.object_type)
+ if (l == TypeManager.object_type &&
+ (r.IsValueType || r == TypeManager.string_type))
right = ConvertImplicit (ec, right, TypeManager.object_type, loc);
if (left == null || right == null) {
Error_OperatorCannotBeApplied (loc, OperName (oper), l, r);
left = left.Resolve (ec);
right = right.Resolve (ec);
- if (left is Invocation) {
- ((Invocation) left).IsRetvalRequired = true;
- }
- if (right is Invocation) {
- ((Invocation) right).IsRetvalRequired = true;
- }
-
if (left == null || right == null)
return null;
public Invocation (Expression expr, ArrayList arguments, Location l)
{
this.expr = expr;
+ if (this.expr is MemberAccess) {
+ ((MemberAccess) this.expr).IsInvocation = true;
+ }
this.is_retval_required = false;
this.is_left_hand = false;
Arguments = arguments;
}
}
+ public bool IsLeftHand {
+ get {
+ return is_left_hand;
+ }
+ set {
+ is_left_hand = value;
+ }
+ }
+
public bool IsRetvalRequired {
get {
return is_retval_required;
}
if (temp == null) {
+ if (is_left_hand)
+ return null;
if (expr is MemberAccess) {
MemberAccess m = expr as MemberAccess;
if (m.Expr.Type == TypeManager.object_type) {
// We can't resolve now, but we
// have to try to access the array with a call
// to LateIndexGet/Set in the runtime
- Expression lig_call_expr;
-
- if (!is_left_hand)
- lig_call_expr = Mono.MonoBASIC.Parser.DecomposeQI("Microsoft.VisualBasic.CompilerServices.LateBinding.LateIndexGet", Location.Null);
- else
- lig_call_expr = Mono.MonoBASIC.Parser.DecomposeQI("Microsoft.VisualBasic.CompilerServices.LateBinding.LateIndexSet", Location.Null);
- Expression obj_type = Mono.MonoBASIC.Parser.DecomposeQI("System.Object", Location.Null);
- ArrayList adims = new ArrayList();
-
- ArrayList ainit = new ArrayList();
- foreach (Argument a in Arguments)
- ainit.Add ((Expression) a.Expr);
-
- adims.Add ((Expression) new IntLiteral (Arguments.Count));
-
- Expression oace = new ArrayCreation (obj_type, adims, "", ainit, Location.Null);
-
- ArrayList args = new ArrayList();
- args.Add (new Argument(expr, Argument.AType.Expression));
- args.Add (new Argument(oace, Argument.AType.Expression));
- args.Add (new Argument(NullLiteral.Null, Argument.AType.Expression));
-
- Expression lig_call = new Invocation (lig_call_expr, args, Location.Null);
- expr_to_return = lig_call.Resolve(ec);
- expr_to_return.eclass = ExprClass.Variable;
+ if (! is_left_hand) {
+ StatementSequence etmp = new StatementSequence (ec.CurrentBlock,
+ loc, ia, Arguments,
+ true, false);
+ etmp.GenerateLateBindingStatements();
+ return etmp.Resolve (ec);
+ }
+ return null;
}
}
return expr_to_return;
}
- static void Error_WrongNumArguments (Location loc, String name, int arg_count)
- {
- Report.Error (1501, loc, "No overload for method `" + name + "' takes `" +
+ static void Error_WrongNumArguments (Location loc, String name, int arg_count)
+ {
+ Report.Error (1501, loc, "No overload for method `" + name + "' takes `" +
arg_count + "' arguments");
- }
+ }
// <summary>
// Emits the list of arguments as an array
public readonly string Identifier;
Expression expr;
Expression member_lookup;
+ bool is_invocation;
+ bool is_left_hand;
public MemberAccess (Expression expr, string id, Location l)
{
loc = l;
}
+ public MemberAccess (Expression expr, string id, Location l, bool isInvocation)
+ {
+ this.expr = expr;
+ Identifier = id;
+ loc = l;
+ is_invocation = isInvocation;
+ }
+
+ public bool IsInvocation {
+ get {
+ return is_invocation;
+ }
+ set {
+ is_invocation = value;
+ }
+ }
+
+ public bool IsLeftHand {
+ get {
+ return is_left_hand;
+ }
+ set {
+ is_left_hand = value;
+ }
+ }
+
public Expression Expr {
get {
return expr;
if (lookup == null) {
if (expr_type != TypeManager.object_type)
Error (30456, "'" + expr_type + "' does not contain a definition for '" + Identifier + "'");
+ // If this came as a part of Invocation,
+ // Since argumets are not known, return null,
+ // let Invocation's Resolve take care
+ if (is_invocation)
+ return null;
+
+ else if (! is_left_hand) {
+ StatementSequence etmp = new StatementSequence (ec.CurrentBlock,
+ loc, this, null,
+ true, is_left_hand);
+ etmp.GenerateLateBindingStatements();
+ return etmp.Resolve (ec);
+ }
+
+ // if the expression is a left hand side of an assignment,
+ // return null, as we dont know the RHS
+ // Let assign take care of Late Binding
return null;
}
else
}
}
- Report.Error (21, loc,
- "Type '" + TypeManager.MonoBASIC_Name (lookup_type) +
- "' does not have any indexers defined");
+ if (lookup_type != TypeManager.object_type)
+ Report.Error (21, loc,
+ "Type '" + TypeManager.MonoBASIC_Name (lookup_type) +
+ "' does not have any indexers defined");
return null;
}
}
this.loc = loc;
}
+ public Expression Instance {
+ get {
+ return instance_expr;
+ }
+ }
+
+ public ArrayList Arguments {
+ get {
+ return arguments;
+ }
+ }
+
protected virtual bool CommonResolve (EmitContext ec)
{
indexer_type = instance_expr.Type;
ec, new MethodGroupExpr (ilist.getters, loc), arguments, loc);
if (get == null){
- Error (30524, "indexer can not be used in this context, because " +
- "it lacks a 'get' accessor");
+ if (instance_expr.Type != TypeManager.object_type)
+ Error (30524, "indexer can not be used in this context, because " +
+ "it lacks a 'get' accessor");
return null;
}
variable_initializer
: expression
{
- $$ = $1;
+ Expression etmp = (Expression) $1;
+ etmp = SetValueRequiredFlag (etmp);
+ $$ = etmp;
}
| array_initializer
{
argument
: expression
{
- Expression expr = (Expression) $1;
- expr = SetValueRequiredFlag (expr);
- $$ = new Argument (expr, Argument.AType.Expression);
+ $$ = new Argument ((Expression) $1, Argument.AType.Expression);
}
| BYREF variable_reference
{
- Expression expr = (Expression) $2;
- expr = SetValueRequiredFlag (expr);
- $$ = new Argument (expr, Argument.AType.Ref);
+ $$ = new Argument ((Expression) $2, Argument.AType.Ref);
}
| /* empty */
{
}
| ADDRESSOF expression
{
- Expression expr = (Expression) $2;
- expr = SetValueRequiredFlag (expr);
- $$ = new Argument (expr, Argument.AType.AddressOf);
+ $$ = new Argument ((Expression) $2, Argument.AType.AddressOf);
}
;
assignment_expression
: prefixed_unary_expression ASSIGN _mark_ expression
{
- Expression expr = SetValueRequiredFlag ((Expression) $4);
- $$ = new Assign ((Expression) $1, expr, (Location)$3);
+ $$ = new Assign ((Expression) $1, (Expression) $4, (Location)$3);
}
| prefixed_unary_expression OP_EXP ASSIGN _mark_ expression
{
Location l = (Location)$4;
- Expression expr = SetValueRequiredFlag ((Expression) $5);
-
$$ = new CompoundAssign (
- Binary.Operator.Exponentiation, (Expression) $1, expr, l);
+ Binary.Operator.Exponentiation, (Expression) $1, (Expression) $5, l);
}
| prefixed_unary_expression STAR ASSIGN _mark_ expression
{
Location l = (Location)$4;
- Expression expr = SetValueRequiredFlag ((Expression) $5);
$$ = new CompoundAssign (
- Binary.Operator.Multiply, (Expression) $1, expr, l);
+ Binary.Operator.Multiply, (Expression) $1, (Expression) $5, l);
}
| prefixed_unary_expression DIV ASSIGN _mark_ expression
{
Location l = (Location)$4;
-
- Expression expr = SetValueRequiredFlag ((Expression) $5);
$$ = new CompoundAssign (
- Binary.Operator.Division, (Expression) $1, expr, l);
+ Binary.Operator.Division, (Expression) $1, (Expression) $5, l);
}
| prefixed_unary_expression PLUS ASSIGN _mark_ expression
{
Location l = (Location)$4;
- Expression expr = SetValueRequiredFlag ((Expression) $5);
-
$$ = new CompoundAssign (
- Binary.Operator.Addition, (Expression) $1, expr, l);
+ Binary.Operator.Addition, (Expression) $1, (Expression) $5, l);
}
| prefixed_unary_expression MINUS ASSIGN _mark_ expression
{
Location l = (Location)$4;
-
- Expression expr = SetValueRequiredFlag ((Expression) $5);
$$ = new CompoundAssign (
- Binary.Operator.Subtraction, (Expression) $1, expr, l);
+ Binary.Operator.Subtraction, (Expression) $1, (Expression) $5, l);
}
| prefixed_unary_expression OP_SHIFT_LEFT ASSIGN _mark_ expression
{
Location l = (Location)$4;
-
- Expression expr = SetValueRequiredFlag ((Expression) $5);
$$ = new CompoundAssign (
- Binary.Operator.LeftShift, (Expression) $1, expr, l);
+ Binary.Operator.LeftShift, (Expression) $1, (Expression) $5, l);
}
| prefixed_unary_expression OP_SHIFT_RIGHT ASSIGN _mark_ expression
{
Location l = (Location)$4;
-
- Expression expr = SetValueRequiredFlag ((Expression) $5);
$$ = new CompoundAssign (
- Binary.Operator.RightShift, (Expression) $1, expr, l);
+ Binary.Operator.RightShift, (Expression) $1, (Expression) $5, l);
}
| prefixed_unary_expression OP_CONCAT ASSIGN _mark_ expression
{
Location l = (Location)$4;
// FIXME should be strings only
- Expression expr = SetValueRequiredFlag ((Expression) $5);
$$ = new CompoundAssign (
- Binary.Operator.Addition, (Expression) $1, expr, l);
+ Binary.Operator.Addition, (Expression) $1, (Expression) $5, l);
}
| prefixed_unary_expression ASSIGN ADDRESSOF _mark_ expression
{
}
}
-static Expression SetValueRequiredFlag (Expression expr) {
+public static Expression SetLeftHandFlag (Expression expr) {
+ if (expr is Invocation) {
+ Invocation e = (Invocation) expr;
+ e.IsLeftHand = true;
+ return e;
+ } else if (expr is MemberAccess) {
+ MemberAccess e = (MemberAccess) expr;
+ e.IsLeftHand = true;
+ return e;
+ }
+
+ return expr;
+}
+
+public static Expression SetValueRequiredFlag (Expression expr) {
if (expr is Invocation) {
Invocation e = (Invocation) expr;
e.IsRetvalRequired = true;
expr = e;
+ return expr;
+ }
+ if (expr is Binary) {
+ Binary binary = (Binary) expr;
+ binary.Left = SetValueRequiredFlag (binary.Left);
+ binary.Right = SetValueRequiredFlag (binary.Right);
+ return binary;
+ }
+ if (expr is Unary) {
+ Unary unary = (Unary) expr;
+ unary.Expr = SetValueRequiredFlag (unary.Expr);
+ return unary;
}
return expr;
}
this.isRetValRequired = this.isLeftHandSide = false;
}
+ public ArrayList Arguments {
+ get {
+ return args;
+ }
+ set {
+ args = value;
+ }
+ }
+
+ public bool IsLeftHandSide {
+ set {
+ isLeftHandSide = value;
+ }
+ }
+
public Block StmtBlock {
get {
return stmtBlock;
public void GenerateLateBindingStatements ()
{
int argCount = 0;
- // Arguments for call Microsoft.VisualBasic.CompilerServices.LateBinding.LateCall
- ArrayList invocationArgs = new ArrayList ();
- invocationArgs.Add (new Argument (((MemberAccess)expr).Expr, Argument.AType.Expression));
- invocationArgs.Add (new Argument (NullLiteral.Null, Argument.AType.Expression));
- invocationArgs.Add (new Argument (new StringLiteral (((MemberAccess)expr).Identifier), Argument.AType.Expression));
- // __LateBindingArgs = new Object () {arg1, arg2 ...}
ArrayList arrayInitializers = new ArrayList ();
ArrayList originalArgs = new ArrayList ();
if (args != null) {
}
}
+ // __LateBindingArgs = new Object () {arg1, arg2 ...}
ArrayCreation new_expr = new ArrayCreation (Parser.DecomposeQI ("System.Object", loc), "[]", arrayInitializers, loc);
Assign assign_stmt = null;
LocalVariableReference v1 = new LocalVariableReference (stmtBlock, Block.lateBindingArgs, loc);
assign_stmt = new Assign (v1, new_expr, loc);
stmtBlock.AddStatement (new StatementExpression ((ExpressionStatement) assign_stmt, loc));
- invocationArgs.Add (new Argument (v1, Argument.AType.Expression));
-
// __LateBindingArgNames = nothing
//LocalVariableReference v2 = new LocalVariableReference (stmtBlock, Block.lateBindingArgNames, loc);
//assign_stmt = new Assign (v2, NullLiteral.Null, loc);
//stmtBlock.AddStatement (new StatementExpression ((ExpressionStatement) assign_stmt, loc));
-
+ // Arguments for call Microsoft.VisualBasic.CompilerServices.LateBinding.LateCall
+ Expression tempExpr = expr;
+ string memName = "";
+ bool isIndexerAccess = true;
+ if (expr is MemberAccess) {
+ tempExpr = ((MemberAccess)expr).Expr;
+ memName = ((MemberAccess)expr).Identifier;
+ isIndexerAccess = false;
+ } else if (expr is IndexerAccess) {
+ tempExpr = ((IndexerAccess) expr).Instance;
+ }
+ ArrayList invocationArgs = new ArrayList ();
+ if (isIndexerAccess) {
+ invocationArgs.Add (new Argument (tempExpr, Argument.AType.Expression));
+ invocationArgs.Add (new Argument (v1, Argument.AType.Expression));
+ invocationArgs.Add (new Argument (NullLiteral.Null, Argument.AType.Expression));
+ Expression tmp = null;
+ if (!isLeftHandSide)
+ tmp = Parser.DecomposeQI ("Microsoft.VisualBasic.CompilerServices.LateBinding.LateIndexGet", loc);
+ else
+ tmp = Parser.DecomposeQI ("Microsoft.VisualBasic.CompilerServices.LateBinding.LateIndexSet", loc);
+ Invocation invStmt = new Invocation (tmp, invocationArgs, Location.Null);
+ invStmt.IsLateBinding = true;
+ stmtBlock.AddStatement (new StatementExpression ((ExpressionStatement) invStmt, loc));
+ return;
+ }
+ invocationArgs.Add (new Argument (tempExpr, Argument.AType.Expression));
+ invocationArgs.Add (new Argument (NullLiteral.Null, Argument.AType.Expression));
+ invocationArgs.Add (new Argument (new StringLiteral (memName), Argument.AType.Expression));
+ invocationArgs.Add (new Argument (v1, Argument.AType.Expression));
invocationArgs.Add (new Argument (NullLiteral.Null, Argument.AType.Expression));
// __LateBindingCopyBack = new Boolean (no_of_args) {}
Expression etmp = null;
if (isLeftHandSide) {
// LateSet
+ etmp = Parser.DecomposeQI ("Microsoft.VisualBasic.CompilerServices.LateBinding.LateSet", loc);
} else if (isRetValRequired) {
// Late Get
etmp = Parser.DecomposeQI ("Microsoft.VisualBasic.CompilerServices.LateBinding.LateGet", loc);