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)); }
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))); }
/// <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)); }