/// <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));
        }
Ejemplo n.º 2
0
        /// <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);
        }