|
1 | 1 | using System; |
2 | 2 | using System.Collections.Generic; |
| 3 | +using System.Diagnostics; |
3 | 4 | using System.IO; |
4 | 5 | using System.Linq; |
5 | 6 | using System.Reflection; |
@@ -68,7 +69,9 @@ public FunctionDescriptorParams() |
68 | 69 | } |
69 | 70 |
|
70 | 71 | /// <summary> |
71 | | - /// Returns full path to the assembly the defined this function |
| 72 | + /// Returns full path to the assembly the defined this function. |
| 73 | + /// This is not always an assembly path, it might be a path to a .ds file |
| 74 | + /// or builtin token like 'operators'. |
72 | 75 | /// </summary> |
73 | 76 | public string Assembly { get; set; } |
74 | 77 |
|
@@ -221,7 +224,9 @@ public FunctionDescriptor(FunctionDescriptorParams funcDescParams) |
221 | 224 | public bool IsOverloaded { get; set; } |
222 | 225 |
|
223 | 226 | /// <summary> |
224 | | - /// Full path to the assembly which defined this function |
| 227 | + /// Returns full path to the assembly the defined this function. |
| 228 | + /// This is not always an assembly path, it might be a path to a .ds file |
| 229 | + /// or builtin token like 'operators'. |
225 | 230 | /// </summary> |
226 | 231 | public string Assembly { get; private set; } |
227 | 232 |
|
@@ -318,49 +323,71 @@ public IEnumerable<Tuple<string, string>> InputParameters |
318 | 323 | private set; |
319 | 324 | } |
320 | 325 |
|
| 326 | + private string category; |
321 | 327 | /// <summary> |
322 | 328 | /// The category of this function. |
323 | 329 | /// </summary> |
324 | 330 | public string Category |
325 | 331 | { |
326 | 332 | get |
327 | 333 | { |
| 334 | + if (category != null) |
| 335 | + { |
| 336 | + return category; |
| 337 | + } |
328 | 338 | var categoryBuf = new StringBuilder(); |
329 | 339 | categoryBuf.Append(GetRootCategory()); |
330 | 340 |
|
331 | | - //if this is not BuiltIn function search NodeCategoryAttribute for it |
332 | | - if (ClassName != null) |
| 341 | + //if this is not BuiltIn function and not a function defined in a .ds file |
| 342 | + //search the containing assembly for the NodeCategoryAttribute. |
| 343 | + if (ClassName != null && |
| 344 | + Assembly!=null && !Assembly.ToLowerInvariant().EndsWith(".ds")) |
333 | 345 | { |
334 | | - //get function assembly |
335 | | - var asm = AppDomain.CurrentDomain.GetAssemblies() |
336 | | - .Where(x => x.GetName().Name == Path.GetFileNameWithoutExtension(Assembly)) |
337 | | - .ToArray(); |
338 | | - |
339 | | - if (asm.Any() && asm.First().GetType(ClassName) != null) |
| 346 | + try |
340 | 347 | { |
341 | | - //get class type of function |
342 | | - var type = asm.First().GetType(ClassName); |
343 | | - |
344 | | - //get NodeCategoryAttribute for this function if it was been defined |
345 | | - var nodeCat = type.GetMethods().Where(x => x.Name == FunctionName) |
346 | | - .Select(x => x.GetCustomAttribute(typeof(NodeCategoryAttribute))) |
347 | | - .Where(x => x != null) |
348 | | - .Cast<NodeCategoryAttribute>() |
349 | | - .Select(x => x.ElementCategory) |
350 | | - .FirstOrDefault(); |
351 | | - |
352 | | - //if attribute is found compose node category string with last part from attribute |
353 | | - if (!string.IsNullOrEmpty(nodeCat) && ( |
354 | | - nodeCat == LibraryServices.Categories.Constructors |
355 | | - || nodeCat == LibraryServices.Categories.Properties |
356 | | - || nodeCat == LibraryServices.Categories.MemberFunctions)) |
| 348 | +#if DEBUG |
| 349 | + var LoadedAssemblyCount = AppDomain.CurrentDomain.GetAssemblies().Length; |
| 350 | +#endif |
| 351 | + var asm = AppDomain.CurrentDomain.Load(Path.GetFileNameWithoutExtension(Assembly)); |
| 352 | +#if DEBUG |
| 353 | + |
| 354 | + Debug.Assert(AppDomain.CurrentDomain.GetAssemblies().Length == LoadedAssemblyCount, |
| 355 | + "Assembly count should not have changed, because should not have actually performed a load."); |
| 356 | + |
| 357 | +#endif |
| 358 | + if (asm != null) |
357 | 359 | { |
358 | | - categoryBuf.Append("." + UnqualifedClassName + "." + nodeCat); |
359 | | - return categoryBuf.ToString(); |
| 360 | + //get class type of function |
| 361 | + var type = asm.GetType(ClassName); |
| 362 | + if (type != null) |
| 363 | + { |
| 364 | + //get NodeCategoryAttribute for this function if it was defined |
| 365 | + var nodeCat = type.GetMethods().Where(x => x.Name == FunctionName) |
| 366 | + .Select(x => x.GetCustomAttribute(typeof(NodeCategoryAttribute))) |
| 367 | + .Where(x => x != null) |
| 368 | + .Cast<NodeCategoryAttribute>() |
| 369 | + .Select(x => x.ElementCategory) |
| 370 | + .FirstOrDefault(); |
| 371 | + |
| 372 | + //if attribute is found compose node category string with last part from attribute |
| 373 | + if (!string.IsNullOrEmpty(nodeCat) && ( |
| 374 | + nodeCat == LibraryServices.Categories.Constructors |
| 375 | + || nodeCat == LibraryServices.Categories.Properties |
| 376 | + || nodeCat == LibraryServices.Categories.MemberFunctions)) |
| 377 | + { |
| 378 | + categoryBuf.Append("." + UnqualifedClassName + "." + nodeCat); |
| 379 | + category = categoryBuf.ToString(); |
| 380 | + return category; |
| 381 | + } |
| 382 | + } |
360 | 383 | } |
361 | 384 | } |
| 385 | + catch (Exception e) |
| 386 | + { |
| 387 | + //TODO ideally this would surface to dynamo logger somehow. |
| 388 | + Console.WriteLine($"Error while generating function descriptor category:{Assembly} {ClassName} {FunctionName} {e}"); |
| 389 | + } |
362 | 390 | } |
363 | | - |
364 | 391 | switch (Type) |
365 | 392 | { |
366 | 393 | case FunctionType.Constructor: |
@@ -583,7 +610,7 @@ private bool CheckIfFunctionIsMarkedExperimentalByPrefs(FunctionDescriptor fd) |
583 | 610 | } |
584 | 611 | return false; |
585 | 612 | } |
586 | | - internal bool IsExperimental { get;} |
| 613 | + internal bool IsExperimental { get; } |
587 | 614 | } |
588 | 615 |
|
589 | 616 | } |
0 commit comments