예제 #1
0
            public static EmbeddedDiagnostic?CheckRootSyntax(JsonCompilationUnit node, JsonOptions options)
            {
                var allowComments       = options.HasFlag(JsonOptions.Comments);
                var allowTrailingCommas = options.HasFlag(JsonOptions.TrailingCommas);

                return(CheckSyntax(node, allowComments, allowTrailingCommas));
            }
예제 #2
0
        private JsonTree ParseTree(JsonOptions options)
        {
            var arraySequence = this.ParseSequence();

            Debug.Assert(_lexer.Position == _lexer.Text.Length);
            Debug.Assert(_currentToken.Kind == JsonKind.EndOfFile);

            var root = new JsonCompilationUnit(arraySequence, _currentToken);

            // There are three forms of diagnostics we can detect.  The first were generated directly when parsing and
            // relate to unknown tokens encountered or tokens that were needed but not found.  The second relates to a
            // set of grammar check rules that apply to both strict and non-strict json.  The last is the specific
            // strict/loose checks we perform.  We look for all three forms, but only report the first issue we found.
            // We want to avoid reporting a ton of cascaded errors.
            var diagnostic1 = GetFirstDiagnostic(root);
            var diagnostic2 = CheckTopLevel(_lexer.Text, root);
            var diagnostic3 = options.HasFlag(JsonOptions.Strict)
                ? StrictSyntaxChecker.CheckRootSyntax(root, options)
                : JsonNetSyntaxChecker.CheckSyntax(root);

            var diagnostic = Earliest(Earliest(diagnostic1, diagnostic2), diagnostic3);

            return(new JsonTree(_lexer.Text, root, diagnostic == null
                ? ImmutableArray <EmbeddedDiagnostic> .Empty
                : ImmutableArray.Create(diagnostic.Value)));
        }
예제 #3
0
        /// <summary>
        /// Checks for errors in json for both json.net and strict mode.
        /// </summary>
        private static EmbeddedDiagnostic?CheckTopLevel(
            VirtualCharSequence text, JsonCompilationUnit compilationUnit)
        {
            var sequence = compilationUnit.Sequence;

            if (sequence.IsEmpty)
            {
                // json is not allowed to be just whitespace.
                //
                // Note: we always have at least some content (either real nodes in the tree) or trivia on the EOF token
                // as we only parse when we have a non-empty sequence of virtual chars to begin with.
                if (text.Length > 0 &&
                    compilationUnit.EndOfFileToken.LeadingTrivia.All(
                        t => t.Kind is JsonKind.WhitespaceTrivia or JsonKind.EndOfLineTrivia))
                {
                    return(new EmbeddedDiagnostic(FeaturesResources.Syntax_error, GetSpan(text)));
                }

                return(null);
            }
            else if (sequence.Length >= 2)
            {
                // the top level can't have more than one actual value.
                var firstToken = GetFirstToken(sequence[1]);
                return(new EmbeddedDiagnostic(
                           string.Format(FeaturesResources._0_unexpected, firstToken.VirtualChars[0]),
                           firstToken.GetSpan()));
            }
            else
            {
                var child = sequence.Single();

                // Commas should never show up in the top level sequence.
                if (child.Kind == JsonKind.CommaValue)
                {
                    var emptyValue = (JsonCommaValueNode)child;
                    return(new EmbeddedDiagnostic(
                               string.Format(FeaturesResources._0_unexpected, ','),
                               emptyValue.CommaToken.GetSpan()));
                }
                else if (child.Kind == JsonKind.Property)
                {
                    var propertyValue = (JsonPropertyNode)child;
                    return(new EmbeddedDiagnostic(
                               string.Format(FeaturesResources._0_unexpected, ':'),
                               propertyValue.ColonToken.GetSpan()));
                }

                return(CheckSyntax(child));
            }