Changeset 519 for trunk/src

Show
Ignore:
Timestamp:
01/23/11 04:26:02 (1 year ago)
Author:
jmdavis
Message:

Added Throwable and default arguments to most Exception and Error constructors.

For whatever reason, a number of Exception and Error types didn't take a
Throwable for chaining exceptions, and most of them didn't have default
arguments for file and line number (some didn't even take file and line
number in the first place). So, most of the Exception and Error types in
core.exception and object_.d/object.di now have take an optional
Throwable argument and optional file and line number arguments which
default to FILE and LINE. In at least one case (AssertError?), I
couldn't make it take default arguments for file and line number without
breaking code, so it doesn't. But if I could do it and maintain
backwards comptability, I did. I also added unit tests to verify that
the various constructors work properly.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/src/core/exception.d

    r408 r519  
    33 * mechanism to alter system-level error handling. 
    44 * 
    5  * Copyright: Copyright Sean Kelly 2005 - 2009
     5 * Copyright: Copyright Sean Kelly 2005 - 2011
    66 * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) 
    7  * Authors:   Sean Kelly 
     7 * Authors:   Sean Kelly and Jonathan M Davis 
    88 * Source:    $(DRUNTIMESRC core/_exception.d) 
    99 */ 
    1010 
    11 /*          Copyright Sean Kelly 2005 - 2009
     11/*          Copyright Sean Kelly 2005 - 2011
    1212 * Distributed under the Boost Software License, Version 1.0. 
    1313 *    (See accompanying file LICENSE_1_0.txt or copy at 
     
    3434class RangeError : Error 
    3535{ 
     36    this( string file = __FILE__, size_t line = __LINE__, Throwable next = null ) 
     37    { 
     38        super( "Range violation", file, line, next ); 
     39    } 
     40} 
     41 
     42unittest 
     43{ 
     44    { 
     45        auto re = new RangeError(); 
     46        assert(re.file == __FILE__); 
     47        assert(re.line == __LINE__ - 2); 
     48        assert(re.next is null); 
     49        assert(re.msg == "Range violation"); 
     50    } 
     51 
     52    { 
     53        auto re = new RangeError("hello", 42, new Exception("It's an Exception!")); 
     54        assert(re.file == "hello"); 
     55        assert(re.line == 42); 
     56        assert(re.next !is null); 
     57        assert(re.msg == "Range violation"); 
     58    } 
     59} 
     60 
     61 
     62/** 
     63 * Thrown on an assert error. 
     64 */ 
     65class AssertError : Error 
     66{ 
    3667    this( string file, size_t line ) 
    3768    { 
    38         super( "Range violation", file, line ); 
    39     } 
    40 
    41  
    42  
    43 /** 
    44  * Thrown on an assert error. 
    45  */ 
    46 class AssertError : Error 
    47 
    48     this( string file, size_t line ) 
    49     { 
    50         super( "Assertion failure", file, line ); 
    51     } 
    52  
    53     this( string msg, string file, size_t line ) 
    54     { 
    55         super( msg, file, line ); 
     69        this(cast(Throwable)null, file, line); 
     70    } 
     71 
     72    this( Throwable next, string file = __FILE__, size_t line = __LINE__ ) 
     73    { 
     74        this( "Assertion failure", file, line, next); 
     75    } 
     76 
     77    this( string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null ) 
     78    { 
     79        super( msg, file, line, next ); 
     80    } 
     81
     82 
     83unittest 
     84
     85    { 
     86        auto ae = new AssertError("hello", 42); 
     87        assert(ae.file == "hello"); 
     88        assert(ae.line == 42); 
     89        assert(ae.next is null); 
     90        assert(ae.msg == "Assertion failure"); 
     91    } 
     92 
     93    { 
     94        auto ae = new AssertError(new Exception("It's an Exception!")); 
     95        assert(ae.file == __FILE__); 
     96        assert(ae.line == __LINE__ - 2); 
     97        assert(ae.next !is null); 
     98        assert(ae.msg == "Assertion failure"); 
     99    } 
     100 
     101    { 
     102        auto ae = new AssertError(new Exception("It's an Exception!"), "hello", 42); 
     103        assert(ae.file == "hello"); 
     104        assert(ae.line == 42); 
     105        assert(ae.next !is null); 
     106        assert(ae.msg == "Assertion failure"); 
     107    } 
     108 
     109    { 
     110        auto ae = new AssertError("msg"); 
     111        assert(ae.file == __FILE__); 
     112        assert(ae.line == __LINE__ - 2); 
     113        assert(ae.next is null); 
     114        assert(ae.msg == "msg"); 
     115    } 
     116 
     117    { 
     118        auto ae = new AssertError("msg", "hello", 42); 
     119        assert(ae.file == "hello"); 
     120        assert(ae.line == 42); 
     121        assert(ae.next is null); 
     122        assert(ae.msg == "msg"); 
     123    } 
     124 
     125    { 
     126        auto ae = new AssertError("msg", "hello", 42, new Exception("It's an Exception!")); 
     127        assert(ae.file == "hello"); 
     128        assert(ae.line == 42); 
     129        assert(ae.next !is null); 
     130        assert(ae.msg == "msg"); 
    56131    } 
    57132} 
     
    65140    ClassInfo   info; 
    66141 
    67     this( ClassInfo c, Exception e = null ) 
    68     { 
    69         super( "Finalization error", e ); 
    70         info = c; 
     142    this( ClassInfo ci, Throwable next, string file = __FILE__, size_t line = __LINE__ ) 
     143    { 
     144        this(ci, file, line, next); 
     145    } 
     146 
     147    this( ClassInfo ci, string file = __FILE__, size_t line = __LINE__, Throwable next = null ) 
     148    { 
     149        super( "Finalization error", file, line, next ); 
     150        info = ci; 
    71151    } 
    72152 
     
    77157} 
    78158 
     159unittest 
     160{ 
     161    ClassInfo info = new ClassInfo; 
     162    info.name = "testInfo"; 
     163 
     164    { 
     165        auto fe = new FinalizeError(info); 
     166        assert(fe.file == __FILE__); 
     167        assert(fe.line == __LINE__ - 2); 
     168        assert(fe.next is null); 
     169        assert(fe.msg == "Finalization error"); 
     170        assert(fe.info == info); 
     171    } 
     172 
     173    { 
     174        auto fe = new FinalizeError(info, new Exception("It's an Exception!")); 
     175        assert(fe.file == __FILE__); 
     176        assert(fe.line == __LINE__ - 2); 
     177        assert(fe.next !is null); 
     178        assert(fe.msg == "Finalization error"); 
     179        assert(fe.info == info); 
     180    } 
     181 
     182    { 
     183        auto fe = new FinalizeError(info, "hello", 42); 
     184        assert(fe.file == "hello"); 
     185        assert(fe.line == 42); 
     186        assert(fe.next is null); 
     187        assert(fe.msg == "Finalization error"); 
     188        assert(fe.info == info); 
     189    } 
     190 
     191    { 
     192        auto fe = new FinalizeError(info, "hello", 42, new Exception("It's an Exception!")); 
     193        assert(fe.file == "hello"); 
     194        assert(fe.line == 42); 
     195        assert(fe.next !is null); 
     196        assert(fe.msg == "Finalization error"); 
     197        assert(fe.info == info); 
     198    } 
     199} 
     200 
    79201 
    80202/** 
     
    83205class HiddenFuncError : Error 
    84206{ 
    85     this( ClassInfo ci ) 
    86     { 
    87         super( "Hidden method called for " ~ ci.name ); 
     207    this( ClassInfo ci, string file = __FILE__, size_t line = __LINE__, Throwable next = null ) 
     208    { 
     209        super( "Hidden method called for " ~ ci.name, file, line, next ); 
     210    } 
     211
     212 
     213unittest 
     214
     215    ClassInfo info = new ClassInfo; 
     216    info.name = "testInfo"; 
     217 
     218    { 
     219        auto hfe = new HiddenFuncError(info); 
     220        assert(hfe.file == __FILE__); 
     221        assert(hfe.line == __LINE__ - 2); 
     222        assert(hfe.next is null); 
     223        assert(hfe.msg == "Hidden method called for testInfo"); 
     224    } 
     225 
     226    { 
     227        auto hfe = new HiddenFuncError(info, "hello", 42, new Exception("It's an Exception!")); 
     228        assert(hfe.file == "hello"); 
     229        assert(hfe.line == 42); 
     230        assert(hfe.next !is null); 
     231        assert(hfe.msg == "Hidden method called for testInfo"); 
    88232    } 
    89233} 
     
    95239class OutOfMemoryError : Error 
    96240{ 
    97     this( string file, size_t line
    98     { 
    99         super( "Memory allocation failed", file, line ); 
     241    this(string file = __FILE__, size_t line = __LINE__, Throwable next = null
     242    { 
     243        super( "Memory allocation failed", file, line, next ); 
    100244    } 
    101245 
     
    106250} 
    107251 
     252unittest 
     253{ 
     254    { 
     255        auto oome = new OutOfMemoryError(); 
     256        assert(oome.file == __FILE__); 
     257        assert(oome.line == __LINE__ - 2); 
     258        assert(oome.next is null); 
     259        assert(oome.msg == "Memory allocation failed"); 
     260    } 
     261 
     262    { 
     263        auto oome = new OutOfMemoryError("hello", 42, new Exception("It's an Exception!")); 
     264        assert(oome.file == "hello"); 
     265        assert(oome.line == 42); 
     266        assert(oome.next !is null); 
     267        assert(oome.msg == "Memory allocation failed"); 
     268    } 
     269} 
     270 
    108271 
    109272/** 
     
    112275class SwitchError : Error 
    113276{ 
    114     this( string file, size_t line ) 
    115     { 
    116         super( "No appropriate switch clause found", file, line ); 
     277    this( string file = __FILE__, size_t line = __LINE__, Throwable next = null ) 
     278    { 
     279        super( "No appropriate switch clause found", file, line, next ); 
     280    } 
     281
     282 
     283unittest 
     284
     285    { 
     286        auto se = new SwitchError(); 
     287        assert(se.file == __FILE__); 
     288        assert(se.line == __LINE__ - 2); 
     289        assert(se.next is null); 
     290        assert(se.msg == "No appropriate switch clause found"); 
     291    } 
     292 
     293    { 
     294        auto se = new SwitchError("hello", 42, new Exception("It's an Exception!")); 
     295        assert(se.file == "hello"); 
     296        assert(se.line == 42); 
     297        assert(se.next !is null); 
     298        assert(se.msg == "No appropriate switch clause found"); 
    117299    } 
    118300} 
     
    126308    size_t idx; 
    127309 
    128     this( string msg, size_t idx
    129     { 
    130         super( msg ); 
     310    this( string msg, size_t idx, string file = __FILE__, size_t line = __LINE__, Throwable next = null
     311    { 
     312        super( msg, file, line, next ); 
    131313        this.idx = idx; 
     314    } 
     315} 
     316 
     317unittest 
     318{ 
     319    { 
     320        auto ue = new UnicodeException("msg", 2); 
     321        assert(ue.file == __FILE__); 
     322        assert(ue.line == __LINE__ - 2); 
     323        assert(ue.next is null); 
     324        assert(ue.msg == "msg"); 
     325        assert(ue.idx == 2); 
     326    } 
     327 
     328    { 
     329        auto ue = new UnicodeException("msg", 2, "hello", 42, new Exception("It's an Exception!")); 
     330        assert(ue.file == "hello"); 
     331        assert(ue.line == 42); 
     332        assert(ue.next !is null); 
     333        assert(ue.msg == "msg"); 
     334        assert(ue.idx == 2); 
    132335    } 
    133336} 
     
    164367 *  line = The line number on which this error occurred. 
    165368 */ 
    166 extern (C) void onAssertError( string file, size_t line
     369extern (C) void onAssertError( string file = __FILE__, size_t line = __LINE__
    167370{ 
    168371    if( assertHandler is null ) 
     
    220423 *  RangeError. 
    221424 */ 
    222 extern (C) void onRangeError( string file, size_t line
    223 { 
    224     throw new RangeError( file, line ); 
     425extern (C) void onRangeError( string file = __FILE__, size_t line = __LINE__, Throwable next = null
     426{ 
     427    throw new RangeError( file, line, next ); 
    225428} 
    226429 
     
    235438 *  FinalizeError. 
    236439 */ 
    237 extern (C) void onFinalizeError( ClassInfo info, Exception ex
    238 { 
    239     throw new FinalizeError( info, ex ); 
     440extern (C) void onFinalizeError( ClassInfo info, Exception e, string file = __FILE__, size_t line = __LINE__
     441{ 
     442    throw new FinalizeError( info, file, line, e ); 
    240443} 
    241444 
     
    248451 *  HiddenFuncError. 
    249452 */ 
    250 extern (C) void onHiddenFuncError( Object o
    251 { 
    252     throw new HiddenFuncError( o.classinfo ); 
     453extern (C) void onHiddenFuncError( Object o, string file = __FILE__, size_t line = __LINE__, Throwable next = null
     454{ 
     455    throw new HiddenFuncError( o.classinfo, file, line, next ); 
    253456} 
    254457 
     
    279482 *  SwitchError. 
    280483 */ 
    281 extern (C) void onSwitchError( string file, size_t line
    282 { 
    283     throw new SwitchError( file, line ); 
     484extern (C) void onSwitchError( string file = __FILE__, size_t line = __LINE__, Throwable next = null
     485{ 
     486    throw new SwitchError( file, line, next ); 
    284487} 
    285488 
     
    295498 *  UnicodeException. 
    296499 */ 
    297 extern (C) void onUnicodeError( string msg, size_t idx
    298 { 
    299     throw new UnicodeException( msg, idx ); 
    300 } 
     500extern (C) void onUnicodeError( string msg, size_t idx, string file = __FILE__, size_t line = __LINE__
     501{ 
     502    throw new UnicodeException( msg, idx, file, line ); 
     503} 
  • trunk/src/object_.d

    r509 r519  
    66 *      WIKI = Object 
    77 * 
    8  * Copyright: Copyright Digital Mars 2000 - 2010
     8 * Copyright: Copyright Digital Mars 2000 - 2011
    99 * License:   <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>. 
    1010 * Authors:   Walter Bright, Sean Kelly 
    1111 */ 
    1212 
    13 /*          Copyright Digital Mars 2000 - 2009
     13/*          Copyright Digital Mars 2000 - 2011
    1414 * Distributed under the Boost Software License, Version 1.0. 
    1515 *    (See accompanying file LICENSE_1_0.txt or copy at 
     
    13241324class Exception : Throwable 
    13251325{ 
    1326     this(string msg, Throwable next = null) 
    1327     { 
    1328         super(msg, next); 
    1329     } 
    1330  
    1331     this(string msg, string file, size_t line, Throwable next = null) 
     1326 
     1327    this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null) 
    13321328    { 
    13331329        super(msg, file, line, next); 
    13341330    } 
     1331    this(string msg, Throwable next, string file = __FILE__, size_t line = __LINE__) 
     1332    { 
     1333        super(msg, file, line, next); 
     1334    } 
     1335} 
     1336 
     1337unittest 
     1338{ 
     1339    { 
     1340        auto e = new Exception("msg"); 
     1341        assert(e.file == __FILE__); 
     1342        assert(e.line == __LINE__ - 2); 
     1343        assert(e.next is null); 
     1344        assert(e.msg == "msg"); 
     1345    } 
     1346 
     1347    { 
     1348        auto e = new Exception("msg", new Exception("It's an Excepton!"), "hello", 42); 
     1349        assert(e.file == "hello"); 
     1350        assert(e.line == 42); 
     1351        assert(e.next !is null); 
     1352        assert(e.msg == "msg"); 
     1353    } 
     1354 
     1355    { 
     1356        auto e = new Exception("msg", "hello", 42, new Exception("It's an Exception!")); 
     1357        assert(e.file == "hello"); 
     1358        assert(e.line == 42); 
     1359        assert(e.next !is null); 
     1360        assert(e.msg == "msg"); 
     1361    } 
    13351362} 
    13361363 
     
    13381365class Error : Throwable 
    13391366{ 
    1340     this(string msg, Throwable next = null) 
    1341     { 
    1342         super(msg, next); 
    1343         bypassedException = null; 
    1344     } 
    1345  
    1346     this(string msg, string file, size_t line, Throwable next = null) 
     1367    this(string msg, Throwable next, string file = __FILE__, size_t line = __LINE__) 
    13471368    { 
    13481369        super(msg, file, line, next); 
    13491370        bypassedException = null; 
    13501371    } 
     1372 
     1373    this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null) 
     1374    { 
     1375        super(msg, file, line, next); 
     1376        bypassedException = null; 
     1377    } 
     1378 
    13511379    /// The first Exception which was bypassed when this Error was thrown, 
    13521380    /// or null if no Exceptions were pending. 
    13531381    Throwable   bypassedException; 
     1382} 
     1383 
     1384unittest 
     1385{ 
     1386    { 
     1387        auto e = new Error("msg"); 
     1388        assert(e.file == __FILE__); 
     1389        assert(e.line == __LINE__ - 2); 
     1390        assert(e.next is null); 
     1391        assert(e.msg == "msg"); 
     1392        assert(e.bypassedException is null); 
     1393    } 
     1394 
     1395    { 
     1396        auto e = new Error("msg", new Exception("It's an Excepton!"), "hello", 42); 
     1397        assert(e.file == "hello"); 
     1398        assert(e.line == 42); 
     1399        assert(e.next !is null); 
     1400        assert(e.msg == "msg"); 
     1401        assert(e.bypassedException is null); 
     1402    } 
     1403 
     1404    { 
     1405        auto e = new Error("msg", "hello", 42, new Exception("It's an Exception!")); 
     1406        assert(e.file == "hello"); 
     1407        assert(e.line == 42); 
     1408        assert(e.next !is null); 
     1409        assert(e.msg == "msg"); 
     1410        assert(e.bypassedException is null); 
     1411    } 
    13541412} 
    13551413