protected virtual IBranch Visit(IVault copyCat, IBranch branch) { var copy = copyCat.GetOrCreateBranch(branch.VPath); copy.SetEntireMetadata(branch.Metadata); branch.GetBranches().ForEach(b => Visit(copyCat, b)); ((Branch)branch).GetValues(ValueKind.Regular).ForEach(v => Visit(copyCat, (IValue)v)); ((Branch)branch).GetValues(ValueKind.Internal).ForEach(v => VisitInternal(copyCat, v)); return copy; }
public static XmlBranchDto FromBranch(IBranch branch) { return new XmlBranchDto { Name = branch.Name, Metadata = ((Branch)branch).Metadata.Raw, Values = ((Branch)branch).GetValues(ValueKind.RegularAndInternal).Select(v => XmlValueDto.FromValue(v)).ToArray(), Branches = branch.GetBranches().Select(b => XmlBranchDto.FromBranch(b)).ToArray(), }; }
public static XmlBranchDto FromBranch(IBranch branch) { return(new XmlBranchDto { Name = branch.Name, Metadata = ((Branch)branch).Metadata.Raw, Values = ((Branch)branch).GetValues(ValueKind.RegularAndInternal).Select(v => XmlValueDto.FromValue(v)).ToArray(), Branches = branch.GetBranches().Select(b => XmlBranchDto.FromBranch(b)).ToArray(), }); }
public TreeNode CreateTreeNodesRecursive(TreeNode parent, IBranch branch) { return(DataVaultEditor.ThreadSafeInvoke(() => { var nodesHost = parent == null ? DataVaultEditor._tree.Nodes : parent.Nodes; var current = nodesHost[nodesHost.Add(branch.AsUIElement())]; branch.GetBranches().ForEach(b => CreateTreeNodesRecursive(current, b)); return current; })); }
protected virtual IBranch Visit(IVault copyCat, IBranch branch) { var copy = copyCat.GetOrCreateBranch(branch.VPath); copy.SetEntireMetadata(branch.Metadata); branch.GetBranches().ForEach(b => Visit(copyCat, b)); ((Branch)branch).GetValues(ValueKind.Regular).ForEach(v => Visit(copyCat, (IValue)v)); ((Branch)branch).GetValues(ValueKind.Internal).ForEach(v => VisitInternal(copyCat, v)); return(copy); }
public IBranch ImportBranch(IBranch branch, CollisionHandling collisionHandling) { using (Vault.ExposeReadWrite()) { using (branch.Vault.ExposeReadWrite()) { var existing = GetBranch(branch.Name); if (existing == null) { return(AttachBranch(branch.Clone())); } else { (collisionHandling != CollisionHandling.Error).AssertTrue(); if (collisionHandling == CollisionHandling.Overwrite) { existing.Delete(); return(AttachBranch(branch.Clone())); } else if (collisionHandling == CollisionHandling.Merge) { // atomicity is not guaranteed. sorry branch.GetBranches().ForEach(b => existing.ImportBranch(b, CollisionHandling.Merge)); branch.GetValues().ForEach(v => existing.ImportValue(v, true)); return(this); } else { throw new NotSupportedException(String.Format( "Collision handling strategy '{0}' is not supported.", collisionHandling)); } } } } }
#pragma warning disable 618,612 private void LoadBranch(IBranch branch, IScenarioNode parent) { foreach (var b in branch.GetBranches()) { if (b.Name.StartsWith("_")) continue; // service node var scenarioNode = ScenarioService.NewNode(); var oldNode = new OLD.ScenarioNode {Model = b,}; scenarioNode.Name = oldNode.Name; scenarioNode.IsAppendix = oldNode.IsAppendix; scenarioNode.TopicTitle = oldNode.Title; scenarioNode.SortingWeight = oldNode.SortingWeight; scenarioNode.IsRadioOwner = oldNode.ConditionDeclarations.Count() > 0; switch (oldNode.NodeType) { case OLD.ScenarioNodeType.Default: scenarioNode.TopicType = LogicalTopicType.Default; break; case OLD.ScenarioNodeType.Topic: scenarioNode.TopicType = LogicalTopicType.Topic1; break; case OLD.ScenarioNodeType.Subtopic2: scenarioNode.TopicType = LogicalTopicType.Topic2; break; case OLD.ScenarioNodeType.Subtopic3: scenarioNode.TopicType = LogicalTopicType.Topic3; break; case OLD.ScenarioNodeType.Subtopic4: scenarioNode.TopicType = LogicalTopicType.Topic4; break; case OLD.ScenarioNodeType.Subtopic5: scenarioNode.TopicType = LogicalTopicType.Topic5; break; case OLD.ScenarioNodeType.ForExport: scenarioNode.TopicType = LogicalTopicType.ForUpload; break; default: scenarioNode.TopicType = LogicalTopicType.Default; break; } if (!ScenarioService.AttachNode(parent, ref scenarioNode)) continue; //TODO: strip word tags scenarioNode.Template = oldNode.Template; foreach (var declaration in oldNode.SourceValueDeclarations) { var sourceDatumDeclaration = ScenarioService.NewSourceDatumDeclaration(); sourceDatumDeclaration.Comment = declaration.Comment; sourceDatumDeclaration.DataType = declaration.Type; sourceDatumDeclaration.MeasurementUnit = declaration.MeasurementUnit; sourceDatumDeclaration.Name = declaration.Name; sourceDatumDeclaration.RepositoryValuePath = declaration.RepositoryValuePath; sourceDatumDeclaration.ValueForTesting = declaration.ValueForTesting; if (!ScenarioService.AttachSourceDatumDeclaration(scenarioNode, ref sourceDatumDeclaration)) continue; } foreach (var declaration in oldNode.FormulaDeclarations) { var formulaDeclaration = ScenarioService.NewFormulaDeclaration(); formulaDeclaration.Comment = declaration.Comment; formulaDeclaration.DataType = declaration.Type; formulaDeclaration.Name = declaration.Name; formulaDeclaration.ElfSource = declaration.ElfCode; formulaDeclaration.HumanSource = declaration.HumanText; if (!ScenarioService.AttachFormulaDeclaration(scenarioNode, ref formulaDeclaration)) continue; } LoadBranch(b, scenarioNode); } }
private void ImplementCreateProperties(CompilationContext ctx, TypeBuilder t, IBranch root) { var relevantCumulations = ctx.ScheduledCumulations.ContainsKey(root) ? ctx.ScheduledCumulations[root].Where(co => co.Subject.IsFov() || co.Subject.Parent.IsFov()) : null; var special = ctx.CumulativeCompilation && relevantCumulations != null; if (special && relevantCumulations.IsEmpty()) return; var base_cp = t.BaseType.GetMethod("CreateProperties", BF.All); var cp = t.DefineOverride(base_cp); if (!base_cp.IsAbstract) cp.il().ldarg(0).call(base_cp); ctx.CPs[t] = cp; var svd = root.GetBranches().Where(b => b.Name == "_sourceValueDeclarations"); var formulae = root.GetBranches().Where(b => b.Name == "_formulaDeclarations"); var conditions = root.GetBranches().Where(b => b.Name == "_conditions"); var nodes = root.GetBranches().Except(svd).Except(formulae).Except(conditions); var svdAndFormulae = svd.Concat(formulae).SelectMany(b => b.GetBranches()).ToArray(); if (special) svdAndFormulae = svdAndFormulae.Where(b => relevantCumulations.Any(co => co.Subject == b || co.Subject.Parent == b)).ToArray(); var propGetCache = new Dictionary<VPath, MethodInfo>(); var fieldCache = new Dictionary<VPath, FieldBuilder>(); var nameCache = new HashSet<String>(); Action<IBranch, bool> ensureProperty = (b, external) => { if (propGetCache.ContainsKey(b.VPath)) { return; } else { var typeToken = b.GetValue("type").ContentString; var propType = typeToken.GetTypeFromToken(); var baseProp = t.BaseType.GetProperties(BF.All).SingleOrDefault( p => p.HasAttr<VPathAttribute>() && p.Attr<VPathAttribute>().VPath == b.VPath); var basePropOk = baseProp != null && baseProp.PropertyType == propType; String name; if (basePropOk) { name = baseProp.Name; } else { var desiredName = b.GetPropertyName(); name = desiredName; var i = 0; while (nameCache.Contains(name)) { name = desiredName + "~" + ++i; } nameCache.Add(b.GetPropertyName()); } if (external) { if (basePropOk) { propGetCache.Add(b.VPath, baseProp.GetGetMethod(true)); } else { var p_prop = t.DefineProperty(name, PropA.None, propType, new Type[0]); p_prop.SetCustomAttribute(new CustomAttributeBuilder( typeof(VPathAttribute).GetConstructor(typeof(String).MkArray()), b.VPath.ToString().MkArray())); var get = t.DefineMethod("get_" + name, MA.ProtectedProp, propType, new Type[0]); get.il() .ldarg(0) .callvirt(typeof(CompiledNode).GetProperty("Root").GetGetMethod()) .ldstr(b.VPath.ToString()) .newobj(typeof(VPath), typeof(String)) .callvirt(typeof(ICompiledNode).GetMethod("Eval")) .ret(); p_prop.SetGetMethod(get); propGetCache.Add(b.VPath, get); } } else { var p_prop = t.DefineProperty(name, PropA.None, propType, new Type[0]); p_prop.SetCustomAttribute(new CustomAttributeBuilder( typeof(VPathAttribute).GetConstructor(typeof(String).MkArray()), b.VPath.ToString().MkArray())); MethodBuilder get; if (basePropOk) { var baseGet = baseProp.GetGetMethod(true); get = t.DefineOverride(baseGet); p_prop.SetGetMethod(get); } else { get = t.DefineMethod("get_" + name, MA.PublicProp, propType, new Type[0]); p_prop.SetGetMethod(get); } propGetCache.Add(b.VPath, get); fieldCache.Add(b.VPath, t.DefineField("_" + name.ToLower(), propType, FA.Private)); } } }; Action<IBranch> updateCp = b => { var get = propGetCache[b.VPath]; cp.il() .ldarg(0) .callvirt(typeof(CompiledNode).GetProperty("Properties").GetGetMethod()) .ldarg(0) .ldstr(b.GetPropertyName()) .ldstr(b.VPath) .newobj(typeof(VPath), typeof(String)) .ldarg(0) .ldftn(get) .newobj(typeof(Func<IEsathObject>), typeof(Object), typeof(IntPtr)) .newobj(typeof(CompiledProperty), typeof(CompiledNode), typeof(String), typeof(VPath), typeof(Func<IEsathObject>)) .callvirt(typeof(CompiledPropertyCollection).GetMethod("Add")); }; // handle deleted flae and svds i.e. create CompiledNode.Eval-like crash if (special) { foreach (IBranch deleted in relevantCumulations.Where(co => co.Reason == EventReason.Remove).Select(co => co.Subject)) { ensureProperty(deleted, false); var get = (MethodBuilder)propGetCache[deleted.VPath]; get.il() .ldstr(String.Format("There's no compiled property at VPath '{0}'.", deleted.VPath)) .@throw(typeof(NotImplementedException), typeof(String)); updateCp(deleted); } } // define all properties in advance so that we can reference them when needed svdAndFormulae.ForEach(b => ensureProperty(b, false)); // implement defined properties foreach (var b in svdAndFormulae) { var typeToken = b.GetValue("type").ContentString; var propType = typeToken.GetTypeFromToken(); var f_prop = fieldCache[b.VPath]; var get = (MethodBuilder)propGetCache[b.VPath]; // if a formula has just been created (i.e. has null elfCode), then we just generate notimplemented stuff // todo. this is a particular case of graceful dealing with invalid elf code // a solid approach would also handle such stuff as: non-existing references, resolving to invalid methods // and i think something else (needs thorough checking) // note. when implementing that stuff, be sure to burn the failboat elf code + the failure reason right into the assembly code // so that one can analyze the formula by him/herself and find the reason of the failure if (b.IsFormula()) { var host = b.GetValue("elfCode"); var code = host == null ? null : host.ContentString; var elfCode = code == null ? null : code.ToCanonicalElf(); if (elfCode == null) { get.il().@throw(typeof(NotImplementedException)); updateCp(b); continue; } } Label cacheOk; LocalBuilder loc_cache, loc_vpath, loc_result; get.il() .ldarg(0) .callvirt(typeof(CompiledNode).GetProperty("Root").GetGetMethod()) .ldfld(typeof(CompiledScenario).GetField("CachedPropertiesRegistry", BF.All)) .def_local(typeof(HashSet<VPath>), out loc_cache) .stloc(loc_cache) .ldstr(b.VPath.ToString()) .newobj(typeof(VPath), typeof(String)) .def_local(typeof(VPath), out loc_vpath) .stloc(loc_vpath) .ldloc(loc_cache) .ldloc(loc_vpath) .callvirt(typeof(HashSet<VPath>).GetMethod("Contains")) .def_label(out cacheOk) .brtrue(cacheOk) // here svd and flae codegen will store the evaluation result .def_local(propType, out loc_result); if (b.IsSvd()) { Label isRuntime, stlocRuntime, isDesignTime, stlocDesignTime, coalesce; LocalBuilder runtime, designTime; get.il() // runtime -> value is stored in the repository .ldarg(0) .callvirt(typeof(CompiledNode).GetProperty("Repository", BF.All).GetGetMethod(true)) .def_label(out stlocRuntime) .def_label(out isRuntime) .def_local(typeof(String), out runtime) .brtrue_s(isRuntime) .ldnull() .br_s(stlocRuntime) .label(isRuntime) .ldarg(0) .callvirt(typeof(CompiledNode).GetProperty("Repository", BF.All).GetGetMethod(true)) .ldarg(0) .callvirt(typeof(CompiledNode).GetProperty("Scenario", BF.All).GetGetMethod(true)) .ldstr(b.VPath.ToString()) .newobj(typeof(VPath), typeof(String)) .callvirt(typeof(CachedVault).GetMethod("GetBranch")) .ldstr("repositoryValue") .newobj(typeof(VPath), typeof(String)) .callvirt(typeof(IBranch).GetMethod("GetValue")) .callvirt(typeof(IValue).GetProperty("ContentString").GetGetMethod()) .newobj(typeof(VPath), typeof(String)) .callvirt(typeof(CachedVault).GetMethod("GetValue")) .callvirt(typeof(IValue).GetProperty("ContentString").GetGetMethod()) .label(stlocRuntime) .stloc(runtime) // design time -> value is stored directly in the scenario next to the node .ldarg(0) .callvirt(typeof(CompiledNode).GetProperty("Repository", BF.All).GetGetMethod(true)) .def_label(out stlocDesignTime) .def_label(out isDesignTime) .def_local(typeof(String), out designTime) .brfalse_s(isDesignTime) .ldnull() .br_s(stlocDesignTime) .label(isDesignTime) .ldarg(0) .callvirt(typeof(CompiledNode).GetProperty("Scenario", BF.All).GetGetMethod(true)) .ldstr(b.VPath.ToString()) .newobj(typeof(VPath), typeof(String)) .callvirt(typeof(CachedVault).GetMethod("GetBranch")) .ldstr("valueForTesting") .newobj(typeof(VPath), typeof(String)) .callvirt(typeof(IBranch).GetMethod("GetValue")) .callvirt(typeof(IValue).GetProperty("ContentString").GetGetMethod()) .label(stlocDesignTime) .stloc(designTime) // prepare for convert .ldtoken(propType) .callvirt(typeof(Type).GetMethod("GetTypeFromHandle")) .callvirt(typeof(Elf.Helpers.ReflectionHelper).GetMethod("ElfDeserializer")) // coalesce designtime and runtime values .ldloc(designTime) .dup() .def_label(out coalesce) .brtrue_s(coalesce) .pop() .ldloc(runtime) .label(coalesce) // convert the string to esath object .callvirt(typeof(Func<String, IElfObject>).GetMethod("Invoke")) .stloc(loc_result); } else if (b.IsFormula()) { var host = b.GetValue("elfCode"); var code = host == null ? null : host.ContentString; var elfCode = code == null ? null : code.ToCanonicalElf(); elfCode.AssertNotNull(); // this is guaranteed by the check above (at the start of this method) Label retTarget; get.il().def_label(out retTarget); var vm = new VirtualMachine(); vm.Load(elfCode); var evis = ((NativeMethod)vm.Classes.Last().Methods.Single()).Body; Func<String, VPath> idToVpath = elfid => { try { return elfid.FromElfIdentifier(); } catch { return null; } }; Func<String, IEsathObject> elfStrToEsath = elfStr => { try { return elfStr.FromStorageString(); } catch { return null; } }; var il = get.il(); var evalStack = new Stack<Type>(); Type auxResultType = null; for (var j = 0; j < evis.Length; j++) { var evi = evis[j]; if (evi is Decl) { throw new NotSupportedException( String.Format("The 'decl' instructions is not supported.")); } else if (evi is Dup) { if (j < evis.Length - 1 && evis[j + 1] is PopRef) { // compile [dup, popref, pop] combo as simply [popref] // since so far constructs like a = b = c are not used } else { var dupe = evalStack.Peek(); evalStack.Push(dupe); il.dup(); } } else if (evi is Enter) { // do nothing } else if (evi is Invoke) { var invoke = (Invoke)evi; var args = new Type[invoke.Argc]; for (var i = invoke.Argc - 1; i >= 0; --i) args[i] = evalStack.Pop(); var resolved = DefaultInvocationResolver.Resolve( vm, invoke.Name, vm.Classes.Last(), args.Select(arg => vm.Classes.Single(c => c.Name == Elf.Helpers.ReflectionHelper.RtimplOf(arg))).ToArray()); if (resolved == null) { throw new NotSupportedException(String.Format( "The '{0}' instruction is not supported. " + "Cannot resolve invocation '{1}({2}).", invoke, invoke.Name, args.Select(arg => Elf.Helpers.ReflectionHelper.RtimplOf(arg)).StringJoin())); } else { if (!(resolved is ClrMethod)) { throw new NotSupportedException(String.Format( "The '{0}' instruction is not supported. " + "Invocation '{1}({2}) has been resolved to a native method '{3}'.", invoke, invoke.Name, args.Select(arg => Elf.Helpers.ReflectionHelper.RtimplOf(arg)).StringJoin(), resolved)); } else { var clrMethod = (MethodInfo)((ClrMethod)resolved).Rtimpl; if (clrMethod.ReturnType == typeof(void)) { throw new NotSupportedException(String.Format( "The '{0}' instruction is not supported. " + "Invocation '{1}({2}) has been resolved to a void-returning method '{3}'.", invoke, invoke.Name, args.Select(arg => Elf.Helpers.ReflectionHelper.RtimplOf(arg)).StringJoin(), clrMethod)); } else { il.callvirt(clrMethod); evalStack.Push(clrMethod.ReturnType); } } } } else if (evi is Jf) { throw new NotSupportedException( String.Format("The 'jf' instruction is not supported.")); } else if (evi is Jt) { throw new NotSupportedException( String.Format("The 'jt' instruction is not supported.")); } else if (evi is Elf.Core.Assembler.Label) { throw new NotSupportedException( String.Format("The 'label' instruction is not supported.")); } else if (evi is Leave) { // do nothing } else if (evi is Pop) { if (j > 0 && evis[j - 1] is PopRef) { // compile [dup, popref, pop] combo as simply [popref] // since so far constructs like a = b = c are not used } else { il.pop(); evalStack.Pop(); } } else if (evi is PopAll) { evalStack.ForEach(t1 => { evalStack.Pop(); il.pop(); }); } else if (evi is PopRef) { var popref = (PopRef)evi; var vpath = idToVpath(popref.Ref); if (vpath == null) { throw new NotSupportedException(String.Format( "The '{0}' instruction is not supported.", popref)); } else { if (vpath != b.VPath) { throw new NotSupportedException(String.Format( "The 'popref <vpath>' instruction is supported only " + "when vpath represents the current node. Current instruction " + "'{0}' is not supported", popref)); } else { auxResultType = evalStack.Pop(); // todo. ensure that nothing significant follows this instruction } } } else if (evi is PushRef) { var pushref = (PushRef)evi; var vpath = idToVpath(pushref.Ref); if (vpath == null) { throw new NotSupportedException(String.Format( "The '{0}' instruction is not supported.", pushref)); } else { if (!propGetCache.ContainsKey(vpath)) { var branch = Vault.GetBranch(vpath); if (branch == null) { throw new NotSupportedException(String.Format( "The 'pushref <vpath>' instruction is supported only " + "when vpath represents the svd or flae node. Current vpath '{0}' " + "doesn't reference any node in the scenario being compiled.", vpath)); } if (!branch.IsFov()) { throw new NotSupportedException(String.Format( "The 'pushref <vpath>' instruction is supported only " + "when vpath represents an svd or a flae node. Current branch " + "'{0}' at vpath '{1}' is not supported.", branch.Name, branch.VPath)); } ensureProperty(branch, true); } var prop = propGetCache[vpath]; il.ldarg(0).callvirt(prop); evalStack.Push(prop.ReturnType); } } else if (evi is PushVal) { var pushval = (PushVal)evi; if (!(pushval.Val is ElfStringLiteral) || (elfStrToEsath(((ElfStringLiteral)pushval.Val).Val)) == null) { throw new NotSupportedException(String.Format( "The 'pushval <val>' instruction is supported only " + "when val represents correctly encoded esath object. Current instruction " + "'{0}' is not supported", pushval)); } else { var storageString = ((ElfStringLiteral)pushval.Val).Val; var match = Regex.Match(storageString, @"^\[\[(?<token>.*?)\]\](?<content>.*)$"); match.Success.AssertTrue(); if (match.Success) { var token = match.Result("${token}"); var content = match.Result("${content}"); il.ldtoken(token.GetTypeFromToken()) .callvirt(typeof(Type).GetMethod("GetTypeFromHandle")) .callvirt(typeof(Elf.Helpers.ReflectionHelper).GetMethod("ElfDeserializer")) .ldstr(content) .callvirt(typeof(Func<String, IElfObject>).GetMethod("Invoke")); evalStack.Push(token.GetTypeFromToken()); } } } else if (evi is Ret) { evalStack.IsEmpty().AssertTrue(); il.br_s(retTarget); } else { throw new NotSupportedException(String.Format( "The '{0}' instruction is not supported.", evi)); } } if (auxResultType == propType) { il.label(retTarget) .stloc(loc_result); } else { LocalBuilder auxResult; var valPropGet = auxResultType.GetProperty("Val").GetGetMethod(); il.label(retTarget) .def_local(auxResultType, out auxResult) .stloc(auxResult) .ldloc(auxResult) .callvirt(valPropGet); if (typeof(ElfNumber).IsAssignableFrom(auxResultType) && propType == typeof(EsathPercent)) { // ldc_r8 is a must, since ldc_i4 performs integer multiplication // and fails stuff like 1.2 * 100 (the result will be 100) il.ldc_r8(100) .mul(); } il.convert(valPropGet.ReturnType, propType) .stloc(loc_result); } } else { throw new NotSupportedException( String.Format("Properties of type '{0}' are not supported", b)); } get.il() // the value is stored in a local after svd or flae codegen .ldarg(0) .ldloc(loc_result) .stfld(f_prop) .ldloc(loc_cache) .ldloc(loc_vpath) .callvirt(typeof(HashSet<VPath>).GetMethod("Add")) .pop() // if the value is cached, just execute this .label(cacheOk) .ldarg(0) .ldfld(f_prop) .ret(); // finally register the property just compiled in the CreateProperties updateCp(b); } cp.il().ret(); }
private void ImplementCreateChildren(CompilationContext ctx, TypeBuilder t, IBranch root) { var relevantCumulations = ctx.ScheduledCumulations.ContainsKey(root) ? ctx.ScheduledCumulations[root].Where(co => !(co.Subject.IsFov() || co.Subject.Parent.IsFov())) : null; var special = ctx.CumulativeCompilation && relevantCumulations != null; if (special && relevantCumulations.IsEmpty()) return; var base_cc = t.BaseType.GetMethod("CreateChildren", BF.All); var cc = t.DefineOverride(base_cc); if (!base_cc.IsAbstract) cc.il().ldarg(0).call(base_cc); ctx.CCs[t] = cc; var svd = root.GetBranches().Where(b => b.Name == "_sourceValueDeclarations"); var formulae = root.GetBranches().Where(b => b.Name == "_formulaDeclarations"); var conditions = root.GetBranches().Where(b => b.Name == "_conditions"); var nodes = root.GetBranches().Except(svd).Except(formulae).Except(conditions).ToArray(); if (special) nodes = nodes.Where(b => relevantCumulations.Any(co => co.Subject == b)).ToArray(); foreach (var b in nodes) { var b_type = CompileNode(ctx, b); var f_child = t.DefineField("_" + b.GetPropertyName().ToLower(), b_type, FA.Private); var p_child = t.DefineProperty(b.GetPropertyName(), PropA.None, b_type, new Type[0]); p_child.SetCustomAttribute(new CustomAttributeBuilder( typeof(VPathAttribute).GetConstructor(typeof(String).MkArray()), b.VPath.ToString().MkArray())); var get = t.DefineMethod("get_" + b.GetPropertyName(), MA.PublicProp, b_type, new Type[0]); p_child.SetGetMethod(get); Label nodeWasCreatedByTheFactory; get.il() .ldarg(0) .ldfld(f_child) // here we check whether the factory returned a valid (non-null) node // if the latter is false, then the node has been deleted during cumulative recompilation // and we need to crash with the same message as CompiledNode.Child(vpath) .def_label(out nodeWasCreatedByTheFactory) .brtrue(nodeWasCreatedByTheFactory) .ldstr(String.Format("There's no compiled node at VPath '{0}'.", b.VPath)) .@throw(typeof(NotImplementedException), typeof(String)) .label(nodeWasCreatedByTheFactory) .ldarg(0) .ldfld(f_child) .ret(); cc.il() .ldarg(0) .ldarg(0) .callvirt(typeof(CompiledNode).GetProperty("Root", BF.All).GetGetMethod(true)) .ldstr(b.VPath.ToString()) .newobj(typeof(VPath), typeof(String)) .ldarg(0) .callvirt(typeof(CompiledScenario).GetMethod("CreateNode", BF.All)) .stfld(f_child) .ldarg(0) .callvirt(typeof(CompiledNode).GetProperty("Children").GetGetMethod()) .ldarg(0) .ldfld(f_child) .callvirt(typeof(CompiledNodeCollection).GetMethod("Add")); } cc.il().ret(); }
public IBranch ImportBranch(IBranch branch, CollisionHandling collisionHandling) { using (Vault.ExposeReadWrite()) { using (branch.Vault.ExposeReadWrite()) { var existing = GetBranch(branch.Name); if (existing == null) { return AttachBranch(branch.Clone()); } else { (collisionHandling != CollisionHandling.Error).AssertTrue(); if (collisionHandling == CollisionHandling.Overwrite) { existing.Delete(); return AttachBranch(branch.Clone()); } else if (collisionHandling == CollisionHandling.Merge) { // atomicity is not guaranteed. sorry branch.GetBranches().ForEach(b => existing.ImportBranch(b, CollisionHandling.Merge)); branch.GetValues().ForEach(v => existing.ImportValue(v, true)); return this; } else { throw new NotSupportedException(String.Format( "Collision handling strategy '{0}' is not supported.", collisionHandling)); } } } } }
private void LoadBranchOld(IBranch branch, TreeNode parent) { if (parent == null) // root { parent = new TreeNode { Text = branch.GetOrCreateValue(new VPath("name"), branch.Name).ContentString, Tag = branch, //Name = branch.GetOrCreateValue(new VPath("id"), Guid.NewGuid().ToString()).ContentString, NodeFont = new Font("Tahoma", 8, FontStyle.Bold), }; treeScenario.Nodes.Add(parent); } foreach (var b in branch.GetBranches()) { if (b.Name.StartsWith("_")) continue; // service node var n = new TreeNode { Text = b.GetOrCreateValue("name", Guid.NewGuid().ToString().Replace('-', '_')).ContentString, Tag = b, //Name = b.GetOrCreateValue(new VPath("id"), Guid.NewGuid().ToString().Replace('-', '_')).ContentString }; parent.Nodes.Add(n); LoadBranchOld(b, n); } }
public TreeNode CreateTreeNodesRecursive(TreeNode parent, IBranch branch) { return DataVaultEditor.ThreadSafeInvoke(() => { var nodesHost = parent == null ? DataVaultEditor._tree.Nodes : parent.Nodes; var current = nodesHost[nodesHost.Add(branch.AsUIElement())]; branch.GetBranches().ForEach(b => CreateTreeNodesRecursive(current, b)); return current; }); }