@@ -239,15 +239,19 @@ private IEnumerable<Class> EnumerateClasses(DeclarationContext context)
239
239
240
240
public virtual void GenerateNamespaceFunctionsAndVariables ( DeclarationContext context )
241
241
{
242
+ var hasGlobalFunctions = ! ( context is Class ) && context . Functions . Any (
243
+ f => f . IsGenerated ) ;
244
+
242
245
var hasGlobalVariables = ! ( context is Class ) && context . Variables . Any (
243
246
v => v . IsGenerated && v . Access == AccessSpecifier . Public ) ;
244
247
245
- if ( ! context . Functions . Any ( f => f . IsGenerated ) && ! hasGlobalVariables )
248
+ if ( ! hasGlobalFunctions && ! hasGlobalVariables )
246
249
return ;
247
250
248
- PushBlock ( BlockKind . Functions ) ;
249
251
var parentName = SafeIdentifier ( context . TranslationUnit . FileNameWithoutExtension ) ;
250
252
253
+ PushBlock ( BlockKind . Functions ) ;
254
+
251
255
var keyword = "class" ;
252
256
var classes = EnumerateClasses ( ) . ToList ( ) ;
253
257
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
271
275
UnindentAndWriteCloseBrace ( ) ;
272
276
PopBlock ( NewLineKind . BeforeNextBlock ) ;
273
277
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 ) )
278
279
GenerateFunction ( function , parentName ) ;
279
- }
280
280
281
281
foreach ( var variable in context . Variables . Where (
282
282
v => v . IsGenerated && v . Access == AccessSpecifier . Public ) )
@@ -443,7 +443,8 @@ public override bool VisitClassDecl(Class @class)
443
443
}
444
444
445
445
GenerateClassConstructors ( @class ) ;
446
-
446
+ foreach ( Function function in @class . Functions . Where ( f => f . IsGenerated ) )
447
+ GenerateFunction ( function , @class . Name ) ;
447
448
GenerateClassMethods ( @class . Methods ) ;
448
449
GenerateClassVariables ( @class ) ;
449
450
GenerateClassProperties ( @class ) ;
@@ -649,6 +650,10 @@ private void GatherClassInternalFunctions(Class @class, bool includeCtors,
649
650
&& ! functions . Contains ( prop . SetMethod ) )
650
651
tryAddOverload ( prop . SetMethod ) ;
651
652
}
653
+
654
+ functions . AddRange ( from function in @class . Functions
655
+ where function . IsGenerated && ! function . IsSynthetized
656
+ select function ) ;
652
657
}
653
658
654
659
private IEnumerable < string > GatherInternalParams ( Function function , out TypePrinterResult retType )
@@ -2323,6 +2328,8 @@ public void GenerateFunction(Function function, string parentName)
2323
2328
2324
2329
if ( function . SynthKind == FunctionSynthKind . DefaultValueOverload )
2325
2330
GenerateOverloadCall ( function ) ;
2331
+ else if ( function . IsOperator )
2332
+ GenerateOperator ( function , default ( QualifiedType ) ) ;
2326
2333
else
2327
2334
GenerateInternalFunctionCall ( function ) ;
2328
2335
@@ -2650,24 +2657,24 @@ private string GetVirtualCallDelegate(Method method)
2650
2657
return delegateId ;
2651
2658
}
2652
2659
2653
- private void GenerateOperator ( Method method , QualifiedType returnType )
2660
+ private void GenerateOperator ( Function function , QualifiedType returnType )
2654
2661
{
2655
- if ( method . SynthKind == FunctionSynthKind . ComplementOperator )
2662
+ if ( function . SynthKind == FunctionSynthKind . ComplementOperator )
2656
2663
{
2657
- if ( method . Kind == CXXMethodKind . Conversion )
2664
+ if ( function is Method method && method . Kind == CXXMethodKind . Conversion )
2658
2665
{
2659
2666
// 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 ( ) ;
2661
2668
paramType = ( paramType . GetPointee ( ) ?? paramType ) . Desugar ( ) ;
2662
2669
Class paramClass ;
2663
2670
Class @interface = null ;
2664
2671
if ( paramType . TryGetClass ( out paramClass ) )
2665
2672
@interface = paramClass . GetInterface ( ) ;
2666
2673
2667
2674
var paramName = string . Format ( "{0}{1}" ,
2668
- method . Parameters [ 0 ] . Type . IsPrimitiveTypeConvertibleToRef ( ) ?
2675
+ function . Parameters [ 0 ] . Type . IsPrimitiveTypeConvertibleToRef ( ) ?
2669
2676
"ref *" : string . Empty ,
2670
- method . Parameters [ 0 ] . Name ) ;
2677
+ function . Parameters [ 0 ] . Name ) ;
2671
2678
var printedType = method . ConversionType . Visit ( TypePrinter ) ;
2672
2679
if ( @interface != null )
2673
2680
{
@@ -2679,30 +2686,45 @@ private void GenerateOperator(Method method, QualifiedType returnType)
2679
2686
}
2680
2687
else
2681
2688
{
2682
- var @operator = Operators . GetOperatorOverloadPair ( method . OperatorKind ) ;
2689
+ var @operator = Operators . GetOperatorOverloadPair ( function . OperatorKind ) ;
2683
2690
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
+ }
2686
2705
}
2687
2706
return ;
2688
2707
}
2689
2708
2690
- if ( method . OperatorKind == CXXOperatorKind . EqualEqual ||
2691
- method . OperatorKind == CXXOperatorKind . ExclaimEqual )
2709
+ if ( function . OperatorKind == CXXOperatorKind . EqualEqual ||
2710
+ function . OperatorKind == CXXOperatorKind . ExclaimEqual )
2692
2711
{
2693
2712
WriteLine ( "bool {0}Null = ReferenceEquals({0}, null);" ,
2694
- method . Parameters [ 0 ] . Name ) ;
2713
+ function . Parameters [ 0 ] . Name ) ;
2695
2714
WriteLine ( "bool {0}Null = ReferenceEquals({0}, null);" ,
2696
- method . Parameters [ 1 ] . Name ) ;
2715
+ function . Parameters [ 1 ] . Name ) ;
2697
2716
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 : ")" ) } ;" ) ;
2703
2725
}
2704
2726
2705
- GenerateInternalFunctionCall ( method , returnType : returnType ) ;
2727
+ GenerateInternalFunctionCall ( function , returnType : returnType ) ;
2706
2728
}
2707
2729
2708
2730
private void GenerateClassConstructor ( Method method , Class @class )
0 commit comments