@@ -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,10 @@ 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 ( var function in from function in context . Functions
279+ where function . IsGenerated
280+ select function )
278281 GenerateFunction ( function , parentName ) ;
279- }
280282
281283 foreach ( var variable in context . Variables . Where (
282284 v => v . IsGenerated && v . Access == AccessSpecifier . Public ) )
@@ -443,7 +445,10 @@ public override bool VisitClassDecl(Class @class)
443445 }
444446
445447 GenerateClassConstructors ( @class ) ;
446-
448+ foreach ( var function in from function in @class . Functions
449+ where function . IsGenerated
450+ select function )
451+ GenerateFunction ( function , @class . Name ) ;
447452 GenerateClassMethods ( @class . Methods ) ;
448453 GenerateClassVariables ( @class ) ;
449454 GenerateClassProperties ( @class ) ;
@@ -649,6 +654,10 @@ private void GatherClassInternalFunctions(Class @class, bool includeCtors,
649654 && ! functions . Contains ( prop . SetMethod ) )
650655 tryAddOverload ( prop . SetMethod ) ;
651656 }
657+
658+ functions . AddRange ( from function in @class . Functions
659+ where function . IsGenerated && ! function . IsSynthetized
660+ select function ) ;
652661 }
653662
654663 private IEnumerable < string > GatherInternalParams ( Function function , out TypePrinterResult retType )
@@ -2323,6 +2332,8 @@ public void GenerateFunction(Function function, string parentName)
23232332
23242333 if ( function . SynthKind == FunctionSynthKind . DefaultValueOverload )
23252334 GenerateOverloadCall ( function ) ;
2335+ else if ( function . IsOperator )
2336+ GenerateOperator ( function , default ( QualifiedType ) ) ;
23262337 else
23272338 GenerateInternalFunctionCall ( function ) ;
23282339
@@ -2650,24 +2661,24 @@ private string GetVirtualCallDelegate(Method method)
26502661 return delegateId ;
26512662 }
26522663
2653- private void GenerateOperator ( Method method , QualifiedType returnType )
2664+ private void GenerateOperator ( Function function , QualifiedType returnType )
26542665 {
2655- if ( method . SynthKind == FunctionSynthKind . ComplementOperator )
2666+ if ( function . SynthKind == FunctionSynthKind . ComplementOperator )
26562667 {
2657- if ( method . Kind == CXXMethodKind . Conversion )
2668+ if ( function is Method method && method . Kind == CXXMethodKind . Conversion )
26582669 {
26592670 // To avoid ambiguity when having the multiple inheritance pass enabled
2660- var paramType = method . Parameters [ 0 ] . Type . SkipPointerRefs ( ) . Desugar ( ) ;
2671+ var paramType = function . Parameters [ 0 ] . Type . SkipPointerRefs ( ) . Desugar ( ) ;
26612672 paramType = ( paramType . GetPointee ( ) ?? paramType ) . Desugar ( ) ;
26622673 Class paramClass ;
26632674 Class @interface = null ;
26642675 if ( paramType . TryGetClass ( out paramClass ) )
26652676 @interface = paramClass . GetInterface ( ) ;
26662677
26672678 var paramName = string . Format ( "{0}{1}" ,
2668- method . Parameters [ 0 ] . Type . IsPrimitiveTypeConvertibleToRef ( ) ?
2679+ function . Parameters [ 0 ] . Type . IsPrimitiveTypeConvertibleToRef ( ) ?
26692680 "ref *" : string . Empty ,
2670- method . Parameters [ 0 ] . Name ) ;
2681+ function . Parameters [ 0 ] . Name ) ;
26712682 var printedType = method . ConversionType . Visit ( TypePrinter ) ;
26722683 if ( @interface != null )
26732684 {
@@ -2679,30 +2690,44 @@ private void GenerateOperator(Method method, QualifiedType returnType)
26792690 }
26802691 else
26812692 {
2682- var @operator = Operators . GetOperatorOverloadPair ( method . OperatorKind ) ;
2693+ var @operator = Operators . GetOperatorOverloadPair ( function . OperatorKind ) ;
26832694
2684- WriteLine ( "return !({0} {1} {2});" , method . Parameters [ 0 ] . Name ,
2685- @operator , method . Parameters [ 1 ] . Name ) ;
2695+ Type retType = function . OriginalReturnType . Type . Desugar ( ) ;
2696+ bool regular = retType . IsPrimitiveType ( PrimitiveType . Bool ) ;
2697+ if ( regular )
2698+ {
2699+ WriteLine ( $@ "return !({ function . Parameters [ 0 ] . Name } {
2700+ @operator } { function . Parameters [ 1 ] . Name } );" ) ;
2701+ }
2702+ else
2703+ {
2704+ WriteLine ( $@ "return global::System.Convert.ToInt32(({
2705+ function . Parameters [ 0 ] . Name } { @operator } {
2706+ function . Parameters [ 1 ] . Name } ) == 0);" ) ;
2707+ }
26862708 }
26872709 return ;
26882710 }
26892711
2690- if ( method . OperatorKind == CXXOperatorKind . EqualEqual ||
2691- method . OperatorKind == CXXOperatorKind . ExclaimEqual )
2712+ if ( function . OperatorKind == CXXOperatorKind . EqualEqual ||
2713+ function . OperatorKind == CXXOperatorKind . ExclaimEqual )
26922714 {
26932715 WriteLine ( "bool {0}Null = ReferenceEquals({0}, null);" ,
2694- method . Parameters [ 0 ] . Name ) ;
2716+ function . Parameters [ 0 ] . Name ) ;
26952717 WriteLine ( "bool {0}Null = ReferenceEquals({0}, null);" ,
2696- method . Parameters [ 1 ] . Name ) ;
2718+ function . Parameters [ 1 ] . Name ) ;
26972719 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 : ")" ) ;
2720+ function . Parameters [ 0 ] . Name , function . Parameters [ 1 ] . Name ) ;
2721+ Type retType = function . OriginalReturnType . Type . Desugar ( ) ;
2722+ bool regular = retType . IsPrimitiveType ( PrimitiveType . Bool ) ;
2723+ WriteLineIndent ( $@ "return { ( regular ? string . Empty : "global::System.Convert.ToInt32(" ) } {
2724+ ( function . OperatorKind == CXXOperatorKind . EqualEqual ? string . Empty : "!(" ) } {
2725+ function . Parameters [ 0 ] . Name } Null && { function . Parameters [ 1 ] . Name } Null{
2726+ ( function . OperatorKind == CXXOperatorKind . EqualEqual ? string . Empty : ")" ) } {
2727+ ( regular ? string . Empty : ")" ) } ;" ) ;
27032728 }
27042729
2705- GenerateInternalFunctionCall ( method , returnType : returnType ) ;
2730+ GenerateInternalFunctionCall ( function , returnType : returnType ) ;
27062731 }
27072732
27082733 private void GenerateClassConstructor ( Method method , Class @class )
0 commit comments