99import six
1010import sys
1111
12- from babelapi .babel .parser import BabelParser
13- from babelapi .data_type import (
12+ from ..api import (
13+ Api ,
14+ ApiRoute ,
15+ )
16+ from ..data_type import (
1417 Binary ,
1518 Boolean ,
1619 DataType ,
3134 Union ,
3235 Void ,
3336)
34- from babelapi .api import (
35- Api ,
36- ApiRoute ,
37- )
38- from babelapi .babel .parser import (
37+
38+ from .exception import InvalidSpec
39+ from .parser import (
3940 BabelAlias ,
4041 BabelInclude ,
4142 BabelNamespace ,
43+ BabelParser ,
4244 BabelRouteDef ,
4345 BabelVoidField ,
4446 BabelTagRef ,
4547 BabelTypeDef ,
4648 BabelTypeRef ,
4749)
4850
49- class InvalidSpec (Exception ):
50- """Raise this to indicate there was an error in a specification."""
51-
52- def __init__ (self , msg , lineno , path = None ):
53- """
54- Args:
55- msg: Error message intended for the spec writer to read.
56- lineno: The line number the error occurred on.
57- path: Path to the spec file with the error.
58- """
59- assert isinstance (msg , six .text_type )
60- assert isinstance (lineno , six .integer_types )
61- self .msg = msg
62- self .lineno = lineno
63- self .path = path
64-
65- def __str__ (self ):
66- return repr (self )
67-
68- def __repr__ (self ):
69- return 'InvalidSpec({!r}, {!r}, {!r})' .format (
70- self .msg ,
71- self .lineno ,
72- self .path ,
73- )
74-
7551def quote (s ):
7652 assert s .replace ('_' , '' ).isalnum (), \
7753 'Only use quote() with names or IDs in Babel.'
@@ -203,8 +179,12 @@ def _create_type(self, env, item):
203179 raise InvalidSpec (
204180 'Data type %s is undefined.' % quote (item .extends ),
205181 item .lineno )
206- else :
207- supertype = env .get (item .extends )
182+ supertype = env [item .extends ]
183+ if not isinstance (supertype , Struct ):
184+ raise InvalidSpec (
185+ 'A struct can only extend another struct: '
186+ '%s is not a struct.' % quote (item .extends ),
187+ item .lineno )
208188 api_type_fields = []
209189 for babel_field in item .fields :
210190 api_type_field = self ._create_struct_field (env , babel_field )
@@ -218,8 +198,12 @@ def _create_type(self, env, item):
218198 raise InvalidSpec (
219199 'Data type %s is undefined.' % quote (item .extends ),
220200 item .lineno )
221- else :
222- subtype = env .get (item .extends )
201+ subtype = env [item .extends ]
202+ if not isinstance (subtype , Union ):
203+ raise InvalidSpec (
204+ 'A union can only extend another union: '
205+ '%s is not a union.' % quote (item .extends ),
206+ item .lineno )
223207 api_type_fields = []
224208 catch_all_field = None
225209 for babel_field in item .fields :
@@ -243,7 +227,6 @@ def _create_type(self, env, item):
243227
244228 catch_all_field = api_type_field
245229 api_type_fields .append (api_type_field )
246-
247230 api_type = Union (item .name , item .doc , api_type_fields , item ,
248231 subtype , catch_all_field )
249232 else :
0 commit comments