static void AddMetadata( Node node, ProjectObjectIdentifiers ids, ConcurrentDictionary <ObjectIdentifier, IEnumerable <ObjectIdentifier> > metadata, Func <IDataType, ImmutableList <ObjectIdentifier> > enqueue) { ids.TryGetIdentifier(node).Do(id => metadata.AddOrUpdate( key: id, addValueFactory: _ => node.MatchWith( (DocumentScope ds) => ds.MatchWith( (ClassNode cn) => enqueue(cn.BaseType), (TemplateNode tn) => enqueue(tn.ProducedType)), (ObjectNode on) => enqueue(on.DataType), (Uno.UX.Markup.UXIL.PropertyNode pn) => ImmutableList <ObjectIdentifier> .Empty, (DependencyNode dn) => ImmutableList <ObjectIdentifier> .Empty), updateValueFactory: (_, v) => v)); }
public static ProjectMetadata GenerateMetadata( this Project project, ProjectObjectIdentifiers ids) { var hierarchy = new ConcurrentDictionary <ObjectIdentifier, IEnumerable <ObjectIdentifier> >(); var precompiledElements = new List <PrecompiledElement>(); var nodeWorklist = new ConcurrentQueue <Node>(); var typeWorklist = new ConcurrentQueue <DataType>(); foreach (var doc in project.RootClasses) { nodeWorklist.Enqueue(doc.Root); } Node node; while (nodeWorklist.TryDequeue(out node)) { AddMetadata(node, ids, hierarchy, dt => { var uxClass = dt as ClassNode; if (uxClass != null) { return(ids .TryGetIdentifier(uxClass) .Select(id => new ObjectIdentifier(id.ToString())) .ToList()); } return(TryGetUnoDataType(dt) .MatchWith( none: () => ImmutableList <ObjectIdentifier> .Empty, some: unoDataType => { typeWorklist.Enqueue(unoDataType); return List.Create(new ObjectIdentifier(unoDataType.FullName)); })); }); foreach (var child in node.Children) { nodeWorklist.Enqueue(child); } } DataType type; while (typeWorklist.TryDequeue(out type)) { if (IsUxDeclarable(type)) { precompiledElements.Add(new PrecompiledElement( id: new ObjectIdentifier(type.FullName), source: "<" + type.Base.FullName + " ux:Class=\"" + type.FullName + "\">" + type.Properties .Where(p => IsUxDeclarable(p.ReturnType)) .Select(p => "<" + p.ReturnType.FullName + " ux:Property=\"" + p.Name + "\" />") .Join("") + "</" + type.Base.FullName + ">")); } hierarchy.AddOrUpdate( key: new ObjectIdentifier(type.FullName), addValueFactory: _ => { var baseType = type.Base; if (baseType == null) { return(ImmutableList <ObjectIdentifier> .Empty); } typeWorklist.Enqueue(baseType); return(List.Create(new ObjectIdentifier(baseType.FullName))); }, updateValueFactory: (_, v) => v); } return(new ProjectMetadata(hierarchy.ToImmutableList(), precompiledElements.ToImmutableList())); }