TARGET_JVM icon support
[mono.git] / mcs / mcs / statement.cs
index d362d00aeb2cb978fdcdf20eb5f831b6c5b51ba5..7d70945eca849c1b7146c0755aaf7a127d440dbb 100644 (file)
@@ -46,8 +46,8 @@ namespace Mono.CSharp {
                        // in unreachable code, for instance.
                        //
 
-                       if (warn && (RootContext.WarningLevel >= 2))
-                               Report.Warning (162, loc, "Unreachable code detected");
+                       if (warn)
+                               Report.Warning (162, 2, loc, "Unreachable code detected");
 
                        ec.StartFlowBranching (FlowBranching.BranchingType.Block, loc);
                        bool ok = Resolve (ec);
@@ -808,7 +808,7 @@ namespace Mono.CSharp {
                        sl = (SwitchLabel) ec.Switch.Elements [val];
 
                        if (sl == null){
-                               Report.Error (159, loc, "No such label `case {0}:' within the scope of the goto statement", c.GetValue () == null ? "null" : val);
+                               Report.Error (159, loc, "No such label `case {0}:' within the scope of the goto statement", c.GetValue () == null ? "null" : val.ToString ());
                                return false;
                        }
 
@@ -1239,7 +1239,7 @@ namespace Mono.CSharp {
                //
                // Keeps track of (name, type) pairs
                //
-               Hashtable variables;
+               IDictionary variables;
 
                //
                // Keeps track of constants
@@ -1309,10 +1309,10 @@ namespace Mono.CSharp {
                        get { return this_id; }
                }
 
-               protected Hashtable Variables {
+               protected IDictionary Variables {
                        get {
                                if (variables == null)
-                                       variables = new Hashtable ();
+                                       variables = new ListDictionary ();
                                return variables;
                        }
                }
@@ -1563,6 +1563,9 @@ namespace Mono.CSharp {
                                constants = new Hashtable ();
 
                        constants.Add (name, value);
+
+                       // A block is considered used if we perform an initialization in a local declaration, even if it is constant.
+                       Use ();
                        return true;
                }
 
@@ -1612,15 +1615,6 @@ namespace Mono.CSharp {
                        return null;
                }
                
-               /// <summary>
-               ///   True if the variable named @name is a constant
-               ///  </summary>
-               public bool IsConstant (string name)
-               {
-                       Expression e = GetConstantExpression (name);
-                       return e != null;
-               }
-
                public void AddStatement (Statement s)
                {
                        statements.Add (s);
@@ -1676,7 +1670,7 @@ namespace Mono.CSharp {
                ///   tc: is our typecontainer (to resolve type references)
                ///   ig: is the code generator:
                /// </remarks>
-               public void ResolveMeta (ToplevelBlock toplevel, EmitContext ec, InternalParameters ip)
+               public void ResolveMeta (ToplevelBlock toplevel, EmitContext ec, Parameters ip)
                {
                        bool old_unsafe = ec.InUnsafe;
 
@@ -1743,8 +1737,15 @@ namespace Mono.CSharp {
                                        if (cv == null)
                                                continue;
 
+                                       // Don't let 'const int Foo = Foo;' succeed.
+                                       // Removing the name from 'constants' ensures that we get a LocalVariableReference below,
+                                       // which in turn causes the 'must be constant' error to be triggered.
+                                       constants.Remove (name);
+
                                        ec.CurrentBlock = this;
                                        Expression e = cv.Resolve (ec);
+                                       if (e == null)
+                                               continue;
 
                                        Constant ce = e as Constant;
                                        if (ce == null){
@@ -1756,7 +1757,6 @@ namespace Mono.CSharp {
                                        if (e == null)
                                                continue;
 
-                                       constants.Remove (name);
                                        constants.Add (name, e);
                                }
                        }
@@ -1837,9 +1837,9 @@ namespace Mono.CSharp {
                                        name = (string) de.Key;
 
                                        if (vector.IsAssigned (vi.VariableInfo)){
-                                               Report.Warning (219, vi.Location, "The variable `{0}' is assigned but its value is never used", name);
+                                               Report.Warning (219, 3, vi.Location, "The variable `{0}' is assigned but its value is never used", name);
                                        } else {
-                                               Report.Warning (168, vi.Location, "The variable `{0}' is declared but never used", name);
+                                               Report.Warning (168, 3, vi.Location, "The variable `{0}' is declared but never used", name);
                                        }
                                }
                        }
@@ -1903,12 +1903,14 @@ namespace Mono.CSharp {
                                // Warn if we detect unreachable code.
                                //
                                if (unreachable) {
+                                       if (s is EmptyStatement)
+                                               continue;
+
                                        if (s is Block)
                                                ((Block) s).unreachable = true;
 
-                                       if (!unreachable_shown && (RootContext.WarningLevel >= 2)) {
-                                               Report.Warning (
-                                                       162, s.loc, "Unreachable code detected");
+                                       if (!unreachable_shown) {
+                                               Report.Warning (162, 2, s.loc, "Unreachable code detected");
                                                unreachable_shown = true;
                                        }
                                }
@@ -1954,7 +1956,7 @@ namespace Mono.CSharp {
                        if ((labels != null) && (RootContext.WarningLevel >= 2)) {
                                foreach (LabeledStatement label in labels.Values)
                                        if (!label.HasBeenReferenced)
-                                               Report.Warning (164, label.loc,
+                                               Report.Warning (164, 2, label.loc,
                                                                "This label has not been referenced");
                        }
 
@@ -1978,8 +1980,8 @@ namespace Mono.CSharp {
                        unreachable_shown = true;
                        unreachable = true;
 
-                       if (warn && (RootContext.WarningLevel >= 2))
-                               Report.Warning (162, loc, "Unreachable code detected");
+                       if (warn)
+                               Report.Warning (162, 2, loc, "Unreachable code detected");
 
                        ec.StartFlowBranching (FlowBranching.BranchingType.Block, loc);
                        bool ok = Resolve (ec);
@@ -2205,7 +2207,7 @@ namespace Mono.CSharp {
                                Parameters pars = t.Parameters;
                                par = pars.GetParameterByName (name, out idx);
                                if (par != null)
-                                       return new ParameterReference (pars, this, idx, name, loc);
+                                       return new ParameterReference (par, this, idx, loc);
                        }
                        return null;
                }
@@ -2267,7 +2269,7 @@ namespace Mono.CSharp {
                        return this_variable == null || this_variable.IsThisAssigned (ec, loc);
                }
 
-               public bool ResolveMeta (EmitContext ec, InternalParameters ip)
+               public bool ResolveMeta (EmitContext ec, Parameters ip)
                {
                        int errors = Report.Errors;
 
@@ -2350,7 +2352,7 @@ namespace Mono.CSharp {
                                return false;
                        }
 
-                       if (required_type == TypeManager.string_type && e is NullLiteral) {
+                       if (required_type == TypeManager.string_type && c.GetValue () == null) {
                                converted = NullStringCase;
                                return true;
                        }
@@ -2368,7 +2370,7 @@ namespace Mono.CSharp {
                        string label;
                        if (converted == null)
                                label = "default";
-                       else if (converted is NullLiteral)
+                       else if (converted == NullStringCase)
                                label = "null";
                        else
                                label = converted.ToString ();
@@ -3282,7 +3284,7 @@ namespace Mono.CSharp {
                        public abstract void EmitExit (ILGenerator ig);
                }
 
-               class ExpressionEmitter: Emitter {
+               class ExpressionEmitter : Emitter {
                        public ExpressionEmitter (Expression converted, LocalInfo li) :
                                base (converted, li)
                        {
@@ -3304,7 +3306,7 @@ namespace Mono.CSharp {
                        }
                }
 
-               class StringEmitter: Emitter {
+               class StringEmitter : Emitter {
                        LocalBuilder pinned_string;
                        Location loc;
 
@@ -3423,7 +3425,7 @@ namespace Mono.CSharp {
                                                return false;
 
                                        if (!Convert.ImplicitConversionExists (ec, e, expr_type)) {
-                                               Convert.Error_CannotImplicitConversion (e.Location, e.Type, expr_type);
+                                               e.Error_ValueCannotBeConverted (e.Location, expr_type, false);
                                                return false;
                                        }
 
@@ -3545,7 +3547,7 @@ namespace Mono.CSharp {
                }
        }
        
-       public class Catch: Statement {
+       public class Catch : Statement {
                public readonly string Name;
                public readonly Block  Block;
 
@@ -3675,6 +3677,14 @@ namespace Mono.CSharp {
                        Report.Debug (1, "END OF CATCH BLOCKS", ec.CurrentBranching);
 
                        if (General != null){
+                               if (CodeGen.Assembly.WrapNonExceptionThrows) {
+                                       foreach (Catch c in Specific){
+                                               if (c.CatchType == TypeManager.exception_type) {
+                                                       Report.Warning (1058, 1, c.loc, "A previous catch clause already catches all exceptions. All non-exceptions thrown will be wrapped in a `System.Runtime.CompilerServices.RuntimeWrappedException'");
+                                               }
+                                       }
+                               }
+
                                ec.CurrentBranching.CreateSibling (
                                        General.Block, FlowBranching.SiblingType.Catch);
 
@@ -3746,12 +3756,15 @@ namespace Mono.CSharp {
                                        if (vi == null)
                                                throw new Exception ("Variable does not exist in this block");
 
-                                       ig.Emit (OpCodes.Stloc, vi.LocalBuilder);
                                        if (vi.IsCaptured){
+                                               LocalBuilder e = ig.DeclareLocal (vi.VariableType);
+                                               ig.Emit (OpCodes.Stloc, e);
+                                               
                                                ec.EmitCapturedVariableInstance (vi);
-                                               ig.Emit (OpCodes.Ldloc, vi.LocalBuilder);
+                                               ig.Emit (OpCodes.Ldloc, e);
                                                ig.Emit (OpCodes.Stfld, vi.FieldBuilder);
-                                       }
+                                       } else
+                                               ig.Emit (OpCodes.Stloc, vi.LocalBuilder);
                                } else
                                        ig.Emit (OpCodes.Pop);
                                
@@ -3933,7 +3946,7 @@ namespace Mono.CSharp {
                                                MethodInfo mi = null;
 
                                                foreach (MethodInfo mk in ((MethodGroupExpr) ml).Methods) {
-                                                       if (TypeManager.GetArgumentTypes (mk).Length == 0) {
+                                                       if (TypeManager.GetParameterData (mk).Count == 0) {
                                                                mi = mk;
                                                                break;
                                                        }
@@ -4003,7 +4016,7 @@ namespace Mono.CSharp {
                                        MethodInfo mi = null;
 
                                        foreach (MethodInfo mk in ((MethodGroupExpr) ml).Methods) {
-                                               if (TypeManager.GetArgumentTypes (mk).Length == 0) {
+                                               if (TypeManager.GetParameterData (mk).Count == 0) {
                                                        mi = mk;
                                                        break;
                                                }
@@ -4113,7 +4126,8 @@ namespace Mono.CSharp {
                        if (expr == null)
                                return false;
 
-                       if (expr is NullLiteral) {
+                       Constant c = expr as Constant;
+                       if (c != null && c.GetValue () == null) {
                                Report.Error (186, loc, "Use of null is not valid in this context");
                                return false;
                        }
@@ -4413,10 +4427,8 @@ namespace Mono.CSharp {
 
                                foreach (MemberInfo m in move_next_list){
                                        MethodInfo mi = (MethodInfo) m;
-                                       Type [] args;
                                
-                                       args = TypeManager.GetArgumentTypes (mi);
-                                       if ((args != null) && (args.Length == 0) &&
+                                       if ((TypeManager.GetParameterData (mi).Count == 0) &&
                                            TypeManager.TypeToCoreType (mi.ReturnType) == TypeManager.bool_type) {
                                                move_next = mi;
                                                return true;
@@ -4457,10 +4469,8 @@ namespace Mono.CSharp {
 
                                foreach (MemberInfo m in dispose_list){
                                        MethodInfo mi = (MethodInfo) m;
-                                       Type [] args;
 
-                                       args = TypeManager.GetArgumentTypes (mi);
-                                       if (args != null && args.Length == 0){
+                                       if (TypeManager.GetParameterData (mi).Count == 0){
                                                if (mi.ReturnType == TypeManager.void_type)
                                                        return mi;
                                        }
@@ -4488,8 +4498,7 @@ namespace Mono.CSharp {
                                        return false;
 
                                foreach (MethodBase mb in mg.Methods) {
-                                       Type [] args = TypeManager.GetArgumentTypes (mb);
-                                       if (args != null && args.Length != 0)
+                                       if (TypeManager.GetParameterData (mb).Count != 0)
                                                continue;
                        
                                        // Check whether GetEnumerator is public