authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-10-28 15:08:33-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2019-10-28 15:08:33-04:00
logb37c0096835253714fe0fd8133eed1008d321405
treeb44b5aec0f16dac9e8a83df382f79456b6947207
parent03603ea35352769063610b55e3b6b770e3a98f34
parent36fa5fabc6402777ff3a806475d0b60f30edf389
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #3541 from xackus/language_server

* fix json parser crashing on empty input * make implicit cast of tagged unions to enums easier to find in docs

2 files changed, 22 insertions(+), 10 deletions(-)

doc/langref.html.in+9
...@@ -2778,6 +2778,7 @@ test "simple union" {...@@ -2778,6 +2778,7 @@ test "simple union" {
2778 This turns the union into a <em>tagged</em> union, which makes it eligible2778 This turns the union into a <em>tagged</em> union, which makes it eligible
2779 to use with {#link|switch#} expressions. One can use {#link|@TagType#} to2779 to use with {#link|switch#} expressions. One can use {#link|@TagType#} to
2780 obtain the enum type from the union type.2780 obtain the enum type from the union type.
2781 Tagged unions implicitly cast to their enum {#link|Implicit Cast: unions and enums#}
2781 </p>2782 </p>
2782 {#code_begin|test#}2783 {#code_begin|test#}
2783const std = @import("std");2784const std = @import("std");
...@@ -2805,6 +2806,14 @@ test "switch on tagged union" {...@@ -2805,6 +2806,14 @@ test "switch on tagged union" {
2805test "@TagType" {2806test "@TagType" {
2806 assert(@TagType(ComplexType) == ComplexTypeTag);2807 assert(@TagType(ComplexType) == ComplexTypeTag);
2807}2808}
2809
2810test "implicit cast to enum" {
2811 const c1 = ComplexType{ .Ok = 42 };
2812 const c2 = ComplexType.NotOk;
2813
2814 assert(c1 == .Ok);
2815 assert(c2 == .NotOk);
2816}
2808 {#code_end#}2817 {#code_end#}
2809 <p>In order to modify the payload of a tagged union in a switch expression,2818 <p>In order to modify the payload of a tagged union in a switch expression,
2810 place a {#syntax#}*{#endsyntax#} before the variable name to make it a pointer:2819 place a {#syntax#}*{#endsyntax#} before the variable name to make it a pointer:
lib/std/json.zig+13-10
...@@ -867,6 +867,8 @@ pub const TokenStream = struct {...@@ -867,6 +867,8 @@ pub const TokenStream = struct {
867 parser: StreamingParser,867 parser: StreamingParser,
868 token: ?Token,868 token: ?Token,
869869
870 pub const Error = StreamingParser.Error || error{UnexpectedEndOfJson};
871
870 pub fn init(slice: []const u8) TokenStream {872 pub fn init(slice: []const u8) TokenStream {
871 return TokenStream{873 return TokenStream{
872 .i = 0,874 .i = 0,
...@@ -876,7 +878,7 @@ pub const TokenStream = struct {...@@ -876,7 +878,7 @@ pub const TokenStream = struct {
876 };878 };
877 }879 }
878880
879 pub fn next(self: *TokenStream) !?Token {881 pub fn next(self: *TokenStream) Error!?Token {
880 if (self.token) |token| {882 if (self.token) |token| {
881 const copy = token;883 const copy = token;
882 self.token = null;884 self.token = null;
...@@ -896,16 +898,11 @@ pub const TokenStream = struct {...@@ -896,16 +898,11 @@ pub const TokenStream = struct {
896 }898 }
897 }899 }
898900
899 if (self.i > self.slice.len) {901 if(self.parser.complete){
900 try self.parser.feed(' ', &t1, &t2);902 return null;
901 self.i += 1;903 } else {
902904 return error.UnexpectedEndOfJson;
903 if (t1) |token| {
904 return token;
905 }
906 }905 }
907
908 return null;
909 }906 }
910};907};
911908
...@@ -1456,3 +1453,9 @@ test "write json then parse it" {...@@ -1456,3 +1453,9 @@ test "write json then parse it" {
1456 testing.expect(tree.root.Object.get("array").?.value.Array.at(1).Float == 12.34);1453 testing.expect(tree.root.Object.get("array").?.value.Array.at(1).Float == 12.34);
1457 testing.expect(mem.eql(u8, tree.root.Object.get("str").?.value.String, "hello"));1454 testing.expect(mem.eql(u8, tree.root.Object.get("str").?.value.String, "hello"));
1458}1455}
1456
1457test "parsing empty string gives appropriate error" {
1458 var p = Parser.init(debug.global_allocator, false);
1459 defer p.deinit();
1460 testing.expectError(error.UnexpectedEndOfJson, p.parse(""));
1461}