/// <summary> /// Performs any post write operations needed after the specified /// token has been written to the underlying stream. /// </summary> /// <param name="token">The token written.</param> protected virtual void PostWrite(JsTokenType token) { this.CurrentToken = token; switch (token) { case JsTokenType.BeginArray: this.StructStack.Push(JsStructType.Array); break; case JsTokenType.BeginObject: this.StructStack.Push(JsStructType.Object); break; case JsTokenType.EndArray: Debug.Assert(this.CurrentStruct == JsStructType.Array); this.StructStack.Pop(); break; case JsTokenType.EndObject: Debug.Assert(this.CurrentStruct == JsStructType.Object); this.StructStack.Pop(); break; default: break; } }
void Add(JsTokenType t, string pattern, Predicate <JsToken> allowedPrev) { Regex r = new Regex(pattern, RegexOptions.IgnorePatternWhitespace); this._orderedRegexList.Add(r); this._typeLookup.Add(r, t); this._allowedPrevToken.Add(allowedPrev); }
/// <summary> /// Initialises a new instance of the JsWriter class and specifies /// the underlying <see cref="System.IO.TextWriter"/> and a value indicating /// if the instance owns the specified TextWriter. /// </summary> /// <param name="writer">The underlying text writer.</param> /// <param name="ownsWriter">True if this instance owns the specified TextWriter, /// otherwise; false.</param> public JsWriter(TextWriter writer, bool ownsWriter) { if (writer == null) { throw new ArgumentNullException("writer"); } _writer = writer; _ownsWriter = ownsWriter; _token = JsTokenType.None; _structStack = new Stack <JsStructType>(); }
void TestScriptAgainstKnownTokens(string script, JsTokenType type, params string[] knownTokens) { // use parser to find tokens var parsed = new JsLexer() .GetTokens(script) .ToArray(); // compare size Assert.That(parsed.Length, Is.EqualTo(knownTokens.Length)); // compare individuals for (int i = 0; i < knownTokens.Length; ++i) { Assert.That(parsed[i].Text, Is.EqualTo(knownTokens[i])); Assert.That(parsed[i].Type, Is.EqualTo(type), parsed[i].Text); } }
private void Assert(bool cond, JsTokenType nextToken) { if (!cond) { StringBuilder sb = new StringBuilder(150); sb.Append("Attempted state transition would lead to an invalid JSON output."); sb.Append(Environment.NewLine); sb.Append("Current Token:\t").Append(this.CurrentToken.ToString()); sb.Append(Environment.NewLine); sb.Append("Attempted Token:\t").Append(nextToken.ToString()); sb.Append(Environment.NewLine); sb.Append("Current Struct:\t").Append(this.CurrentStruct.ToString()); throw new InvalidOperationException(sb.ToString()); } }
/// <summary> /// Performs any assertions and / or write operations needed before the specified /// token is written to the underlying stream. /// </summary> /// <param name="token">The next token to be written.</param> protected virtual void PreWrite(JsTokenType token) { switch (JsWriter.TRANSITION_TABLE[(int)this.CurrentToken][(int)token]) { case ST.SOK: // void. break; case ST.ERR: Assert(false, token); break; case ST.AIO: Assert(this.CurrentStruct == JsStructType.Object, token); break; case ST.AIA: Assert(this.CurrentStruct == JsStructType.Array, token); break; case ST.AIS: Assert(this.CurrentStruct != JsStructType.None, token); break; default: Debug.Fail("JsWriter::PreWrite - Unknown token."); break; } // This is horrible but without increasing the complexity of the state // table it is needed. Assert(!(this.CurrentStruct == JsStructType.Object && token != JsTokenType.EndObject && this.CurrentToken != JsTokenType.Name && token != JsTokenType.Name), token); // See if we should write a seperator. if (!JsWriter.IsStructEnd(token) && (JsWriter.IsStructEnd(this.CurrentToken) || this.CurrentToken == JsTokenType.Value)) { this.Writer.Write(JsWriter.ValueSeperator); } }
void Add(JsTokenType t, string pattern) { this.Add(t, pattern, null); }
/// <summary> /// Constructs a JavaScript token from the host string /// </summary> /// <param name="host"></param> /// <param name="begin"></param> /// <param name="end"></param> /// <param name="type"></param> public JsToken(string host, int begin, int end, JsTokenType type) { this.Text = host.Substring(begin, end - begin); this.Begin = begin; this.Type = type; }
void TestWhiteSpaceDelimitedTokens(string script, JsTokenType type) { TestScriptAgainstKnownTokens(script, type, script.Split(' ')); }
internal static bool IsStructStart(JsTokenType token) { return(token == JsTokenType.BeginArray || token == JsTokenType.BeginObject); }
internal static bool IsStructEnd(JsTokenType token) { return(token == JsTokenType.EndArray || token == JsTokenType.EndObject); }
/// <summary> /// Performs any assertions and / or write operations needed before the specified /// token is written to the underlying stream. /// </summary> /// <param name="token">The next token to be written.</param> protected override void PreWrite(JsTokenType token) { base.PreWrite(token); // Firstly, see if a new line is required. switch (base.CurrentStruct) { case JsStructType.Array: // Every array element starts on a new line. base.Writer.WriteLine(); break; case JsStructType.Object: // Don't write primitives on a new line. if (token != JsTokenType.Value) { base.Writer.WriteLine(); } break; case JsStructType.None: break; default: Debug.Fail("IndentJsWriter::PreWrite - Unknown base.CurrentStruct."); break; } // Secondly, see if the indent should be written and / or adjusted. switch (token) { case JsTokenType.BeginArray: case JsTokenType.BeginObject: WriteIndent(); ++this.IndentLevel; break; case JsTokenType.EndArray: case JsTokenType.EndObject: --this.IndentLevel; WriteIndent(); break; case JsTokenType.Name: WriteIndent(); break; case JsTokenType.Value: // Primtives are not written on a new line when in an object. if (base.CurrentStruct != JsStructType.Object) { WriteIndent(); } else { base.Writer.Write(" "); } break; case JsTokenType.None: break; default: Debug.Fail("IndentedJsWriter::PreWrite - Unknown token."); break; } }
public JsToken(string value, JsTokenType type) { this.Type = type; this.Value = value; Node = null; }
public void Write(string token, JsTokenType type) { Write(new JsToken(token, type)); }