From 3087738f284efdc49aac28d68b50b26f0842b714 Mon Sep 17 00:00:00 2001 From: Roger Meier Date: Mon, 17 Sep 2012 21:18:05 +0000 Subject: [PATCH] THRIFT-1651 Support annotations on all elements Patch: Benjy Weinberger git-svn-id: https://svn.apache.org/repos/asf/thrift/trunk@1386848 13f79535-47bb-0310-9956-ffa450edef68 --- compiler/cpp/src/parse/t_enum_value.h | 2 ++ compiler/cpp/src/parse/t_function.h | 2 ++ compiler/cpp/src/thrifty.yy | 48 ++++++++++++++++++++++----- compiler/cpp/test_parser.sh | 31 +++++++++++++++++ test/AnnotationTest.thrift | 30 ++++++++++++++++- 5 files changed, 104 insertions(+), 9 deletions(-) create mode 100644 compiler/cpp/test_parser.sh diff --git a/compiler/cpp/src/parse/t_enum_value.h b/compiler/cpp/src/parse/t_enum_value.h index 283a87e7..3a4a90a8 100644 --- a/compiler/cpp/src/parse/t_enum_value.h +++ b/compiler/cpp/src/parse/t_enum_value.h @@ -60,6 +60,8 @@ class t_enum_value : public t_doc { value_ = val; } + std::map annotations_; + private: std::string name_; bool has_value_; diff --git a/compiler/cpp/src/parse/t_function.h b/compiler/cpp/src/parse/t_function.h index a72aa6c3..0da2fd6a 100644 --- a/compiler/cpp/src/parse/t_function.h +++ b/compiler/cpp/src/parse/t_function.h @@ -82,6 +82,8 @@ class t_function : public t_doc { return oneway_; } + std::map annotations_; + private: t_type* returntype_; std::string name_; diff --git a/compiler/cpp/src/thrifty.yy b/compiler/cpp/src/thrifty.yy index ef53cc38..696fd462 100644 --- a/compiler/cpp/src/thrifty.yy +++ b/compiler/cpp/src/thrifty.yy @@ -504,11 +504,15 @@ TypeDefinition: } Typedef: - tok_typedef FieldType tok_identifier + tok_typedef FieldType tok_identifier TypeAnnotations { pdebug("TypeDef -> tok_typedef FieldType tok_identifier"); t_typedef *td = new t_typedef(g_program, $2, $3); $$ = td; + if ($4 != NULL) { + $$->annotations_ = $4->annotations_; + delete $4; + } } CommaOrSemicolonOptional: @@ -520,11 +524,15 @@ CommaOrSemicolonOptional: {} Enum: - tok_enum tok_identifier '{' EnumDefList '}' + tok_enum tok_identifier '{' EnumDefList '}' TypeAnnotations { pdebug("Enum -> tok_enum tok_identifier { EnumDefList }"); $$ = $4; $$->set_name($2); + if ($6 != NULL) { + $$->annotations_ = $6->annotations_; + delete $6; + } $$->resolve_values(); // make constants for all the enum values if (g_parse_mode == PROGRAM) { @@ -556,7 +564,7 @@ EnumDefList: } EnumDef: - CaptureDocText tok_identifier '=' tok_int_constant CommaOrSemicolonOptional + CaptureDocText tok_identifier '=' tok_int_constant TypeAnnotations CommaOrSemicolonOptional { pdebug("EnumDef -> tok_identifier = tok_int_constant"); if ($4 < 0) { @@ -569,22 +577,34 @@ EnumDef: if ($1 != NULL) { $$->set_doc($1); } + if ($5 != NULL) { + $$->annotations_ = $5->annotations_; + delete $5; + } } | - CaptureDocText tok_identifier CommaOrSemicolonOptional + CaptureDocText tok_identifier TypeAnnotations CommaOrSemicolonOptional { pdebug("EnumDef -> tok_identifier"); $$ = new t_enum_value($2); if ($1 != NULL) { $$->set_doc($1); } + if ($3 != NULL) { + $$->annotations_ = $3->annotations_; + delete $3; + } } Senum: - tok_senum tok_identifier '{' SenumDefList '}' + tok_senum tok_identifier '{' SenumDefList '}' TypeAnnotations { pdebug("Senum -> tok_senum tok_identifier { SenumDefList }"); $$ = new t_typedef(g_program, $4, $2); + if ($6 != NULL) { + $$->annotations_ = $6->annotations_; + delete $6; + } } SenumDefList: @@ -771,21 +791,29 @@ XsdAttributes: } Xception: - tok_xception tok_identifier '{' FieldList '}' + tok_xception tok_identifier '{' FieldList '}' TypeAnnotations { pdebug("Xception -> tok_xception tok_identifier { FieldList }"); $4->set_name($2); $4->set_xception(true); $$ = $4; + if ($6 != NULL) { + $$->annotations_ = $6->annotations_; + delete $6; + } } Service: - tok_service tok_identifier Extends '{' FlagArgs FunctionList UnflagArgs '}' + tok_service tok_identifier Extends '{' FlagArgs FunctionList UnflagArgs '}' TypeAnnotations { pdebug("Service -> tok_service tok_identifier { FunctionList }"); $$ = $6; $$->set_name($2); $$->set_extends($3); + if ($9 != NULL) { + $$->annotations_ = $9->annotations_; + delete $9; + } } FlagArgs: @@ -830,13 +858,17 @@ FunctionList: } Function: - CaptureDocText Oneway FunctionType tok_identifier '(' FieldList ')' Throws CommaOrSemicolonOptional + CaptureDocText Oneway FunctionType tok_identifier '(' FieldList ')' Throws TypeAnnotations CommaOrSemicolonOptional { $6->set_name(std::string($4) + "_args"); $$ = new t_function($3, $4, $6, $8, $2); if ($1 != NULL) { $$->set_doc($1); } + if ($9 != NULL) { + $$->annotations_ = $9->annotations_; + delete $9; + } } Oneway: diff --git a/compiler/cpp/test_parser.sh b/compiler/cpp/test_parser.sh new file mode 100644 index 00000000..066e09a6 --- /dev/null +++ b/compiler/cpp/test_parser.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +# Tests the parser, independently of whether any generators +# are correct or useful. +# Currently only tests that valid .thrift files parse cleanly. +# Doesn't test that correct information is extracted from them. + +shopt -s extglob + +MY_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +ROOT_DIR=`cd $MY_DIR/../../ && pwd` +TEST_THRIFT_DIR=${ROOT_DIR}/test +THRIFT_FILES=`find ${TEST_THRIFT_DIR} -type f -name *.thrift ! -name BrokenConstants.thrift` + +OUTPUT_DIR=`mktemp -d -t test_thrift_parser.XXXXX` + +PASS=0 +FAIL=0 +for f in ${THRIFT_FILES}; +do + echo "Parsing ${f}" + ${MY_DIR}/thrift -o ${OUTPUT_DIR} -nowarn --allow-64bit-consts --gen cpp ${f} + EXIT_CODE=$? + if [ ${EXIT_CODE} -eq 0 ]; then + let PASS=PASS+1 + else + let FAIL=FAIL+1 + fi +done +echo +echo "${PASS} files parsed correctly. ${FAIL} files failed to parse." diff --git a/test/AnnotationTest.thrift b/test/AnnotationTest.thrift index 1a34320c..dac476f5 100644 --- a/test/AnnotationTest.thrift +++ b/test/AnnotationTest.thrift @@ -30,5 +30,33 @@ struct foo { java.final = "", ) -typedef string ( unicode.encoding = "UTF-16" ) non_latin_string +exception foo_error { + 1: i32 error_code ( foo="bar" ) + 2: string error_msg +} (foo = "bar") + +typedef string ( unicode.encoding = "UTF-16" ) non_latin_string (foo="bar") typedef list< double ( cpp.fixed_point = "16" ) > tiny_float_list + +enum weekdays { + SUNDAY ( weekend = "yes" ), + MONDAY, + TUESDAY, + WEDNESDAY, + THURSDAY, + FRIDAY, + SATURDAY ( weekend = "yes" ) +} (foo.bar="baz") + +/* Note that annotations on senum values are not supported. */ +senum seasons { + "Spring", + "Summer", + "Fall", + "Winter" +} ( foo = "bar" ) + +service foo_service { + void foo() ( foo = "bar" ) +} (a.b="c") + -- 2.17.1