/// <summary> /// Adds each found property and any associated warnings to token it belongs to /// </summary> /// <param name="currentToken">token to add warning to</param> /// <param name="foundPropertySets">property sets which have been found (list of list of tokens, where the inner list represents key, key value seperator and value)</param> private void AddPropertiesAndWarnings(Token currentToken, List<List<Token>> foundPropertySets) { foreach (var propertyTokenSet in foundPropertySets) { //check for errors if (propertyTokenSet.Count == 1) { if (IsPropertyNameValueSeperatorDelimeter(propertyTokenSet[0])) currentToken.AddWarning("Property added with no key or value"); else currentToken.AddWarning(String.Format("Properties declaration contains no value for the key {0}", propertyTokenSet[0].Text)); } else if (propertyTokenSet.Count == 2) { if (IsPropertyNameValueSeperatorDelimeter(propertyTokenSet[0])) currentToken.AddWarning(String.Format("A property has been added with the value {0} but no key", propertyTokenSet[1].Text)); else if (IsPropertyNameValueSeperatorDelimeter(propertyTokenSet[1])) currentToken.AddWarning(String.Format("Properties declaration contains no value for the key {0}", propertyTokenSet[0].Text)); else currentToken.AddWarning(String.Format("Can not determine key value seperator. {0} and {1} supplied", propertyTokenSet[0].Text, propertyTokenSet[1].Text)); } else { string propertyName = propertyTokenSet[0].Text; if (_delimeterSet.IsDelimeterAllowedProperty(currentToken.Text, propertyName)) { string propertyValue = propertyTokenSet[2].Text; currentToken[propertyName] = propertyValue; } else currentToken.AddWarning(String.Format("The property '{0}' is not allowed on this delimeter.", propertyName)); } } }
/// <summary> /// Handles a custom delimeter from it's start until it's end. /// Also handles tokens within those custom delimeters /// </summary> /// <param name="currentToken">current token (which is a delimeter)</param> /// <param name="tokenStream"></param> private List<Token> HandleCustomDelimeter(Token currentToken, IWaneTokenStream tokenStream) { if (!IsCustomDelimeter(currentToken)) throw new ArgumentException("Expected custome delimeter", "currentToken"); var tokens = new List<Token>(); currentToken.IsStartingDelimeter = true; tokens.Add(currentToken); //find ending delimeter List<Token> tokensToInspect = GetRawTokensUntilAndIncludingEndingDelimeter(currentToken, tokenStream); if (tokensToInspect.Count > 0) { //remove ending token else this will not be processed properly Token closingToken = tokensToInspect.Last(); tokensToInspect.RemoveAt(tokensToInspect.Count - 1); var internalStream = new WaneEnumerableTokenStream(tokensToInspect); //get and remove properties ExtractPropertiesFromTokenListAndApplyToCurrentToken(currentToken, internalStream); if (!internalStream.IsEndOfStream) { List<Token> procesedInternalStreamTokens = ProcessTokenStream(internalStream); tokens.AddRange(procesedInternalStreamTokens); } //add closing delimeter token closingToken.IsEndingDelimeter = true; tokens.Add(closingToken); WarnIfClosingTokenHasProperties(closingToken, tokenStream); } else { //no closing delimeter currentToken.ChangeTokenTypeToText(); currentToken.AddWarning("Delimeter start does not have a matching end delimeter, or the actual start delimeter has been escaped"); } return tokens; }
/// <summary> /// Checks to see if a given token (representing a closing delimeter has properties. If it does then adds warning to that token /// </summary> /// <param name="closingToken">token representing delimeter</param> /// <param name="tokenStream">remaining token stream</param> private void WarnIfClosingTokenHasProperties(Token closingToken, IWaneTokenStream tokenStream) { //check for closing token properties Token possiblePropertyToken = tokenStream.Peek(); if (possiblePropertyToken != null && IsPropertiesStartDelimeter(possiblePropertyToken)) { //check if has full properties List<Token> propertyTokens = GetRawTokensUntilAndIncludingEndingDelimeter(possiblePropertyToken, tokenStream); if (propertyTokens.Count > 0) closingToken.AddWarning("Can not put properties on closing delimeters."); } }
/// <summary> /// Extracts tokens which represent properties for a given token and apply put those properties onto the token /// </summary> /// <param name="currentToken">token that will have properties added to it</param> /// <param name="tokenStream">token stream to inspect</param> private void ExtractPropertiesFromTokenListAndApplyToCurrentToken(Token currentToken, IWaneTokenStream tokenStream) { if (IsPropertiesStartDelimeter(tokenStream.Peek())) { List<Token> rawPropertyTokens = GetRawTokensUntilAndIncludingEndingDelimeter(tokenStream.Peek(), tokenStream); if (rawPropertyTokens.Count == 0) currentToken.AddWarning("Properties start delimeter found, but could not find ending properties delimeter."); else if(rawPropertyTokens.Count == 2) currentToken.AddWarning("Properties declaration contains no key value pairs. Could not construct properties."); else ProcessProperties(currentToken, rawPropertyTokens); } }