1 // SDLang-D 2 // Written in the D programming language. 3 4 module sdlang.exception; 5 6 import std.array; 7 import std.exception; 8 import std.range; 9 import std.stdio; 10 import std..string; 11 12 import sdlang.ast; 13 import sdlang.util; 14 15 /// Abstract parent class of all SDLang-D defined exceptions. 16 abstract class SDLangException : Exception 17 { 18 this(string msg, string file = __FILE__, size_t line = __LINE__) 19 { 20 super(msg, file, line); 21 } 22 } 23 24 /// Thrown when a syntax error is encounterd while parsing. 25 class ParseException : SDLangException 26 { 27 Location location; 28 bool hasLocation; 29 30 this(string msg, string file = __FILE__, size_t line = __LINE__) 31 { 32 hasLocation = false; 33 super(msg, file, line); 34 } 35 36 this(Location location, string msg, string file = __FILE__, size_t line = __LINE__) 37 { 38 hasLocation = true; 39 super("%s: %s".format(location.toString(), msg), file, line); 40 } 41 } 42 43 /// Compatibility alias 44 deprecated("The new name is ParseException") 45 alias SDLangParseException = ParseException; 46 47 /++ 48 Thrown when attempting to do something in the DOM that's unsupported, such as: 49 50 $(UL 51 $(LI Adding the same instance of a tag or attribute to more than one parent.) 52 $(LI Writing SDLang where: 53 $(UL 54 $(LI The root tag has values, attributes or a namespace. ) 55 $(LI An anonymous tag has a namespace. ) 56 $(LI An anonymous tag has no values. ) 57 $(LI A floating point value is infinity or NaN. ) 58 ) 59 )) 60 +/ 61 class ValidationException : SDLangException 62 { 63 this(string msg, string file = __FILE__, size_t line = __LINE__) 64 { 65 super(msg, file, line); 66 } 67 } 68 69 /// Compatibility alias 70 deprecated("The new name is ValidationException") 71 alias SDLangValidationException = ValidationException; 72 73 /// Thrown when someting is wrong with the provided arguments to a function. 74 class ArgumentException : SDLangException 75 { 76 this(string msg, string file = __FILE__, size_t line = __LINE__) 77 { 78 super(msg, file, line); 79 } 80 } 81 82 /// Thrown by the DOM on empty range and out-of-range conditions. 83 abstract class DOMException : SDLangException 84 { 85 Tag base; /// The tag searched from 86 87 this(Tag base, string msg, string file = __FILE__, size_t line = __LINE__) 88 { 89 this.base = base; 90 super(msg, file, line); 91 } 92 93 /// Prefixes a message with file/line information from the tag (if tag exists). 94 /// Optionally takes output range as a sink. 95 string customMsg(string msg) 96 { 97 if(!base) 98 return msg; 99 100 Appender!string sink; 101 this.customMsg(sink, msg); 102 return sink.data; 103 } 104 105 ///ditto 106 void customMsg(Sink)(ref Sink sink, string msg) if(isOutputRange!(Sink,char)) 107 { 108 if(base) 109 { 110 sink.put(base.location.toString()); 111 sink.put(": "); 112 sink.put(msg); 113 } 114 else 115 sink.put(msg); 116 } 117 118 /// Outputs a message to stderr, prefixed with file/line information 119 void writeCustomMsg(string msg) 120 { 121 stderr.writeln( customMsg(msg) ); 122 } 123 } 124 125 /// Thrown by the DOM on empty range and out-of-range conditions. 126 class DOMRangeException : DOMException 127 { 128 this(Tag base, string msg, string file = __FILE__, size_t line = __LINE__) 129 { 130 super(base, msg, file, line); 131 } 132 } 133 134 /// Compatibility alias 135 deprecated("The new name is DOMRangeException") 136 alias SDLangRangeException = DOMRangeException; 137 138 /// Abstract parent class of `TagNotFoundException`, `ValueNotFoundException` 139 /// and `AttributeNotFoundException`. 140 /// 141 /// Thrown by the DOM's `sdlang.ast.Tag.expectTag`, etc. functions if a matching element isn't found. 142 abstract class DOMNotFoundException : DOMException 143 { 144 FullName tagName; /// The tag searched for 145 146 this(Tag base, FullName tagName, string msg, string file = __FILE__, size_t line = __LINE__) 147 { 148 this.tagName = tagName; 149 super(base, msg, file, line); 150 } 151 } 152 153 /// Thrown by the DOM's `sdlang.ast.Tag.expectTag`, etc. functions if a Tag isn't found. 154 class TagNotFoundException : DOMNotFoundException 155 { 156 this(Tag base, FullName tagName, string msg, string file = __FILE__, size_t line = __LINE__) 157 { 158 super(base, tagName, msg, file, line); 159 } 160 } 161 162 /// Thrown by the DOM's `sdlang.ast.Tag.expectValue`, etc. functions if a Value isn't found. 163 class ValueNotFoundException : DOMNotFoundException 164 { 165 /// Expected type for the not-found value. 166 TypeInfo valueType; 167 168 this(Tag base, FullName tagName, TypeInfo valueType, string msg, string file = __FILE__, size_t line = __LINE__) 169 { 170 this.valueType = valueType; 171 super(base, tagName, msg, file, line); 172 } 173 } 174 175 /// Thrown by the DOM's `sdlang.ast.Tag.expectAttribute`, etc. functions if an Attribute isn't found. 176 class AttributeNotFoundException : DOMNotFoundException 177 { 178 FullName attributeName; /// The attribute searched for 179 180 /// Expected type for the not-found attribute's value. 181 TypeInfo valueType; 182 183 this(Tag base, FullName tagName, FullName attributeName, TypeInfo valueType, string msg, 184 string file = __FILE__, size_t line = __LINE__) 185 { 186 this.valueType = valueType; 187 this.attributeName = attributeName; 188 super(base, tagName, msg, file, line); 189 } 190 }