public static ICliFunctionalityProvider AddCustomHandler( this ICliFunctionalityProvider functionalityProvider, Action handler, string tokenText) { if (handler == null) { throw new ArgumentNullException(nameof(handler)); } if (tokenText == null) { throw new ArgumentNullException(nameof(tokenText)); } var family = CheckArgumentsAndGetOrCreateFamily(functionalityProvider); var verbClass = GetVerbTextClass(tokenText); var commandNode = new ExactTextNode( tokenText, verbClass, true, (node, token, resultAccumulator) => { handler(); throw new CliCustomHandlerException(); }, family, $"Custom handler node for verb '{tokenText}'"); functionalityProvider.Node.EstablishLink(commandNode); return(functionalityProvider); }
public void Parse_Concurrency_ThrowsNodeConcurrencyException() { // Arrange INodeFamily nodeFamily = new NodeFamily("family"); INode idle = new IdleNode(nodeFamily, null); INode exactText = new ExactTextNode( "foo", new[] { WordTextClass.Instance, }, false, (node, token, arg3) => { }, nodeFamily, null); INode someText = new TextNode( new ITextClass[] { WordTextClass.Instance, }, null, nodeFamily, null); idle.EstablishLink(someText); idle.EstablishLink(exactText); someText.EstablishLink(EndNode.Instance); exactText.EstablishLink(EndNode.Instance); IParser parser = new Parser(); var tokens = new List <IToken> { new TextToken( WordTextClass.Instance, NoneTextDecoration.Instance, "foo", Position.Zero, 3), }; // Act parser.Root = idle; var ex = Assert.Throws <NodeConcurrencyException>(() => parser.Parse(tokens)); // Assert Assert.That(ex.Message, Is.EqualTo("More than one node accepted the token.")); Assert.That(ex.ConcurrentNodes, Has.Length.EqualTo(2)); Assert.That(ex.ConcurrentNodes, Does.Contain(exactText)); Assert.That(ex.ConcurrentNodes, Does.Contain(someText)); Assert.That(ex.Token, Is.SameAs(tokens.Single())); }
public virtual INode CreateNode(PseudoList item) { if (item == null) { throw new ArgumentNullException(nameof(item)); } try { var car = item.GetCarSymbolName(); INode node; switch (car) { case "EXACT-TEXT": node = new ExactTextNode( item.GetSingleKeywordArgument <StringAtom>(":value").Value, this.ParseTextClasses(item.GetAllKeywordArguments(":classes")), _isCaseSensitive, null, this.NodeFamily, item.GetItemName()); break; case "SOME-TEXT": node = new TextNode( this.ParseTextClasses(item.GetAllKeywordArguments(":classes")), null, this.NodeFamily, item.GetItemName()); break; case "MULTI-TEXT": node = new MultiTextNode( item.GetAllKeywordArguments(":values").Cast <StringAtom>().Select(x => x.Value), this.ParseTextClasses(item.GetAllKeywordArguments(":classes")), _isCaseSensitive, null, this.NodeFamily, item.GetItemName()); break; case "EXACT-PUNCTUATION": node = new ExactPunctuationNode( item.GetSingleKeywordArgument <StringAtom>(":value").Value.Single(), null, this.NodeFamily, item.GetItemName()); break; // todo: some-number? case "SOME-INTEGER": node = new IntegerNode( null, this.NodeFamily, item.GetItemName()); break; case "FALLBACK": var name = item.GetItemName(); if (name == null) { throw new BuildingException("Fallback node must have a name."); } node = new FallbackNode( this.CreateFallbackPredicate(name), this.NodeFamily, name); break; default: return(null); } return(node); } catch (Exception ex) { throw new BuildingException($"Could not build a node from item {item}.", ex); } }