@@ -239,15 +239,19 @@ private IEnumerable<Class> EnumerateClasses(DeclarationContext context)
239239
240240 public virtual void GenerateNamespaceFunctionsAndVariables ( DeclarationContext context )
241241 {
242+ var hasGlobalFunctions = ! ( context is Class ) && context . Functions . Any (
243+ f => f . IsGenerated ) ;
244+
242245 var hasGlobalVariables = ! ( context is Class ) && context . Variables . Any (
243246 v => v . IsGenerated && v . Access == AccessSpecifier . Public ) ;
244247
245- if ( ! context . Functions . Any ( f => f . IsGenerated ) && ! hasGlobalVariables )
248+ if ( ! hasGlobalFunctions && ! hasGlobalVariables )
246249 return ;
247250
248- PushBlock ( BlockKind . Functions ) ;
249251 var parentName = SafeIdentifier ( context . TranslationUnit . FileNameWithoutExtension ) ;
250252
253+ PushBlock ( BlockKind . Functions ) ;
254+
251255 var keyword = "class" ;
252256 var classes = EnumerateClasses ( ) . ToList ( ) ;
253257 if ( classes . FindAll ( cls => cls . IsValueType && cls . Name == parentName && context . QualifiedLogicalName == cls . Namespace . QualifiedLogicalName ) . Any ( ) )
@@ -271,12 +275,8 @@ public virtual void GenerateNamespaceFunctionsAndVariables(DeclarationContext co
271275 UnindentAndWriteCloseBrace ( ) ;
272276 PopBlock ( NewLineKind . BeforeNextBlock ) ;
273277
274- foreach ( var function in context . Functions )
275- {
276- if ( ! function . IsGenerated ) continue ;
277-
278+ foreach ( Function function in context . Functions . Where ( f => f . IsGenerated ) )
278279 GenerateFunction ( function , parentName ) ;
279- }
280280
281281 foreach ( var variable in context . Variables . Where (
282282 v => v . IsGenerated && v . Access == AccessSpecifier . Public ) )
@@ -443,7 +443,8 @@ public override bool VisitClassDecl(Class @class)
443443 }
444444
445445 GenerateClassConstructors ( @class ) ;
446-
446+ foreach ( Function function in @class . Functions . Where ( f => f . IsGenerated ) )
447+ GenerateFunction ( function , @class . Name ) ;
447448 GenerateClassMethods ( @class . Methods ) ;
448449 GenerateClassVariables ( @class ) ;
449450 GenerateClassProperties ( @class ) ;
@@ -649,6 +650,10 @@ private void GatherClassInternalFunctions(Class @class, bool includeCtors,
649650 && ! functions . Contains ( prop . SetMethod ) )
650651 tryAddOverload ( prop . SetMethod ) ;
651652 }
653+
654+ functions . AddRange ( from function in @class . Functions
655+ where function . IsGenerated && ! function . IsSynthetized
656+ select function ) ;
652657 }
653658
654659 private IEnumerable < string > GatherInternalParams ( Function function , out TypePrinterResult retType )
@@ -2323,6 +2328,8 @@ public void GenerateFunction(Function function, string parentName)
23232328
23242329 if ( function . SynthKind == FunctionSynthKind . DefaultValueOverload )
23252330 GenerateOverloadCall ( function ) ;
2331+ else if ( function . IsOperator )
2332+ GenerateOperator ( function , default ( QualifiedType ) ) ;
23262333 else
23272334 GenerateInternalFunctionCall ( function ) ;
23282335
@@ -2650,24 +2657,24 @@ private string GetVirtualCallDelegate(Method method)
26502657 return delegateId ;
26512658 }
26522659
2653- private void GenerateOperator ( Method method , QualifiedType returnType )
2660+ private void GenerateOperator ( Function function , QualifiedType returnType )
26542661 {
2655- if ( method . SynthKind == FunctionSynthKind . ComplementOperator )
2662+ if ( function . SynthKind == FunctionSynthKind . ComplementOperator )
26562663 {
2657- if ( method . Kind == CXXMethodKind . Conversion )
2664+ if ( function is Method method && method . Kind == CXXMethodKind . Conversion )
26582665 {
26592666 // To avoid ambiguity when having the multiple inheritance pass enabled
2660- var paramType = method . Parameters [ 0 ] . Type . SkipPointerRefs ( ) . Desugar ( ) ;
2667+ var paramType = function . Parameters [ 0 ] . Type . SkipPointerRefs ( ) . Desugar ( ) ;
26612668 paramType = ( paramType . GetPointee ( ) ?? paramType ) . Desugar ( ) ;
26622669 Class paramClass ;
26632670 Class @interface = null ;
26642671 if ( paramType . TryGetClass ( out paramClass ) )
26652672 @interface = paramClass . GetInterface ( ) ;
26662673
26672674 var paramName = string . Format ( "{0}{1}" ,
2668- method . Parameters [ 0 ] . Type . IsPrimitiveTypeConvertibleToRef ( ) ?
2675+ function . Parameters [ 0 ] . Type . IsPrimitiveTypeConvertibleToRef ( ) ?
26692676 "ref *" : string . Empty ,
2670- method . Parameters [ 0 ] . Name ) ;
2677+ function . Parameters [ 0 ] . Name ) ;
26712678 var printedType = method . ConversionType . Visit ( TypePrinter ) ;
26722679 if ( @interface != null )
26732680 {
@@ -2679,30 +2686,45 @@ private void GenerateOperator(Method method, QualifiedType returnType)
26792686 }
26802687 else
26812688 {
2682- var @operator = Operators . GetOperatorOverloadPair ( method . OperatorKind ) ;
2689+ var @operator = Operators . GetOperatorOverloadPair ( function . OperatorKind ) ;
26832690
2684- WriteLine ( "return !({0} {1} {2});" , method . Parameters [ 0 ] . Name ,
2685- @operator , method . Parameters [ 1 ] . Name ) ;
2691+ // handle operators for comparison which return int instead of bool
2692+ Type retType = function . OriginalReturnType . Type . Desugar ( ) ;
2693+ bool regular = retType . IsPrimitiveType ( PrimitiveType . Bool ) ;
2694+ if ( regular )
2695+ {
2696+ WriteLine ( $@ "return !({ function . Parameters [ 0 ] . Name } {
2697+ @operator } { function . Parameters [ 1 ] . Name } );" ) ;
2698+ }
2699+ else
2700+ {
2701+ WriteLine ( $@ "return global::System.Convert.ToInt32(({
2702+ function . Parameters [ 0 ] . Name } { @operator } {
2703+ function . Parameters [ 1 ] . Name } ) == 0);" ) ;
2704+ }
26862705 }
26872706 return ;
26882707 }
26892708
2690- if ( method . OperatorKind == CXXOperatorKind . EqualEqual ||
2691- method . OperatorKind == CXXOperatorKind . ExclaimEqual )
2709+ if ( function . OperatorKind == CXXOperatorKind . EqualEqual ||
2710+ function . OperatorKind == CXXOperatorKind . ExclaimEqual )
26922711 {
26932712 WriteLine ( "bool {0}Null = ReferenceEquals({0}, null);" ,
2694- method . Parameters [ 0 ] . Name ) ;
2713+ function . Parameters [ 0 ] . Name ) ;
26952714 WriteLine ( "bool {0}Null = ReferenceEquals({0}, null);" ,
2696- method . Parameters [ 1 ] . Name ) ;
2715+ function . Parameters [ 1 ] . Name ) ;
26972716 WriteLine ( "if ({0}Null || {1}Null)" ,
2698- method . Parameters [ 0 ] . Name , method . Parameters [ 1 ] . Name ) ;
2699- WriteLineIndent ( "return {0}{1}Null && {2}Null{3};" ,
2700- method . OperatorKind == CXXOperatorKind . EqualEqual ? string . Empty : "!(" ,
2701- method . Parameters [ 0 ] . Name , method . Parameters [ 1 ] . Name ,
2702- method . OperatorKind == CXXOperatorKind . EqualEqual ? string . Empty : ")" ) ;
2717+ function . Parameters [ 0 ] . Name , function . Parameters [ 1 ] . Name ) ;
2718+ Type retType = function . OriginalReturnType . Type . Desugar ( ) ;
2719+ bool regular = retType . IsPrimitiveType ( PrimitiveType . Bool ) ;
2720+ WriteLineIndent ( $@ "return { ( regular ? string . Empty : "global::System.Convert.ToInt32(" ) } {
2721+ ( function . OperatorKind == CXXOperatorKind . EqualEqual ? string . Empty : "!(" ) } {
2722+ function . Parameters [ 0 ] . Name } Null && { function . Parameters [ 1 ] . Name } Null{
2723+ ( function . OperatorKind == CXXOperatorKind . EqualEqual ? string . Empty : ")" ) } {
2724+ ( regular ? string . Empty : ")" ) } ;" ) ;
27032725 }
27042726
2705- GenerateInternalFunctionCall ( method , returnType : returnType ) ;
2727+ GenerateInternalFunctionCall ( function , returnType : returnType ) ;
27062728 }
27072729
27082730 private void GenerateClassConstructor ( Method method , Class @class )
0 commit comments