@@ -89,8 +89,8 @@ abstract private class GeneratedType extends ValueOrRefType, GeneratedElement {
8989 else
9090 result = this .stubComment ( ) + this .stubAttributes ( ) + this .stubAbstractModifier ( ) +
9191 this .stubStaticModifier ( ) + this .stubAccessibilityModifier ( ) + this .stubKeyword ( ) + " " +
92- this .getUndecoratedName ( ) + stubGenericArguments ( this ) + stubBaseTypesString ( ) + "\n{\n" +
93- stubMembers ( ) + "}\n\n"
92+ this .getUndecoratedName ( ) + stubGenericArguments ( this ) + stubBaseTypesString ( ) +
93+ stubTypeParametersConstraints ( this ) + "\n{\n" + stubMembers ( ) + "}\n\n"
9494 }
9595
9696 private ValueOrRefType getAnInterestingBaseType ( ) {
@@ -270,11 +270,16 @@ private string stubAccessibility(Member m) {
270270}
271271
272272private string stubModifiers ( Member m ) {
273- result = stubAccessibility ( m ) + stubStatic ( m ) + stubOverride ( m )
273+ result = stubAccessibility ( m ) + stubStaticOrConst ( m ) + stubOverride ( m )
274274}
275275
276- private string stubStatic ( Member m ) {
277- if m .( Modifiable ) .isStatic ( ) then result = "static " else result = ""
276+ private string stubStaticOrConst ( Member m ) {
277+ if m .( Modifiable ) .isStatic ( )
278+ then result = "static "
279+ else
280+ if m .( Modifiable ) .isConst ( )
281+ then result = "const "
282+ else result = ""
278283}
279284
280285private string stubOverride ( Member m ) {
@@ -386,18 +391,136 @@ private string stubGenericMethodParams(Method m) {
386391 else result = ""
387392}
388393
394+ private string stubConstraints ( TypeParameterConstraints tpc ) {
395+ tpc .hasConstructorConstraint ( ) and result = "new()"
396+ or
397+ tpc .hasUnmanagedTypeConstraint ( ) and result = "unmanaged"
398+ or
399+ tpc .hasValueTypeConstraint ( ) and result = "struct"
400+ or
401+ tpc .hasRefTypeConstraint ( ) and result = "class"
402+ or
403+ result = tpc .getATypeParameterConstraint ( ) .getName ( )
404+ or
405+ result = stubClassName ( tpc .getAnInterfaceConstraint ( ) )
406+ or
407+ result = stubClassName ( tpc .getClassConstraint ( ) )
408+ }
409+
410+ private string stubTypeParameterConstraints ( TypeParameter tp ) {
411+ exists ( TypeParameterConstraints tpc | tpc = tp .getConstraints ( ) |
412+ result = " where " + tp .getName ( ) + ": " +
413+ strictconcat ( string s | s = stubConstraints ( tpc ) | s , ", " )
414+ )
415+ }
416+
417+ private string stubTypeParametersConstraints ( Declaration d ) {
418+ if d instanceof UnboundGeneric
419+ then
420+ result = concat ( TypeParameter tp |
421+ tp = d .( UnboundGeneric ) .getATypeParameter ( )
422+ |
423+ stubTypeParameterConstraints ( tp ) , " "
424+ )
425+ else result = ""
426+ }
427+
389428private string stubImplementation ( Virtualizable c ) {
390429 if c .isAbstract ( ) or c .getDeclaringType ( ) instanceof Interface
391430 then result = ""
392431 else result = " => throw null"
393432}
394433
434+ private predicate isKeyword ( string s ) {
435+ s = "abstract" or
436+ s = "as" or
437+ s = "base" or
438+ s = "bool" or
439+ s = "break" or
440+ s = "byte" or
441+ s = "case" or
442+ s = "catch" or
443+ s = "char" or
444+ s = "checked" or
445+ s = "class" or
446+ s = "const" or
447+ s = "continue" or
448+ s = "decimal" or
449+ s = "default" or
450+ s = "delegate" or
451+ s = "do" or
452+ s = "double" or
453+ s = "else" or
454+ s = "enum" or
455+ s = "event" or
456+ s = "explicit" or
457+ s = "extern" or
458+ s = "false" or
459+ s = "finally" or
460+ s = "fixed" or
461+ s = "float" or
462+ s = "for" or
463+ s = "foreach" or
464+ s = "goto" or
465+ s = "if" or
466+ s = "implicit" or
467+ s = "in" or
468+ s = "int" or
469+ s = "interface" or
470+ s = "internal" or
471+ s = "is" or
472+ s = "lock" or
473+ s = "long" or
474+ s = "namespace" or
475+ s = "new" or
476+ s = "null" or
477+ s = "object" or
478+ s = "operator" or
479+ s = "out" or
480+ s = "override" or
481+ s = "params" or
482+ s = "private" or
483+ s = "protected" or
484+ s = "public" or
485+ s = "readonly" or
486+ s = "ref" or
487+ s = "return" or
488+ s = "sbyte" or
489+ s = "sealed" or
490+ s = "short" or
491+ s = "sizeof" or
492+ s = "stackalloc" or
493+ s = "static" or
494+ s = "string" or
495+ s = "struct" or
496+ s = "switch" or
497+ s = "this" or
498+ s = "throw" or
499+ s = "true" or
500+ s = "try" or
501+ s = "typeof" or
502+ s = "uint" or
503+ s = "ulong" or
504+ s = "unchecked" or
505+ s = "unsafe" or
506+ s = "ushort" or
507+ s = "using" or
508+ s = "using static" or
509+ s = "virtual" or
510+ s = "void" or
511+ s = "volatile" or
512+ s = "while"
513+ }
514+
515+ bindingset [ s]
516+ private string escapeIfKeyword ( string s ) { if isKeyword ( s ) then result = "@" + s else result = s }
517+
395518private string stubParameters ( Parameterizable p ) {
396519 result = concat ( int i , Parameter param |
397520 param = p .getParameter ( i ) and not param .getType ( ) instanceof ArglistType
398521 |
399- stubParameterModifiers ( param ) + stubClassName ( param .getType ( ) ) + " " + param . getName ( ) +
400- stubDefaultValue ( param ) , ", "
522+ stubParameterModifiers ( param ) + stubClassName ( param .getType ( ) ) + " " +
523+ escapeIfKeyword ( param . getName ( ) ) + stubDefaultValue ( param ) , ", "
401524 order by
402525 i
403526 )
@@ -437,7 +560,7 @@ private string stubMember(Member m) {
437560 exists ( Method c | m = c and not m .getDeclaringType ( ) instanceof Enum |
438561 result = " " + stubModifiers ( c ) + stubClassName ( c .getReturnType ( ) ) + " " +
439562 stubExplicitImplementation ( c ) + c .getName ( ) + stubGenericMethodParams ( c ) + "(" +
440- stubParameters ( c ) + ")" + stubImplementation ( c ) + ";\n"
563+ stubParameters ( c ) + ")" + stubTypeParametersConstraints ( c ) + stubImplementation ( c ) + ";\n"
441564 )
442565 or
443566 exists ( Operator op |
@@ -469,8 +592,10 @@ private string stubMember(Member m) {
469592 "] { " + stubGetter ( i ) + stubSetter ( i ) + "}\n"
470593 )
471594 or
472- exists ( Field f | f = m and not f instanceof EnumConstant |
473- result = " " + stubModifiers ( m ) + stubClassName ( f .getType ( ) ) + " " + f .getName ( ) + ";\n"
595+ exists ( Field f , string impl | f = m and not f instanceof EnumConstant |
596+ ( if f .isConst ( ) then impl = " = throw null" else impl = "" ) and
597+ result = " " + stubModifiers ( m ) + stubClassName ( f .getType ( ) ) + " " + f .getName ( ) + impl +
598+ ";\n"
474599 )
475600}
476601
0 commit comments