loc = l;
}
+/*
void LoadExprValue (EmitContext ec)
{
}
+*/
public override void Emit (EmitContext ec)
{
public enum Operator : byte {
Exponentiation,
Multiply, Division, IntDivision, Modulus,
- Addition, Subtraction,
+ Addition, Subtraction, Concat,
LeftShift, RightShift,
LessThan, GreaterThan, LessThanOrEqual, GreaterThanOrEqual,
Equality, Inequality,
Type conv_left_as = null;
Type conv_right_as = null;
- if (left is NullLiteral && (r.IsValueType || r == TypeManager.string_type)) {
+ if ((left is NullLiteral ||(Type.GetTypeCode(l)==TypeCode.DBNull)) && (r.IsValueType || r == TypeManager.string_type)) {
// Just treat nothing as the other type, implicit conversion
// will return the default value
conv_left_as = r;
l = r;
+ //incase of DBNull set to NullLiteral
+ left = NullLiteral.Null;
}
- if (right is NullLiteral && (l.IsValueType || l == TypeManager.string_type)) {
+ if ((right is NullLiteral ||(Type.GetTypeCode(r)==TypeCode.DBNull)) && (l.IsValueType || l == TypeManager.string_type)) {
// Just treat nothing as the other type, implicit conversion
// will return the default value
conv_right_as = l;
r = l;
+ right = NullLiteral.Null;
}
// deal with objects and reference types first
public override Expression DoResolve (EmitContext ec)
{
+ if (oper == Operator.Concat) {
+ Expression e = new StringConcat (loc, left, right);
+ return e.Resolve (ec);
+ }
left = left.Resolve (ec);
right = right.Resolve (ec);
{
VariableInfo vi = VariableInfo;
- if (ec.DoFlowAnalysis)
+ if (ec.DoFlowAnalysis) {
ec.SetVariableAssigned (vi);
+ }
Expression e = DoResolve (ec);
VariableInfo vi = VariableInfo;
ILGenerator ig = ec.ig;
- ig.Emit (OpCodes.Ldloc, vi.LocalBuilder);
+ if (vi.Alias != null && vi.Static) {
+ ArrayList fields = ec.TypeContainer.Fields;
+ FieldBase fb = null;
+ for (int i = 0; i < fields.Count; i++) {
+ if (((Field) fields[i]).Name == vi.Alias) {
+ fb = (Field) fields[i];
+ break;
+ }
+ }
+ if ((fb.ModFlags & Modifiers.STATIC) != 0)
+ ig.Emit (OpCodes.Ldsfld, fb.FieldBuilder);
+ else {
+ ig.Emit (OpCodes.Ldarg_0);
+ ig.Emit (OpCodes.Ldfld, fb.FieldBuilder);
+ }
+ } else
+ ig.Emit (OpCodes.Ldloc, vi.LocalBuilder);
+
vi.Used = true;
}
vi.Assigned = true;
- source.Emit (ec);
-
- ig.Emit (OpCodes.Stloc, vi.LocalBuilder);
+ if (vi.Alias != null && vi.Static) {
+ ArrayList fields = ec.TypeContainer.Fields;
+ FieldBase fb = null;
+ for (int i = 0; i < fields.Count; i++) {
+ if (((Field) fields[i]).Name == vi.Alias) {
+ fb = (Field) fields[i];
+ break;
+ }
+ }
+ if ((fb.ModFlags & Modifiers.STATIC) != 0) {
+ source.Emit (ec);
+ ig.Emit (OpCodes.Stsfld, fb.FieldBuilder);
+ }
+ else {
+ ig.Emit (OpCodes.Ldarg_0);
+ source.Emit (ec);
+ ig.Emit (OpCodes.Stfld, fb.FieldBuilder);
+ }
+ }
+ else {
+ source.Emit (ec);
+ ig.Emit (OpCodes.Stloc, vi.LocalBuilder);
+ }
}
public void AddressOf (EmitContext ec, AddressOp mode)
{
VariableInfo vi = VariableInfo;
- ec.ig.Emit (OpCodes.Ldloca, vi.LocalBuilder);
+ if (vi.Alias != null && vi.Static) {
+ ArrayList fields = ec.TypeContainer.Fields;
+ FieldBase fb = null;
+ for (int i = 0; i < fields.Count; i++) {
+ if (((Field) fields[i]).Name == vi.Alias) {
+ fb = (Field) fields[i];
+ break;
+ }
+ }
+ if ((fb.ModFlags & Modifiers.STATIC) != 0)
+ ec.ig.Emit (OpCodes.Ldsflda, fb.FieldBuilder);
+ else {
+ ec.ig.Emit (OpCodes.Ldarg_0);
+ ec.ig.Emit (OpCodes.Ldflda, fb.FieldBuilder);
+ }
+ } else
+ ec.ig.Emit (OpCodes.Ldloca, vi.LocalBuilder);
}
}
bool is_left_hand; // Needed for late bound calls
bool is_retval_required; // Needed for late bound calls
static Hashtable method_parameter_cache;
- static MemberFilter CompareName;
+ //static MemberFilter CompareName;
static ArrayList tempvars; // For ByRef - different parameter and argument type
static bool is_byref_conversion = false; //For ByRef when it is converted
public Invocation (Expression expr, ArrayList arguments, Location l)
{
this.expr = expr;
- if (this.expr is MemberAccess) {
+ if (this.expr is MemberAccess)
((MemberAccess) this.expr).IsInvocation = true;
- }
+ if (this.expr is SimpleName)
+ ((SimpleName) this.expr).IsInvocation = true;
this.is_retval_required = false;
this.is_left_hand = false;
Arguments = arguments;
loc = l;
- CompareName = new MemberFilter (compare_name_filter);
+ //CompareName = new MemberFilter (compare_name_filter);
}
public Expression Expr {
static ConversionType CheckParameterAgainstArgument (EmitContext ec, ParameterData pd, int i, Argument a, Type ptype)
{
- if (a.ArgType == Argument.AType.NoArg) {
- return ConversionType.Widening;
- }
+ if (a.ArgType == Argument.AType.NoArg) {
+ return ConversionType.Widening;
+ }
Parameter.Modifier a_mod = a.GetParameterModifier () &
~(Parameter.Modifier.REF);
return ConversionType.Widening;
// }
+/*
if ((a_mod & Parameter.Modifier.ISBYREF) != 0) {
Type pt = pd.ParameterType (i);
return ConversionType.None;
}
return ConversionType.Widening;
+*/
} else
return ConversionType.None;
}
return orderedArgs;
}
+/*
static bool compare_name_filter (MemberInfo m, object filterCriteria)
{
return (m.Name == ((string) filterCriteria));
}
+*/
public static MethodBase OverloadResolve (EmitContext ec, MethodGroupExpr me,
ref ArrayList Arguments, Location loc)
return OverloadResolve (ec, me, ref a, loc);
}
+/*
static string ToString(MethodBase mbase)
{
if (mbase == null)
return mbase.ToString();
}
+*/
/// <summary>
/// Find the Applicable Function Members (7.4.2.1)
bool dummy;
if (narrow_count != 0) {
- if (IsApplicable (ec, Arguments, c, out dummy) == ConversionType.None)
+ if (IsApplicable (ec, Arguments, c, out dummy) == ConversionType.None)
continue;
Report.Error (1502, loc,
"Overloaded match for method '" +
if (candidates != null) {
foreach (MethodBase candidate in candidates){
- if (candidate == method)
- continue;
+ if (candidate == method)
+ continue;
if (BetterFunction (ec, Arguments, candidate, method,
false, loc) == Applicability.Better) {
- Report.Error (
- 121, loc,
- "Ambiguous call of '" + me.Name + "' when selecting function due to implicit casts");
+ Report.Error (
+ 121, loc,
+ "Ambiguous call of '" + me.Name + "' when selecting function due to implicit casts");
return null;
- }
+ }
}
}
if (newarglist == null)
return null;
}
-
Arguments = ConstructArgumentList(ec, newarglist, namedArgs, method);
if (VerifyArgumentsCompat (ec, Arguments, argument_count, method,
chose_params_expanded, null, loc))
bool IsDelegate = TypeManager.IsDelegateType (param_type);
if (a.ArgType == Argument.AType.NoArg) {
+ Expression pdvalue = pd.DefaultValue (i);
+ pdvalue.Resolve (ec);
+ if (pdvalue != NullLiteral.Null)
+ pdvalue = ConvertImplicit (ec, pdvalue, param_type, Location.Null);;
if (argNamesGiven)
- a = new Argument (pd.ParameterName (i), pd.DefaultValue (i), Argument.AType.Expression);
+ a = new Argument (pd.ParameterName (i), pdvalue, Argument.AType.Expression);
else
- a = new Argument (pd.DefaultValue (i), Argument.AType.Expression);
+ a = new Argument (pdvalue, Argument.AType.Expression);
a.Resolve (ec, Location.Null);
}
return newarglist;
for (int i = arg_count; i < pd.Count; i++) {
+ Type param_type = pd.ParameterType (i);
Expression e = pd.DefaultValue (i);
+ e.Resolve (ec);
+ if (e != NullLiteral.Null)
+ e = ConvertImplicit (ec, e, param_type, Location.Null);
Argument a = null;
if (argNamesGiven)
a = new Argument (e, Argument.AType.Expression);
a = new Argument (pd.ParameterName (i), e, Argument.AType.Expression);
if ((pd.ParameterModifier (i) & Parameter.Modifier.REF) != 0)
a.ArgType = Argument.AType.Ref;
- e.Resolve (ec);
a.Resolve (ec, Location.Null);
newarglist.Add (a);
}
return false;
}
if (pd.ParameterModifier (j) == Parameter.Modifier.PARAMS &&
- chose_params_expanded)
+ chose_params_expanded)
parameter_type = TypeManager.TypeToCoreType (parameter_type.GetElementType ());
// By pass conversion for foll. case and handle it in EmitArguments()
return true;
}
-
+
public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
{
this.is_left_hand = true;
Expression expr_to_return = DoResolve (ec);
+ if (expr_to_return is PropertyGroupExpr) {
+ PropertyGroupExpr pe = expr_to_return as PropertyGroupExpr;
+ pe = (PropertyGroupExpr) pe.ResolveLValue (ec, right_side);
+ if (pe == null)
+ return null;
+ if (pe.IndexerAccessRequired) {
+ if (pe.Type.IsArray) {
+ // If we are here, expr must be an ArrayAccess
+ ArrayList idxs = new ArrayList();
+ foreach (Argument a in Arguments)
+ {
+ idxs.Add (a.Expr);
+ }
+ ElementAccess ea = new ElementAccess (expr_to_return, idxs, expr.Location);
+ ArrayAccess aa = new ArrayAccess (ea, expr_to_return.Location);
+ expr_to_return = aa.DoResolve(ec);
+ expr_to_return.eclass = ExprClass.Variable;
+ } else {
+ //
+ // check whether this is a indexer
+ //
+ ArrayList idxs = new ArrayList();
+ foreach (Argument a in Arguments) {
+ idxs.Add (a.Expr);
+ }
+ ElementAccess ea = new ElementAccess (expr_to_return, idxs, expr.Location);
+ IndexerAccess ia = new IndexerAccess (ea, expr_to_return.Location);
+ if (is_left_hand)
+ expr_to_return = ia.DoResolveLValue (ec, right_side);
+ else
+ expr_to_return = ia.DoResolve(ec);
+ }
+ return expr_to_return;
+ }
+ }
- if (expr_to_return is IndexerAccess) {
+ if (expr_to_return is IndexerAccess && is_left_hand) {
IndexerAccess ia = expr_to_return as IndexerAccess;
expr_to_return = ia.DoResolveLValue (ec, right_side);
}
+
return expr_to_return;
}
expr = expr.Resolve(ec);
}
- if (!(expr is MethodGroupExpr))
+ if (!(expr is MethodGroupExpr || expr is PropertyGroupExpr))
{
Type expr_type = expr.Type;
return expr_to_return;
}
- if (expr is PropertyExpr)
+ if (expr is PropertyGroupExpr)
{
- PropertyExpr pe = ((PropertyExpr) expr);
- if (pe.PropertyArgs != null)
+ PropertyGroupExpr pe = ((PropertyGroupExpr) expr);
+ if (pe.Arguments != null)
goto skip_already_resolved_property;
- pe.PropertyArgs = (ArrayList) Arguments;
- MethodBase mi = pe.PropertyInfo.GetGetMethod(true);
- int argCount = 0;
if (Arguments != null)
- argCount = Arguments.Count;
-
- bool expanded = false;
- if (IsApplicable(ec, pe.PropertyArgs, mi, out expanded) != ConversionType.None) {
- if(VerifyArgumentsCompat (ec, pe.PropertyArgs,
- argCount, mi, expanded, null, loc, pe.Name))
- {
- expr_to_return = pe.DoResolve (ec);
- expr_to_return.eclass = ExprClass.PropertyAccess;
- Arguments = new ArrayList ();
- return expr_to_return;
- }
- else
- {
- throw new Exception("Error resolving Property Access expression\n" + pe.ToString());
- }
- } else {
- pe.PropertyArgs = new ArrayList ();
- if (VerifyArgumentsCompat (ec, pe.PropertyArgs,
- 0, mi, false, null, loc, pe.Name)) {
- expr = pe.DoResolve (ec);
- expr.eclass = ExprClass.PropertyAccess;
- } else {
- throw new Exception("Error resolving Property Access expression\n" + pe.ToString());
- }
+ pe.Arguments = (ArrayList) Arguments.Clone ();
+ if (is_left_hand)
+ return pe;
+ string name = pe.Name;
+ pe = (PropertyGroupExpr) pe.Resolve (ec);
+ if (pe == null) {
+ Error (30057, "Property '" + name + "' cannot be invoked with given arguments");
+ return null;
}
+
+ if (!pe.IndexerAccessRequired)
+ return pe;
+ expr = pe;
}
skip_already_resolved_property:
public static void EmitArguments (EmitContext ec, MethodBase mb, ArrayList arguments)
{
ParameterData pd = GetParameterData (mb);
-
//
// If we are calling a params method with no arguments, special case it
//
if(argtype.IsByRef)
argtype = argtype.GetElementType();
conv = ConvertImplicit (ec, localtmp, argtype, Location.Null);
- tempvars.Add (new Assign (a.Expr, conv, Location.Null));
+ tempvars.Add (new Assign (a.Expr, conv, Location.Null));
+ } else if (a.Expr is PropertyGroupExpr) {
+ // FIXME: We shouldnt be doing Resolve from inside 'Emit'.
+ // Have to find a way to push this up to 'Resolve'
+ Expression conv;
+ if(argtype.IsByRef)
+ argtype = argtype.GetElementType();
+ conv = ConvertImplicit (ec, localtmp, argtype, Location.Null);
+ Assign assgn = new Assign (a.Expr, conv, Location.Null);
+ Expression e = assgn.Resolve (ec);
+ tempvars.Add (e);
}
localtmp.Store (ec);
a = new Argument (localtmp, a.ArgType);
}
}
+/*
static void EmitPropertyArgs (EmitContext ec, ArrayList prop_args)
{
int top = prop_args.Count;
a.Emit (ec);
}
}
+*/
public override void Emit (EmitContext ec)
{
MethodGroupExpr mg = (MethodGroupExpr) this.expr;
-
+
EmitCall (
ec, is_base, method.IsStatic, mg.InstanceExpression, method, Arguments, loc);
}
ec.ig.Emit (OpCodes.Pop);
if (tempvars != null) {
- foreach (ExpressionStatement s in tempvars)
- s.EmitStatement (ec);
+ foreach (Expression s in tempvars) {
+ if (s is ExpressionStatement)
+ ((ExpressionStatement) s).EmitStatement (ec);
+ else
+ s.Emit (ec);
+ }
tempvars.Clear ();
}
}
}
}
+/*
void Error_NegativeArrayIndex ()
{
Error (284, "Can not create array with a negative size");
return target;
}
+*/
//
// Creates the type of the array
public readonly string Identifier;
Expression expr;
Expression member_lookup;
- bool is_invocation;
+ bool is_invocation = false;
bool is_left_hand;
+ bool is_addressof = false;
public MemberAccess (Expression expr, string id, Location l)
{
}
}
+ public bool IsAddressOf {
+ set {
+ is_addressof = value;
+ }
+ }
+
public bool IsLeftHand {
get {
return is_left_hand;
if (member_lookup is IMemberExpr) {
IMemberExpr me = (IMemberExpr) member_lookup;
- if (left_is_type){
- MethodGroupExpr mg = me as MethodGroupExpr;
- if ((mg != null) && left_is_explicit && left.Type.IsInterface)
- mg.IsExplicitImpl = left_is_explicit;
-
- if (!me.IsStatic){
- if (IdenticalNameAndTypeName (ec, left_original, loc))
- return member_lookup;
-
- SimpleName.Error_ObjectRefRequired (ec, loc, me.Name);
- return null;
+ if (left_is_type) {
+ if (me is PropertyGroupExpr) {
+ PropertyGroupExpr mg = me as PropertyGroupExpr;
+ if ((mg != null) && left_is_explicit && left.Type.IsInterface)
+ mg.IsExplicitImpl = left_is_explicit;
+
+ if (!me.IsStatic){
+ if (IdenticalNameAndTypeName (ec, left_original, loc))
+ return member_lookup;
+
+ SimpleName.Error_ObjectRefRequired (ec, loc, me.Name);
+ return null;
+ }
+ } else {
+ MethodGroupExpr mg = me as MethodGroupExpr;
+ if ((mg != null) && left_is_explicit && left.Type.IsInterface)
+ mg.IsExplicitImpl = left_is_explicit;
+
+ if (!me.IsStatic){
+ if (IdenticalNameAndTypeName (ec, left_original, loc))
+ return member_lookup;
+
+ SimpleName.Error_ObjectRefRequired (ec, loc, me.Name);
+ return null;
+ }
}
} else {
SimpleName child_expr = (SimpleName) expr;
Expression new_expr = new SimpleName (child_expr.Name + "." + Identifier, loc);
+ ((SimpleName) new_expr).IsInvocation = is_invocation;
if ((flags & ResolveFlags.MaskExprClass) == ResolveFlags.Type)
return new_expr.Resolve (ec, flags);
}
member_lookup = MemberLookup (ec, expr_type, Identifier, loc);
-
if (member_lookup == null)
{
// Error has already been reported.
if (member_lookup == null)
return null;
+ if ((member_lookup is MethodGroupExpr) && ! is_invocation && !is_addressof) {
+ Expression inv = new Invocation (this, new ArrayList (), loc);
+ return inv.Resolve (ec);
+ }
+
+ if (member_lookup is PropertyGroupExpr && is_invocation) // As we dont know the arguments yet
+ return member_lookup;
+
// The following DoResolve/DoResolveLValue will do the definite assignment
// check.
if (right_side != null)
else
member_lookup = member_lookup.DoResolve (ec);
+
return member_lookup;
}
return ix;
}
}
-
- if (lookup_type != TypeManager.object_type)
- Report.Error (21, loc,
- "Type '" + TypeManager.MonoBASIC_Name (lookup_type) +
- "' does not have any indexers defined");
return null;
}
}
MethodInfo get, set;
Indexers ilist;
ArrayList set_arguments;
- bool is_base_indexer;
+ //bool is_base_indexer;
protected Type indexer_type;
protected Type current_type;
Location loc)
{
this.instance_expr = instance_expr;
- this.is_base_indexer = is_base_indexer;
+ //this.is_base_indexer = is_base_indexer;
this.eclass = ExprClass.Value;
this.loc = loc;
}
//
// This is a group of properties, piles of them.
- if (ilist == null)
+ if (ilist == null) {
ilist = Indexers.GetIndexersForType (
current_type, indexer_type, loc);
+ if (ilist == null && indexer_type != TypeManager.object_type) {
+ Report.Error (21, loc,
+ "Type '" + TypeManager.MonoBASIC_Name (indexer_type) +
+ "' does not have any indexers defined");
+ return null;
+ }
+ }
+
//
// Step 2: find the proper match
//
Type right_type = right_side.Type;
- if (ilist == null)
+ if (ilist == null) {
ilist = Indexers.GetIndexersForType (
current_type, indexer_type, loc);
+ if (ilist == null && indexer_type != TypeManager.object_type) {
+ Report.Error (21, loc,
+ "Type '" + TypeManager.MonoBASIC_Name (indexer_type) +
+ "' does not have any indexers defined");
+ return null;
+ }
+ }
if (ilist != null && ilist.setters != null && ilist.setters.Count > 0){
set_arguments = (ArrayList) arguments.Clone ();