55using System ;
66using System . Collections . Generic ;
77using System . Collections . ObjectModel ;
8+ using System . Diagnostics . CodeAnalysis ;
89using System . Linq ;
910using System . Runtime . CompilerServices ;
1011using System . Threading ;
1920using LightLambdaExpression = Microsoft . Scripting . Ast . LightLambdaExpression ;
2021using MSAst = System . Linq . Expressions ;
2122
23+ #nullable enable
24+
2225namespace IronPython . Compiler . Ast {
2326 using Ast = MSAst . Expression ;
2427
@@ -27,18 +30,18 @@ public class ClassDefinition : ScopeStatement {
2730 private readonly Arg [ ] _bases ;
2831 private readonly Arg [ ] _keywords ;
2932
30- private LightLambdaExpression _dlrBody ; // the transformed body including all of our initialization, etc...
33+ private LightLambdaExpression ? _dlrBody ; // the transformed body including all of our initialization, etc...
3134
3235 private static int _classId ;
3336
3437 private static readonly MSAst . ParameterExpression _parentContextParam = Ast . Parameter ( typeof ( CodeContext ) , "$parentContext" ) ;
3538 private static readonly MSAst . Expression _tupleExpression = MSAst . Expression . Call ( AstMethods . GetClosureTupleFromContext , _parentContextParam ) ;
3639
37- public ClassDefinition ( string name , IReadOnlyList < Arg > bases , IReadOnlyList < Arg > keywords , Statement body = null ) {
40+ public ClassDefinition ( string name , IReadOnlyList < Arg > ? bases , IReadOnlyList < Arg > ? keywords , Statement ? body = null ) {
3841 _name = name ;
3942 _bases = bases ? . ToArray ( ) ?? Array . Empty < Arg > ( ) ;
4043 _keywords = keywords ? . ToArray ( ) ?? Array . Empty < Arg > ( ) ;
41- Body = body ;
44+ Body = body ?? EmptyStatement . PreCompiledInstance ;
4245 Metaclass = _keywords . Where ( arg => arg . Name == "metaclass" ) . Select ( arg => arg . Expression ) . FirstOrDefault ( ) ;
4346 }
4447
@@ -52,34 +55,41 @@ public ClassDefinition(string name, IReadOnlyList<Arg> bases, IReadOnlyList<Arg>
5255
5356 public IReadOnlyList < Arg > Keywords => _keywords ;
5457
55- public Expression Metaclass { get ; }
58+ public Expression ? Metaclass { get ; }
5659
5760 public Statement Body { get ; set ; }
5861
59- public IList < Expression > Decorators { get ; internal set ; }
62+ public IList < Expression > ? Decorators { get ; internal set ; }
6063
6164 /// <summary>
62- /// Variable corresponding to the class name
65+ /// Variable corresponding to the class name, set during name binding
6366 /// </summary>
64- internal PythonVariable PythonVariable { get ; set ; }
67+ [ DisallowNull ]
68+ internal PythonVariable ? PythonVariable { get ; set ; }
6569
6670 /// <summary>
67- /// Variable for the the __module__ (module name)
71+ /// Variable for the the __module__ (module name), set during name binding
6872 /// </summary>
69- internal PythonVariable ModVariable { get ; set ; }
73+ [ DisallowNull ]
74+ internal PythonVariable ? ModVariable { get ; set ; }
7075
7176 /// <summary>
72- /// Variable for the __doc__ attribute
77+ /// Variable for the __doc__ attribute, set during name binding
7378 /// </summary>
74- internal PythonVariable DocVariable { get ; set ; }
79+ [ DisallowNull ]
80+ internal PythonVariable ? DocVariable { get ; set ; }
7581
7682 /// <summary>
77- /// Variable for the module's __name__
83+ /// Variable for the module's __name__, set during name binding
7884 /// </summary>
79- internal PythonVariable ModuleNameVariable { get ; set ; }
85+ [ DisallowNull ]
86+ internal PythonVariable ? ModuleNameVariable { get ; set ; }
8087
81- private PythonVariable ClassCellVariable { get ; set ; }
82- private PythonVariable ClassVariable { get ; set ; }
88+ // set during name binding
89+ [ DisallowNull ]
90+ private PythonVariable ? ClassCellVariable { get ; set ; }
91+ [ DisallowNull ]
92+ private PythonVariable ? ClassVariable { get ; set ; }
8393
8494 internal override bool HasLateBoundVariableSets {
8595 get {
@@ -111,8 +121,8 @@ internal override bool TryBindOuter(ScopeStatement from, PythonReference referen
111121 return base . TryBindOuter ( from , reference , out variable ) ;
112122 }
113123
114- internal override PythonVariable BindReference ( PythonNameBinder binder , PythonReference reference ) {
115- PythonVariable variable ;
124+ internal override PythonVariable ? BindReference ( PythonNameBinder binder , PythonReference reference ) {
125+ PythonVariable ? variable ;
116126
117127 // Python semantics: The variables bound local in the class
118128 // scope are accessed by name - the dictionary behavior of classes
@@ -187,7 +197,7 @@ public override MSAst.Expression Reduce() {
187197 classDef = AddDecorators ( classDef , Decorators ) ;
188198
189199 return GlobalParent . AddDebugInfoAndVoid (
190- AssignValue ( Parent . GetVariableExpression ( PythonVariable ) , classDef ) ,
200+ AssignValue ( Parent . GetVariableExpression ( PythonVariable ! ) , classDef ) ,
191201 new SourceSpan (
192202 GlobalParent . IndexToLocation ( StartIndex ) ,
193203 GlobalParent . IndexToLocation ( HeaderIndex )
@@ -242,8 +252,8 @@ private Microsoft.Scripting.Ast.LightExpression<Func<CodeContext, CodeContext>>
242252 init . Add ( Ast . Assign ( LocalCodeContextVariable , createLocal ) ) ;
243253 // __classcell__ == ClosureCell(__class__)
244254 if ( needClassCell ) {
245- var exp = ( ClosureExpression ) GetVariableExpression ( ClassVariable ) ;
246- MSAst . Expression assignClassCell = AssignValue ( GetVariableExpression ( ClassCellVariable ) , exp . ClosureCell ) ;
255+ var exp = ( ClosureExpression ) GetVariableExpression ( ClassVariable ! ) ;
256+ MSAst . Expression assignClassCell = AssignValue ( GetVariableExpression ( ClassCellVariable ! ) , exp . ClosureCell ) ;
247257 init . Add ( assignClassCell ) ;
248258 }
249259
@@ -253,13 +263,13 @@ private Microsoft.Scripting.Ast.LightExpression<Func<CodeContext, CodeContext>>
253263
254264
255265 // __module__ = __name__
256- MSAst . Expression modStmt = AssignValue ( GetVariableExpression ( ModVariable ) , GetVariableExpression ( ModuleNameVariable ) ) ;
266+ MSAst . Expression modStmt = AssignValue ( GetVariableExpression ( ModVariable ! ) , GetVariableExpression ( ModuleNameVariable ! ) ) ;
257267
258268 string doc = GetDocumentation ( Body ) ;
259269 if ( doc != null ) {
260270 statements . Add (
261271 AssignValue (
262- GetVariableExpression ( DocVariable ) ,
272+ GetVariableExpression ( DocVariable ! ) ,
263273 AstUtils . Constant ( doc )
264274 )
265275 ) ;
@@ -325,7 +335,7 @@ public override void Walk(PythonWalker walker) {
325335 foreach ( Arg b in _keywords ) {
326336 b . Walk ( walker ) ;
327337 }
328- Body ? . Walk ( walker ) ;
338+ Body . Walk ( walker ) ;
329339 }
330340 walker . PostWalk ( this ) ;
331341 }
0 commit comments