@@ -332,10 +332,67 @@ def genAmqpException(c,v,cls):
332332-export([lookup_amqp_exception/1]).
333333-export([amqp_exception/1]).
334334
335- bitvalue(true) -> 1;
336- bitvalue(false) -> 0;
337- bitvalue(undefined) -> 0.
335+ """
336+ print "%% Various types"
337+ print "-ifdef(use_specs)."
338+
339+ print """-export_type([amqp_table/0, amqp_property_type/0, amqp_method_record/0,
340+ amqp_method_name/0, amqp_method/0, amqp_class_id/0,
341+ amqp_value/0, amqp_array/0, amqp_exception/0, amqp_property_record/0]).
342+
343+ -type(amqp_field_type() ::
344+ 'longstr' | 'signedint' | 'decimal' | 'timestamp' |
345+ 'table' | 'byte' | 'double' | 'float' | 'long' |
346+ 'short' | 'bool' | 'binary' | 'void').
347+ -type(amqp_property_type() ::
348+ 'shortstr' | 'longstr' | 'octet' | 'shortint' | 'longint' |
349+ 'longlongint' | 'timestamp' | 'bit' | 'table').
350+
351+ -type(amqp_table() :: [{binary(), amqp_field_type(), amqp_value()}]).
352+ -type(amqp_array() :: [{amqp_field_type(), amqp_value()}]).
353+ -type(amqp_value() :: binary() | % longstr
354+ integer() | % signedint
355+ {non_neg_integer(), non_neg_integer()} | % decimal
356+ amqp_table() |
357+ amqp_array() |
358+ byte() | % byte
359+ float() | % double
360+ integer() | % long
361+ integer() | % short
362+ boolean() | % bool
363+ binary() | % binary
364+ 'undefined' | % void
365+ non_neg_integer() % timestamp
366+ ).
367+ """
368+
369+ print prettyType ("amqp_method_name()" ,
370+ [m .erlangName () for m in methods ])
371+ print prettyType ("amqp_method()" ,
372+ ["{%s, %s}" % (m .klass .index , m .index ) for m in methods ],
373+ 6 )
374+ print prettyType ("amqp_method_record()" ,
375+ ["#%s{}" % (m .erlangName ()) for m in methods ])
376+ fieldNames = set ()
377+ for m in methods :
378+ fieldNames .update (m .arguments )
379+ fieldNames = [erlangize (f .name ) for f in fieldNames ]
380+ print prettyType ("amqp_method_field_name()" ,
381+ fieldNames )
382+ print prettyType ("amqp_property_record()" ,
383+ ["#'P_%s'{}" % erlangize (c .name ) for c in spec .allClasses ()])
384+ print prettyType ("amqp_exception()" ,
385+ ["'%s'" % erlangConstantName (c ).lower () for (c , v , cls ) in spec .constants ])
386+ print prettyType ("amqp_exception_code()" ,
387+ ["%i" % v for (c , v , cls ) in spec .constants ])
388+ classIds = set ()
389+ for m in spec .allMethods ():
390+ classIds .add (m .klass .index )
391+ print prettyType ("amqp_class_id()" ,
392+ ["%i" % ci for ci in classIds ])
393+ print "-endif. % use_specs"
338394
395+ print """
339396%% Method signatures
340397-ifdef(use_specs).
341398-spec(lookup_method_name/1 :: (amqp_method()) -> amqp_method_name()).
@@ -351,6 +408,10 @@ def genAmqpException(c,v,cls):
351408-spec(lookup_amqp_exception/1 :: (amqp_exception()) -> {boolean(), amqp_exception_code(), binary()}).
352409-spec(amqp_exception/1 :: (amqp_exception_code()) -> amqp_exception()).
353410-endif. % use_specs
411+
412+ bitvalue(true) -> 1;
413+ bitvalue(false) -> 0;
414+ bitvalue(undefined) -> 0.
354415"""
355416 for m in methods : genLookupMethodName (m )
356417 print "lookup_method_name({_ClassId, _MethodId} = Id) -> exit({unknown_method_id, Id})."
@@ -425,75 +486,14 @@ def fillField(field):
425486 for c in spec .allClasses ():
426487 print "-record('P_%s', {%s})." % (erlangize (c .name ), fieldNameList (c .fields ))
427488
428- print "-ifdef(use_specs)."
429- print "%% Various types"
430- print prettyType ("amqp_method_name()" ,
431- [m .erlangName () for m in methods ])
432- print prettyType ("amqp_method()" ,
433- ["{%s, %s}" % (m .klass .index , m .index ) for m in methods ],
434- 6 )
435- print prettyType ("amqp_method_record()" ,
436- ["#%s{}" % (m .erlangName ()) for m in methods ])
437- fieldNames = set ()
438- for m in methods :
439- fieldNames .update (m .arguments )
440- fieldNames = [erlangize (f .name ) for f in fieldNames ]
441- print prettyType ("amqp_method_field_name()" ,
442- fieldNames )
443- print prettyType ("amqp_property_record()" ,
444- ["#'P_%s'{}" % erlangize (c .name ) for c in spec .allClasses ()])
445- print prettyType ("amqp_exception()" ,
446- ["'%s'" % erlangConstantName (c ).lower () for (c , v , cls ) in spec .constants ])
447- print prettyType ("amqp_exception_code()" ,
448- ["%i" % v for (c , v , cls ) in spec .constants ])
449- print "-endif. % use_specs"
450-
451- def genSpec (spec ):
452- methods = spec .allMethods ()
453-
454- printFileHeader ()
455- print """% Hard-coded types
456- -type(amqp_field_type() ::
457- 'longstr' | 'signedint' | 'decimal' | 'timestamp' |
458- 'table' | 'byte' | 'double' | 'float' | 'long' |
459- 'short' | 'bool' | 'binary' | 'void').
460- -type(amqp_property_type() ::
461- 'shortstr' | 'longstr' | 'octet' | 'shortint' | 'longint' |
462- 'longlongint' | 'timestamp' | 'bit' | 'table').
463- %% we could make this more precise but ultimately are limited by
464- %% dialyzer's lack of support for recursive types
465- -type(amqp_table() :: [{binary(), amqp_field_type(), any()}]).
466- %% TODO: make this more precise
467- -type(amqp_properties() :: tuple()).
468-
469- -type(channel_number() :: non_neg_integer()).
470- -type(resource_name() :: binary()).
471- -type(routing_key() :: binary()).
472- -type(username() :: binary()).
473- -type(password() :: binary()).
474- -type(vhost() :: binary()).
475- -type(ctag() :: binary()).
476- -type(exchange_type() :: atom()).
477- -type(binding_key() :: binary()).
478- """
479- print "% Auto-generated types"
480- classIds = set ()
481- for m in spec .allMethods ():
482- classIds .add (m .klass .index )
483- print prettyType ("amqp_class_id()" ,
484- ["%i" % ci for ci in classIds ])
485489
486490def generateErl (specPath ):
487491 genErl (AmqpSpec (specPath ))
488492
489493def generateHrl (specPath ):
490494 genHrl (AmqpSpec (specPath ))
491495
492- def generateSpec (specPath ):
493- genSpec (AmqpSpec (specPath ))
494-
495496if __name__ == "__main__" :
496497 do_main_dict ({"header" : generateHrl ,
497- "spec" : generateSpec ,
498498 "body" : generateErl })
499499
0 commit comments