public CommentInfos Parse(string source, string startComment = "/*", string endComment = "*/", int numberOfCommentToParse = -1) { var l = new CommentInfos(); int currentPos = 0; while (true) { var startPos = source.IndexOf(startComment, currentPos); if (startPos == -1) { break; } else { var ci = new CommentInfo(); var endPos = source.IndexOf(endComment, startPos); if (endPos == -1) { ci.Error = true; break; } ci.Start = startPos; ci.End = endPos + endComment.Length - 1; ci.Length = endPos - startPos - startComment.Length; ci.Text = source.Substring(startPos + startComment.Length, ci.Length); l.Add(ci); currentPos = endPos + 2; if (numberOfCommentToParse != -1 && l.Count > numberOfCommentToParse) { break; } } } l.UpdateHash(); return(l); }
/// <summary> /// Parses the string json into a value /// </summary> /// <param name="json">A JSON string.</param> /// <returns>An ArrayList, a Hashtable, a double, a string, null, true, or false</returns> public object Validate(string json, bool supportStartComment = false, bool relaxMode = false, CommentInfos commentInfos = null) { bool success = true; this._supportStartComment = supportStartComment; if (commentInfos == null) // Optimization for the TextHighlighter extension { // So we do not have parse the comment twice if possible commentInfos = new CommentParser().Parse(json); } _supportIDWithNoQuote = (relaxMode) || (commentInfos.IsRelax); _supportTrailingComa = _supportIDWithNoQuote; _supportSlashComment = _supportIDWithNoQuote; return(Compile(json, ref success)); }
/// <summary> /// http://social.msdn.microsoft.com/Forums/en-US/vsx/thread/73871dc0-b7a0-404b-b8e2-4e95ead59112/ /// </summary> /// <param name="spans"></param> /// <returns></returns> public IEnumerable <ITagSpan <JsonErrorTokenTag> > GetTags(NormalizedSnapshotSpanCollection spans) { var requestAFullRefresh = false; var colorizedTokens = new List <ITagSpan <JsonErrorTokenTag> >(); JSON.SyntaxValidator.CommentInfos comments = null; if (string.IsNullOrEmpty(jsonRelaxMode)) { jsonRelaxMode = ConfigurationEngine.Singleton.GetConfigJson().JsonRelaxMode.ToString(); } try { foreach (SnapshotSpan curSpan in spans) // << spans collection always contains 1 object { ITextSnapshotLine containingLine = curSpan.Start.GetContainingLine(); int curLocStart = containingLine.Start.Position; int curLocEnd = containingLine.End.Position; string line = containingLine.GetText(); string allJsonSource = containingLine.Snapshot.GetText(); Tokens Tokens = new Tokens(line, curLocStart, "$", "$"); if (comments == null) // Detect that we are processing the first tags { comments = new JSON.SyntaxValidator.CommentParser().Parse(allJsonSource); } // Detect change in the comment as we may request a full refresh // Because of the comment metadata like "use relax" or minimap:true or :openconfig if ((!comments.Hash.Equals(_previousCommentHash)) && _previousCommentHash != null) { requestAFullRefresh = true; } _previousCommentHash = comments.Hash; // Detect if json source text changed, because if it does not we do not need to execute // the JSON syntax validation, we re use the previous result. var jsonSourceHash = MD5Hash.Make(allJsonSource); if (jsonSourceHash.Equals(this._previousJsonSourceHash)) { this.Out("Json Validation OPTIMIZATION"); _jsonErrorInfo = _previousJsonErrorInfo; } else { _jsonErrorInfo = Json.JsonValidator.ValidateJson(allJsonSource, comments, jsonRelaxMode == "True"); this._previousJsonSourceHash = jsonSourceHash; } //this.Out("\nValidation:[curLocStart:{0},curLocEnd:{1}]{2}".format(curLocStart, curLocEnd, line)); if (_jsonErrorInfo.Valid) { if (_previousValidationFailed) { _previousValidationFailed = false; requestAFullRefresh = true; } } else { _previousValidationFailed = true; if ((_jsonErrorInfo.AbsPosition >= curLocStart || _jsonErrorInfo.AbsPosition + 2 >= curLocStart) && _jsonErrorInfo.AbsPosition <= curLocEnd) { var tokenSpan = new SnapshotSpan(curSpan.Snapshot, new Span(curLocStart, line.Length)); curLocStart += line.Length; if (tokenSpan.IntersectsWith(curSpan)) { colorizedTokens.Add(new TagSpan <JsonErrorTokenTag>(tokenSpan, new JsonErrorTokenTag(Tokens.Current.Value, Tokens.Index, _jsonErrorInfo.Message))); } } // If validation failed twice in a row for different reason we // need to request a full refresh if (_previousJsonErrorInfo.ToString() != _jsonErrorInfo.ToString()) { requestAFullRefresh = true; } } } } catch (System.Exception ex) { this.Out(ex.ToString()); #if DEBUG //System.Diagnostics.Debugger.Break(); #endif } if (requestAFullRefresh) { this.RequestFullRefresh(); } _previousJsonErrorInfo = _jsonErrorInfo; return(colorizedTokens); }