TSTypeFile EnsureInitialized(IActivityMonitor monitor, TSTypeFile f, ref HashSet <Type>?cycleDetector) { if (!f.IsInitialized) { TypeScriptAttribute attr = f.Attribute; var generators = f.Generators; var t = f.Type; ITSCodeGenerator?globalControl = null; foreach (var g in _globals) { _success &= g.ConfigureTypeScriptAttribute(monitor, this, t, attr, generators, ref globalControl); } if (globalControl == null) { if (generators.Count > 0) { foreach (var g in generators) { _success &= g.ConfigureTypeScriptAttribute(monitor, attr, generators); } } } NormalizedPath folder; string? fileName = null; Type? refTarget = attr.SameFileAs ?? attr.SameFolderAs; if (refTarget != null) { if (cycleDetector == null) { cycleDetector = new HashSet <Type>(); } if (!cycleDetector.Add(t)) { throw new InvalidOperationException($"TypeScript.SameFoldeAs cycle detected: {cycleDetector.Select( c => c.Name ).Concatenate( " => " )}."); } var target = DoGetTSTypeFile(monitor, refTarget, ref cycleDetector); folder = target.Folder; if (attr.SameFileAs != null) { fileName = target.FileName; } } else { folder = attr.Folder ?? t.Namespace !.Replace('.', '/'); } var defName = t.GetExternalName() ?? t.Name; fileName ??= attr.FileName ?? (defName + ".ts"); string typeName = attr.TypeName ?? defName; f.Initialize(folder, fileName, typeName, globalControl); } return(f); }
TSTypeFile DoGetTSTypeFile(IActivityMonitor monitor, Type t, ref HashSet <Type>?cycleDetector) { TSTypeFile?f = _typeMappings.GetValueOrDefault(t); if (f == null) { Debug.Assert(!_attributeCache.ContainsKey(t)); f = new TSTypeFile(this, t, Array.Empty <ITSCodeGeneratorType>(), null); _typeMappings.Add(t, f); _typeFiles.Add(f); } if (!f.IsInitialized) { EnsureInitialized(monitor, f, ref cycleDetector); } return(f); }
internal bool BuildTSTypeFilesFromAttributes(IActivityMonitor monitor) { List <ITSCodeGenerator>?globals = null; // Reused per type. TypeScriptImpl?impl = null; List <ITSCodeGeneratorType> generators = new List <ITSCodeGeneratorType>(); foreach (var attributeCache in _attributeCache.Values) { impl = null; generators.Clear(); foreach (var m in attributeCache.GetTypeCustomAttributes <ITSCodeGeneratorAutoDiscovery>()) { if (m is ITSCodeGenerator g) { if (globals == null) { globals = new List <ITSCodeGenerator>(); } globals.Add(g); } if (m is TypeScriptImpl a) { impl = a; } if (m is ITSCodeGeneratorType tG) { generators.Add(tG); } } if (impl != null || generators.Count > 0) { var f = new TSTypeFile(this, attributeCache.Type, generators.ToArray(), impl?.Attribute); _typeMappings.Add(attributeCache.Type, f); _typeFiles.Add(f); } } _globals = (IReadOnlyList <ITSCodeGenerator>?)globals ?? Array.Empty <ITSCodeGenerator>(); return(_success); }