Changeset 9005
- Timestamp:
- 12/06/12 12:07:31 (12 years ago)
- Location:
- trunk/sources
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.Persistence/3.3/Auxiliary/TypeName.cs
r8698 r9005 51 51 52 52 /// <summary> 53 /// Gets or sets the number of generic args for 54 /// each class in a series of nested classes. 55 /// </summary> 56 [Storable] 57 public List<int> GenericArgCounts { get; private set; } 58 59 /// <summary> 53 60 /// Gets or sets the generic args. 54 61 /// </summary> … … 103 110 /// <param name="nameSpace">The namespace.</param> 104 111 /// <param name="className">Name of the class.</param> 105 internal TypeName(string nameSpace, string className ) {112 internal TypeName(string nameSpace, string className, List<int> genericArgCounts=null) { 106 113 Namespace = nameSpace; 107 114 ClassName = className; … … 109 116 MemoryMagic = ""; 110 117 AssemblyAttribues = new Dictionary<string, string>(); 118 if (genericArgCounts != null) 119 GenericArgCounts = genericArgCounts.ToList(); 111 120 } 112 121 113 122 internal TypeName(TypeName typeName, string className = null, string nameSpace = null) { 114 Namespace = typeName.Namespace;115 ClassName = typeName.ClassName;123 Namespace = nameSpace ?? typeName.Namespace; 124 ClassName = className ?? typeName.ClassName; 116 125 GenericArgs = new List<TypeName>(typeName.GenericArgs); 117 126 AssemblyAttribues = new Dictionary<string, string>(typeName.AssemblyAttribues); … … 119 128 AssemblyName = typeName.AssemblyName; 120 129 IsReference = typeName.IsReference; 121 if (nameSpace != null) 122 Namespace = nameSpace; 123 if (className != null) 124 ClassName = className; 130 if (typeName.GenericArgCounts != null) 131 GenericArgCounts = typeName.GenericArgCounts.ToList(); 125 132 } 126 133 … … 148 155 /// </returns> 149 156 public string ToString(bool full, bool includeAssembly) { 150 StringBuilder sb = new StringBuilder();157 var sb = new StringBuilder(); 151 158 if (!string.IsNullOrEmpty(Namespace)) 152 159 sb.Append(Namespace).Append('.'); 153 sb.Append(ClassName); 160 if (GenericArgCounts != null) { 161 sb.Append(string.Join("+", 162 ClassName 163 .Split('+') 164 .Zip(GenericArgCounts, (n, c) => 165 c > 0 ? String.Format("{0}`{1}", n, c) : n))); 166 } else { 167 sb.Append(ClassName); 168 if (IsGeneric) 169 sb.Append('`').Append(GenericArgs.Count); 170 } 154 171 if (IsGeneric) { 155 sb.Append('`').Append(GenericArgs.Count).Append('['); 156 bool first = true; 157 foreach (TypeName t in GenericArgs) { 158 if (first) 159 first = false; 160 else 161 sb.Append(','); 162 sb.Append('[').Append(t.ToString(full)).Append(']'); 163 } 172 sb.Append('['); 173 sb.Append(String.Join(",", GenericArgs.Select(a => 174 string.Format("[{0}]", a.ToString(full))))); 164 175 sb.Append(']'); 165 176 } … … 174 185 } 175 186 176 public string GetTypeNameInCode(HashSet<string> omitNamespaces) { 177 StringBuilder sb = new StringBuilder(); 178 if (!string.IsNullOrEmpty(Namespace) && omitNamespaces == null || !omitNamespaces.Contains(Namespace)) 179 sb.Append(Namespace).Append('.'); 180 sb.Append(ClassName); 181 if (IsGeneric) { 182 sb.Append("<"); 183 sb.Append( 184 string.Join(", ", 185 GenericArgs 186 .Select(a => a.GetTypeNameInCode(omitNamespaces)) 187 .ToArray())); 188 sb.Append(">"); 187 private IEnumerable<string> GetNestedClassesInCode(HashSet<string> omitNamespaces, bool includeAllNamespaces) { 188 var i = 0; 189 foreach (var pair in ClassName.Split('+').Zip(GenericArgCounts, (n, c) => new {n, c})) { 190 if (pair.c == 0) { 191 yield return pair.n; 192 } 193 else { 194 yield return string.Format("{0}<{1}>", 195 pair.n, 196 string.Join(",", 197 GenericArgs 198 .GetRange(i, pair.c) 199 .Select(a => a.GetTypeNameInCode(omitNamespaces, includeAllNamespaces)))); 200 i += pair.c; 201 } 202 } 203 } 204 205 private string GetTypeNameInCode(HashSet<string> omitNamespaces, bool includeNamespaces) { 206 var sb = new StringBuilder(); 207 if (!string.IsNullOrEmpty(Namespace) && 208 (omitNamespaces == null && includeNamespaces) || 209 omitNamespaces != null && !omitNamespaces.Contains(Namespace)) 210 sb.Append(Namespace).Append('.'); 211 if (GenericArgCounts != null) { 212 sb.Append(string.Join(".", GetNestedClassesInCode(omitNamespaces, includeNamespaces))); 213 } else { 214 sb.Append(ClassName); 215 if (IsGeneric) { 216 sb.Append("<"); 217 sb.Append( 218 string.Join(", ", 219 GenericArgs 220 .Select(a => a.GetTypeNameInCode(omitNamespaces, includeNamespaces)) 221 .ToArray())); 222 sb.Append(">"); 223 } 189 224 } 190 225 sb.Append(MemoryMagic); … … 192 227 } 193 228 194 public string GetTypeNameInCode(bool includeAllNamespaces) { 195 StringBuilder sb = new StringBuilder(); 196 if (includeAllNamespaces) 197 sb.Append(Namespace).Append('.'); 198 sb.Append(ClassName); 199 if (IsGeneric) { 200 sb.Append("<"); 201 sb.Append( 202 string.Join(", ", 203 GenericArgs 204 .Select(a => a.GetTypeNameInCode(includeAllNamespaces)) 205 .ToArray())); 206 sb.Append(">"); 207 } 208 sb.Append(MemoryMagic); 209 return sb.ToString(); 229 public string GetTypeNameInCode(HashSet<string> omitNamespaces) { 230 return GetTypeNameInCode(omitNamespaces, false); 231 } 232 233 public string GetTypeNameInCode(bool includeNamespaces) { 234 return GetTypeNameInCode(null, includeNamespaces); 210 235 } 211 236 -
trunk/sources/HeuristicLab.Persistence/3.3/Auxiliary/TypeNameParser.cs
r7259 r9005 21 21 22 22 using System; 23 using System.Linq; 23 24 using System.Collections.Generic; 24 25 using System.Text; … … 46 47 /// 47 48 /// SimpleTypeSpec := (IDENTIFIER '.')* 48 /// (IDENTIFIER ' +')*49 /// (IDENTIFIER '`\d+'? '+')* 49 50 /// IDENTIFIER 50 51 /// ( '`\d+[' Generics ']' )? … … 69 70 70 71 SimpleTypeSpec := (IDENTIFIER '.')* 71 (IDENTIFIER ' +')*72 IDENTIFIER73 ( ' `\d+[' Generics ']' )?72 (IDENTIFIER '`\d+'? 73 ( '+' IDENTIFIER '`\d+'? )* 74 ( '[' Generics ']' )? 74 75 (\*|\[(\d+\.\.\d+|\d+\.\.\.|(|\*)(,(|\*))*)\])* 75 76 (',\s*' IDENTIFIER (',\s*' AssemblyProperty)* )? 76 77 77 Generics := '[' SimpleTypeSpec ']' (',[' SimpleTypeSpec ']') 78 Generics := '[' SimpleTypeSpec ']' (',[' SimpleTypeSpec ']')* 78 79 79 80 AssemblyProperty := 'Version=' Version … … 88 89 89 90 private class Token { 90 private static Dictionary<string, string> tokens = 91 new Dictionary<string, string> { 92 {"-", "DASH"}, 93 {"&", "AMPERSAND"}, 94 {".", "DOT"}, 95 {"+", "PLUS"}, 96 {",", "COMMA"}, 97 {"[", "OPEN_BRACKET"}, 98 {"]", "CLOSE_BRACKET"}, 99 {"*", "ASTERISK"}, 100 {" ", "SPACE"}, 101 {"=", "EQUALS"}, 102 {"`", "BACKTICK"} }; 103 private static Regex NumberRegex = new Regex("^\\d+$"); 104 private static Regex IdentifierRegex = new Regex("^[_a-zA-Z][_a-zA-Z0-9]*$"); 105 private static Regex TokenRegex = new Regex("[-&.+,\\[\\]* =`]|[a-f0-9]+|\\d+|[_a-zA-Z][_a-zA-Z0-9]*"); 106 public string Name { get; private set; } 91 public enum Symbol {None, Dash, Ampersand, Dot, Plus, Comma, OpenBracket, CloseBracket, Asterisk, Space, Equals, Backtick} 92 private static readonly Dictionary<string, Symbol> TOKENS = 93 new Dictionary<string, Symbol> { 94 {"-", Symbol.Dash}, 95 {"&", Symbol.Ampersand}, 96 {".", Symbol.Dot}, 97 {"+", Symbol.Plus}, 98 {",", Symbol.Comma}, 99 {"[", Symbol.OpenBracket}, 100 {"]", Symbol.CloseBracket}, 101 {"*", Symbol.Asterisk}, 102 {" ", Symbol.Space}, 103 {"=", Symbol.Equals}, 104 {"`", Symbol.Backtick}}; 105 private static readonly Regex NumberRegex = new Regex("^\\d+$"); 106 private static readonly Regex IdentifierRegex = new Regex("^[_a-zA-Z][_a-zA-Z0-9]*$"); 107 private static readonly Regex TokenRegex = new Regex("[-&.+,\\[\\]* =`]|[a-f0-9]+|\\d+|[_a-zA-Z][_a-zA-Z0-9]*"); 108 public Symbol Name { get; private set; } 107 109 public string Value { get; private set; } 108 110 public bool IsIdentifier { get; private set; } … … 111 113 private Token(string value, int pos) { 112 114 Position = pos; 113 if (tokens.ContainsKey(value)) { 114 Name = tokens[value]; 115 Name = Symbol.None; 116 if (TOKENS.ContainsKey(value)) { 117 Name = TOKENS[value]; 115 118 } else if (NumberRegex.IsMatch(value)) { 116 119 Number = int.Parse(value); … … 128 131 } 129 132 public override string ToString() { 130 if (Name != null)133 if (Name != Symbol.None) 131 134 return "Token(" + Name + ")"; 132 135 if (Value != null) … … 181 184 private TypeName TransformTypeSpec() { 182 185 TypeName t = TransformSimpleTypeSpec(); 183 t.IsReference = ConsumeToken( "AMPERSAND");186 t.IsReference = ConsumeToken(Token.Symbol.Ampersand); 184 187 return t; 185 188 } 186 189 187 190 private TypeName TransformSimpleTypeSpec() { 188 List<string> nameSpace = new List<string>(); 189 nameSpace.Add(ConsumeIdentifier()); 190 while (ConsumeToken("DOT")) 191 var nameSpace = new List<string> {ConsumeIdentifier()}; 192 while (ConsumeToken(Token.Symbol.Dot)) 191 193 nameSpace.Add(ConsumeIdentifier()); 192 List<string>className = new List<string>();194 var className = new List<string>(); 193 195 if (nameSpace.Count > 0) { 194 196 className.Add(nameSpace[nameSpace.Count - 1]); 195 197 nameSpace.RemoveAt(nameSpace.Count - 1); 196 198 } 197 while (ConsumeToken("PLUS")) 199 var genericArgCounts = new List<int> { 200 ConsumeToken(Token.Symbol.Backtick) ? ConsumeNumber() : 0 201 }; 202 while(ConsumeToken(Token.Symbol.Plus)) { 198 203 className.Add(ConsumeIdentifier()); 199 TypeName typeName = new TypeName( 204 genericArgCounts.Add(ConsumeToken(Token.Symbol.Backtick) ? ConsumeNumber() : 0); 205 } 206 var nGenericArgs = genericArgCounts.Sum(); 207 var typeName = new TypeName( 200 208 string.Join(".", nameSpace.ToArray()), 201 string.Join("+", className.ToArray())); 202 if (ConsumeToken("BACKTICK")) { 203 int nGenericArgs = ConsumeNumber(); 204 if (ConsumeToken("OPEN_BRACKET") && 205 CanConsumeToken("OPEN_BRACKET")) { 206 typeName.GenericArgs.AddRange(TransformGenerics()); 207 ConsumeToken("CLOSE_BRACKET", true); 208 } 209 } 210 StringBuilder pointerOrArray = new StringBuilder(); 209 string.Join("+", className.ToArray()), 210 nGenericArgs > genericArgCounts.Last() ? genericArgCounts : null); 211 if (nGenericArgs > 0 && ConsumeToken(Token.Symbol.OpenBracket, true)) { 212 typeName.GenericArgs.AddRange(TransformGenerics()); 213 ConsumeToken(Token.Symbol.CloseBracket, true); 214 } 215 var pointerOrArray = new StringBuilder(); 211 216 while (true) { 212 if (ConsumeToken( "ASTERSIK")) {217 if (ConsumeToken(Token.Symbol.Asterisk)) { 213 218 pointerOrArray.Append("*"); 214 } else if (ConsumeToken( "OPEN_BRACKET")) {219 } else if (ConsumeToken(Token.Symbol.OpenBracket)) { 215 220 pointerOrArray.Append('['); 216 221 ParseDimension(pointerOrArray); 217 while (ConsumeToken( "COMMA")) {222 while (ConsumeToken(Token.Symbol.Comma)) { 218 223 pointerOrArray.Append(","); 219 224 ParseDimension(pointerOrArray); 220 225 } 221 ConsumeToken( "CLOSE_BRACKET", true);226 ConsumeToken(Token.Symbol.CloseBracket, true); 222 227 pointerOrArray.Append(']'); 223 228 } else { … … 227 232 typeName.MemoryMagic = pointerOrArray.ToString(); 228 233 if (ConsumeComma()) { 229 StringBuilder sb = new StringBuilder();234 var sb = new StringBuilder(); 230 235 sb.Append(ConsumeIdentifier()); 231 while (CanConsumeToken( "DOT") ||232 CanConsumeToken( "DASH") ||236 while (CanConsumeToken(Token.Symbol.Dot) || 237 CanConsumeToken(Token.Symbol.Dash) || 233 238 CanConsumeNumber() || 234 239 CanConsumeIdentifier()) { 235 if (ConsumeToken( "DOT"))240 if (ConsumeToken(Token.Symbol.Dot)) 236 241 sb.Append('.'); 237 else if (ConsumeToken( "DASH"))242 else if (ConsumeToken(Token.Symbol.Dash)) 238 243 sb.Append('-'); 239 244 else if (CanConsumeNumber()) … … 253 258 254 259 private void ParseDimension(StringBuilder sb) { 255 if (ConsumeToken( "ASTERSIK")) {260 if (ConsumeToken(Token.Symbol.Asterisk)) { 256 261 sb.Append("*"); 257 262 } else if (CanConsumeNumber()) { 258 263 sb.Append(ConsumeNumber()); 259 ConsumeToken( "DOT", true);260 ConsumeToken( "DOT", true);261 if (ConsumeToken( "DOT")) {264 ConsumeToken(Token.Symbol.Dot, true); 265 ConsumeToken(Token.Symbol.Dot, true); 266 if (ConsumeToken(Token.Symbol.Dot)) { 262 267 sb.Append("..."); 263 268 } else { … … 268 273 269 274 private IEnumerable<TypeName> TransformGenerics() { 270 ConsumeToken( "OPEN_BRACKET", true);275 ConsumeToken(Token.Symbol.OpenBracket, true); 271 276 yield return TransformSimpleTypeSpec(); 272 ConsumeToken( "CLOSE_BRACKET", true);273 while (ConsumeToken( "COMMA")) {274 ConsumeToken( "OPEN_BRACKET", true);277 ConsumeToken(Token.Symbol.CloseBracket, true); 278 while (ConsumeToken(Token.Symbol.Comma)) { 279 ConsumeToken(Token.Symbol.OpenBracket, true); 275 280 yield return TransformSimpleTypeSpec(); 276 ConsumeToken( "CLOSE_BRACKET", true);281 ConsumeToken(Token.Symbol.CloseBracket, true); 277 282 } 278 283 } … … 280 285 private KeyValuePair<string, string> TransformAssemblyProperty() { 281 286 if (ConsumeIdentifier("Version")) { 282 ConsumeToken( "EQUALS", true);287 ConsumeToken(Token.Symbol.Equals, true); 283 288 return new KeyValuePair<string, string>( 284 289 "Version", … … 300 305 301 306 private KeyValuePair<string, string> ConsumeAssignment(string name) { 302 ConsumeToken( "EQUALS", true);307 ConsumeToken(Token.Symbol.Equals, true); 303 308 return new KeyValuePair<string, string>(name, ConsumeToken()); 304 309 } … … 307 312 StringBuilder version = new StringBuilder(); 308 313 version.Append(ConsumeNumber()); 309 ConsumeToken( "DOT");314 ConsumeToken(Token.Symbol.Dot); 310 315 version.Append('.').Append(ConsumeNumber()); 311 ConsumeToken( "DOT");316 ConsumeToken(Token.Symbol.Dot); 312 317 version.Append('.').Append(ConsumeNumber()); 313 ConsumeToken( "DOT");318 ConsumeToken(Token.Symbol.Dot); 314 319 version.Append('.').Append(ConsumeNumber()); 315 320 return version.ToString(); … … 368 373 369 374 private bool ConsumeComma() { 370 if (ConsumeToken( "COMMA")) {371 while (ConsumeToken( "SPACE")) ;375 if (ConsumeToken(Token.Symbol.Comma)) { 376 while (ConsumeToken(Token.Symbol.Space)) ; 372 377 return true; 373 378 } else { … … 376 381 } 377 382 378 private bool ConsumeToken( string name) {379 return ConsumeToken( name, false);380 } 381 382 private bool CanConsumeToken( string name) {383 if (tokens.Count == 0) 384 return false; 385 if (tokens.Peek().Name == name)383 private bool ConsumeToken(Token.Symbol symbol) { 384 return ConsumeToken(symbol, false); 385 } 386 387 private bool CanConsumeToken(Token.Symbol symbol) { 388 if (tokens.Count == 0) 389 return false; 390 if (tokens.Peek().Name == symbol) 386 391 return true; 387 392 return false; 388 393 } 389 394 390 private bool ConsumeToken( string name, bool force) {395 private bool ConsumeToken(Token.Symbol symbol, bool force) { 391 396 if (tokens.Count == 0) 392 397 if (force) 393 398 throw new ParseError(String.Format( 394 399 "end of input while expecting token \"{0}\"", 395 name));400 symbol)); 396 401 else 397 402 return false; 398 if (tokens.Peek().Name == name) {403 if (tokens.Peek().Name == symbol) { 399 404 tokens.Dequeue(); 400 405 return true; … … 402 407 throw new ParseError(String.Format( 403 408 "expected \"{0}\" found \"{1}\"", 404 name,409 symbol, 405 410 tokens.Peek().ToString())); 406 411 } else { -
trunk/sources/HeuristicLab.Tests/HeuristicLab.Persistence-3.3/UseCases.cs
r7915 r9005 1323 1323 } 1324 1324 1325 public class G<T,T2> { 1326 public class S {} 1327 public class S2<T3,T4> {} 1328 } 1329 1330 [TestMethod] 1331 public void TestInternalClassOfGeneric() { 1332 var s = new G<int, char>.S(); 1333 var typeName = s.GetType().AssemblyQualifiedName; 1334 Assert.AreEqual( 1335 "UseCases.G<Int32,Char>.S", 1336 TypeNameParser.Parse(typeName).GetTypeNameInCode(false)); 1337 XmlGenerator.Serialize(s, tempFile); 1338 var s1 = XmlParser.Deserialize(tempFile); 1339 } 1340 1341 [TestMethod] 1342 public void TestInternalClassOfGeneric2() { 1343 var s = new G<int, float>.S2<int, char>(); 1344 var typeName = s.GetType().AssemblyQualifiedName; 1345 Assert.AreEqual( 1346 "UseCases.G<Int32,Single>.S2<Int32,Char>", 1347 TypeNameParser.Parse(typeName).GetTypeNameInCode(false)); 1348 XmlGenerator.Serialize(s, tempFile); 1349 var s1 = XmlParser.Deserialize(tempFile); 1350 } 1351 1325 1352 [ClassInitialize] 1326 1353 public static void Initialize(TestContext testContext) {
Note: See TracChangeset
for help on using the changeset viewer.