1 // RUN: %check_clang_tidy %s cata-json-translation-input %t -- -plugins=%cata_plugin --
2
3 // check_clang_tidy uses -nostdinc++, so we add dummy declaration of std::string here
4 namespace std
5 {
6 template<class CharT, class Traits = void, class Allocator = void>
7 class basic_string
8 {
9 public:
10 basic_string();
11 basic_string( const CharT * );
12 CharT *c_str();
13 const CharT *c_str() const;
14 };
15 using string = basic_string<char>;
16 string operator+( const string &, const string & );
17 } // namespace std
18
19 // check_clang_tidy uses -nostdinc++, so we add dummy translation interface here instead of including translations.h
20 std::string _( const std::string & );
21 std::string gettext( const std::string & );
22 std::string pgettext( const std::string &, const std::string & );
23 std::string ngettext( const std::string &, const std::string &, int );
24 std::string npgettext( const std::string &, const std::string &, const std::string &, int );
25
26 class translation
27 {
28 public:
29 static translation to_translation( const std::string & );
30 static translation to_translation( const std::string &, const std::string & );
31 static translation pl_translation( const std::string &, const std::string & );
32 static translation pl_translation( const std::string &, const std::string &, const std::string & );
33 static translation no_translation( const std::string & );
34 };
35
36 translation to_translation( const std::string & );
37 translation to_translation( const std::string &, const std::string & );
38 translation pl_translation( const std::string &, const std::string & );
39 translation pl_translation( const std::string &, const std::string &, const std::string & );
40 translation no_translation( const std::string & );
41
42 // dummy json interface
43 class JsonArray
44 {
45 public:
46 std::string next_string();
47 };
48
49 class JsonObject
50 {
51 public:
52 std::string get_string( const std::string & );
53 JsonArray get_array( const std::string & );
54 template<class T>
55 bool read( const std::string &name, T &t, bool throw_on_error = true );
56 };
57
58 class JsonIn
59 {
60 public:
61 JsonObject get_object();
62 };
63
64 class foo
65 {
66 public:
67 std::string name;
68 std::string double_name;
69 std::string nickname;
70 translation msg;
71 translation more_msg;
72 translation moar_msg;
73 translation endless_msg;
74 translation desc;
75 std::string whatever;
76 };
77
78 // <translation function>( ... <json input object>.<method>(...) ... )
deserialize(foo & bar,JsonIn & jin)79 static void deserialize( foo &bar, JsonIn &jin )
80 {
81 JsonObject jo = jin.get_object();
82 bar.name = _( jo.get_string( "name" ) );
83 // CHECK-MESSAGES: [[@LINE-1]]:16: warning: immediately translating a value read from json causes translation updating issues. Consider reading into a translation object instead.
84 // CHECK-MESSAGES: [[@LINE-2]]:19: note: value read from json
85
86 JsonArray ja = jo.get_array( "double_name" );
87 bar.double_name = std::string( _( ja.next_string() ) ) + pgettext( "blah",
88 // CHECK-MESSAGES: [[@LINE-1]]:36: warning: immediately translating a value read from json causes translation updating issues. Consider reading into a translation object instead.
89 // CHECK-MESSAGES: [[@LINE-2]]:39: note: value read from json
90 // CHECK-MESSAGES: [[@LINE-3]]:62: warning: immediately translating a value read from json causes translation updating issues. Consider reading into a translation object instead.
91 std::string( ja.next_string() ) );
92 // CHECK-MESSAGES: [[@LINE-1]]:36: note: value read from json
93
94 // ok, not reading from json
95 bar.nickname = _( "blah" );
96
97 bar.msg = to_translation( jo.get_string( "message" ) );
98 // CHECK-MESSAGES: [[@LINE-1]]:15: warning: read translation directly instead of constructing it from json strings to ensure consistent format in json.
99 // CHECK-MESSAGES: [[@LINE-2]]:31: note: string read from json
100
101 bar.more_msg = pl_translation( jo.get_string( "message" ), "foo" );
102 // CHECK-MESSAGES: [[@LINE-1]]:20: warning: read translation directly instead of constructing it from json strings to ensure consistent format in json.
103 // CHECK-MESSAGES: [[@LINE-2]]:36: note: string read from json
104
105 bar.moar_msg = translation::to_translation( jo.get_string( "more_message" ) );
106 // CHECK-MESSAGES: [[@LINE-1]]:20: warning: read translation directly instead of constructing it from json strings to ensure consistent format in json.
107 // CHECK-MESSAGES: [[@LINE-2]]:49: note: string read from json
108
109 // ok, reading translation directly
110 jo.read( "endless_msg", bar.endless_msg );
111
112 // ok, using no_translation to avoid re-translating generated string
113 bar.desc = no_translation( jo.get_string( "generated_desc" ) );
114
115 std::string duh;
116 // ok, not reading from json
117 bar.whatever = _( duh.c_str() );
118 }
119