@@ -19,6 +19,7 @@ along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
1919
2020#include " Interface.h"
2121#include " InterfacePrivate.h"
22+ #include " NativeType.h"
2223
2324// //////////////////////////////////////////////////////////////////////////////
2425
@@ -38,7 +39,8 @@ enum InterfaceError
3839 kInterfaceErrorParamAlreadyDefined ,
3940 kInterfaceErrorInvalidParameterType ,
4041 kInterfaceErrorOptionalParamImpliesIn ,
41- kInterfaceErrorNoOptionalBoolean ,
42+ kInterfaceErrorNonPointerOptionalParameterMustHaveDefaultValue ,
43+ kInterfaceErrorDefaultWrongType ,
4244 kInterfaceErrorUnknownType ,
4345 kInterfaceErrorJavaImpliesInParam ,
4446 kInterfaceErrorMethodsCannotHaveVariants ,
@@ -120,8 +122,11 @@ static bool InterfaceReport(InterfaceRef self, Position p_where, InterfaceError
120122 case kInterfaceErrorOptionalParamImpliesIn :
121123 fprintf (stderr, " Optional parameters must be of 'in' type\n " );
122124 break ;
123- case kInterfaceErrorNoOptionalBoolean :
124- fprintf (stderr, " Optional boolean parameters not yet supported\n " );
125+ case kInterfaceErrorNonPointerOptionalParameterMustHaveDefaultValue :
126+ fprintf (stderr, " Default values must be specified for non-pointer type optional parameters\n " );
127+ break ;
128+ case kInterfaceErrorDefaultWrongType :
129+ fprintf (stderr, " Default specified is the wrong type\n " );
125130 break ;
126131 case kInterfaceErrorUnknownType :
127132 fprintf (stderr, " Unknown type '%s'\n " , StringGetCStringPtr (NameGetString ((NameRef)p_hint)));
@@ -406,11 +411,11 @@ bool InterfaceEndHandler(InterfaceRef self)
406411 return true ;
407412}
408413
409- bool InterfaceDefineHandlerParameter (InterfaceRef self, Position p_where, ParameterType p_param_type, NameRef p_name, NameRef p_type, ValueRef p_default)
414+ bool InterfaceDefineHandlerParameter (InterfaceRef self, Position p_where, ParameterType p_param_type, NameRef p_name, NameRef p_type, ValueRef p_default, bool p_optional )
410415{
411416 static const char *s_param_types[] = {" in" , " out" , " inout" , " ref" };
412417 MCLog (" %s - %s%s parameter %s as %s" , PositionDescribe (p_where),
413- p_default != nil ? " optional " : " " ,
418+ p_optional ? " optional " : " " ,
414419 s_param_types[p_param_type],
415420 StringGetCStringPtr (NameGetString (p_name)),
416421 StringGetCStringPtr (NameGetString (p_type)));
@@ -424,11 +429,46 @@ bool InterfaceDefineHandlerParameter(InterfaceRef self, Position p_where, Parame
424429 // RULE: 'ref' not currently supported
425430 if (p_param_type == kParameterTypeRef )
426431 InterfaceReport (self, p_where, kInterfaceErrorInvalidParameterType , nil);
427-
428- // RULE: optional 'boolean' not currently supported
429- if (NameEqualToCString (p_type, " boolean" ) && p_default != nil)
430- InterfaceReport (self, p_where, kInterfaceErrorNoOptionalBoolean , nil);
431-
432+
433+ // RULE: only pointer types may not have a default value
434+ if (p_optional && p_default == nil &&
435+ (NameEqualToCString (p_type, " boolean" ) ||
436+ NameEqualToCString (p_type, " integer" ) ||
437+ NameEqualToCString (p_type, " real" ) ||
438+ NameEqualToCString (p_type, " c-data" )))
439+ InterfaceReport (self, p_where, kInterfaceErrorNonPointerOptionalParameterMustHaveDefaultValue , nil);
440+
441+ NativeType t_native_type;
442+ t_native_type = NativeTypeFromName (p_type);
443+
444+ // RULE: wrong default type
445+ if (p_default != nil)
446+ {
447+ bool t_correct_type = false ;
448+ switch (t_native_type) {
449+ case kNativeTypeBoolean :
450+ t_correct_type = ValueIsBoolean (p_default);
451+ break ;
452+ case kNativeTypeInteger :
453+ t_correct_type = ValueIsInteger (p_default);
454+ break ;
455+ case kNativeTypeReal :
456+ t_correct_type = ValueIsReal (p_default) || ValueIsInteger (p_default);
457+ break ;
458+ case kNativeTypeObjcString :
459+ case kNativeTypeCString :
460+ case kNativeTypeEnum :
461+ t_correct_type = ValueIsString (p_default);
462+ break ;
463+ default :
464+ t_correct_type = false ;
465+ break ;
466+ }
467+
468+ if (!t_correct_type)
469+ InterfaceReport (self, p_where, kInterfaceErrorDefaultWrongType , nil);
470+ }
471+
432472 // RULE: optional parameters can only be 'in'
433473 if (p_default != nil && p_param_type != kParameterTypeIn )
434474 InterfaceReport (self, p_where, kInterfaceErrorOptionalParamImpliesIn , nil);
@@ -442,9 +482,9 @@ bool InterfaceDefineHandlerParameter(InterfaceRef self, Position p_where, Parame
442482 }
443483
444484 // RULE: No non-optional parameters after an optional one
445- if (p_default == nil &&
485+ if (!p_optional &&
446486 t_variant -> parameter_count > 0 &&
447- t_variant -> parameters[t_variant -> parameter_count - 1 ] . default_value != nil )
487+ t_variant -> parameters[t_variant -> parameter_count - 1 ] . is_optional )
448488 InterfaceReport (self, p_where, kInterfaceErrorParamAfterOptionalParam , nil);
449489
450490 // RULE: If java handler, then only in parameters are allowed.
@@ -460,8 +500,9 @@ bool InterfaceDefineHandlerParameter(InterfaceRef self, Position p_where, Parame
460500 t_variant -> parameters[t_variant -> parameter_count - 1 ] . name = ValueRetain (p_name);
461501 t_variant -> parameters[t_variant -> parameter_count - 1 ] . type = ValueRetain (p_type);
462502 t_variant -> parameters[t_variant -> parameter_count - 1 ] . default_value = ValueRetain (p_default);
503+ t_variant -> parameters[t_variant -> parameter_count - 1 ] . is_optional = p_optional;
463504
464- if (p_default == nil )
505+ if (!p_optional )
465506 t_variant -> minimum_parameter_count += 1 ;
466507
467508 return true ;
0 commit comments