1212using IronPython . Runtime ;
1313
1414using Microsoft . Scripting ;
15+ using Microsoft . Scripting . Actions ;
1516using Microsoft . Scripting . Utils ;
1617
1718using AstUtils = Microsoft . Scripting . Ast . Utils ;
@@ -23,7 +24,7 @@ namespace IronPython.Compiler.Ast {
2324
2425 public class ClassDefinition : ScopeStatement {
2526 private readonly string _name ;
26- private readonly Expression [ ] _bases ;
27+ private readonly Arg [ ] _bases ;
2728 private readonly Arg [ ] _keywords ;
2829
2930 private LightLambdaExpression _dlrBody ; // the transformed body including all of our initialization, etc...
@@ -33,15 +34,12 @@ public class ClassDefinition : ScopeStatement {
3334 private static readonly MSAst . ParameterExpression _parentContextParam = Ast . Parameter ( typeof ( CodeContext ) , "$parentContext" ) ;
3435 private static readonly MSAst . Expression _tupleExpression = MSAst . Expression . Call ( AstMethods . GetClosureTupleFromContext , _parentContextParam ) ;
3536
36- public ClassDefinition ( string name , Expression [ ] bases , Arg [ ] keywords , Statement body = null ) {
37- ContractUtils . RequiresNotNullItems ( bases , nameof ( bases ) ) ;
38- ContractUtils . RequiresNotNullItems ( keywords , nameof ( keywords ) ) ;
39-
37+ public ClassDefinition ( string name , IReadOnlyList < Arg > bases , IReadOnlyList < Arg > keywords , Statement body = null ) {
4038 _name = name ;
41- _bases = bases ;
42- _keywords = keywords ;
39+ _bases = bases ? . ToArray ( ) ?? Array . Empty < Arg > ( ) ;
40+ _keywords = keywords ? . ToArray ( ) ?? Array . Empty < Arg > ( ) ;
4341 Body = body ;
44- Metaclass = keywords . Where ( arg => arg . Name == "metaclass" ) . Select ( arg => arg . Expression ) . FirstOrDefault ( ) ;
42+ Metaclass = _keywords . Where ( arg => arg . Name == "metaclass" ) . Select ( arg => arg . Expression ) . FirstOrDefault ( ) ;
4543 }
4644
4745 public SourceLocation Header => GlobalParent . IndexToLocation ( HeaderIndex ) ;
@@ -50,7 +48,7 @@ public ClassDefinition(string name, Expression[] bases, Arg[] keywords, Statemen
5048
5149 public override string Name => _name ;
5250
53- public IReadOnlyList < Expression > Bases => _bases ;
51+ public IReadOnlyList < Arg > Bases => _bases ;
5452
5553 public IReadOnlyList < Arg > Keywords => _keywords ;
5654
@@ -181,10 +179,7 @@ public override MSAst.Expression Reduce() {
181179 lambda ,
182180 Parent . LocalContext ,
183181 AstUtils . Constant ( _name ) ,
184- Ast . NewArrayInit (
185- typeof ( object ) ,
186- ToObjectArray ( _bases )
187- ) ,
182+ UnpackBasesHelper ( _bases ) ,
188183 Metaclass is null ? AstUtils . Constant ( null , typeof ( object ) ) : AstUtils . Convert ( Metaclass , typeof ( object ) ) ,
189184 AstUtils . Constant ( FindSelfNames ( ) )
190185 ) ;
@@ -198,6 +193,33 @@ public override MSAst.Expression Reduce() {
198193 GlobalParent . IndexToLocation ( HeaderIndex )
199194 )
200195 ) ;
196+
197+ // Compare to: CallExpression.Reduce.__UnpackListHelper
198+ static MSAst . Expression UnpackBasesHelper ( IReadOnlyList < Arg > bases ) {
199+ if ( bases . Count == 0 ) {
200+ return Expression . Call ( AstMethods . MakeEmptyTuple ) ;
201+ } else if ( bases . All ( arg => arg . ArgumentInfo . Kind is ArgumentType . Simple ) ) {
202+ return Expression . Call ( AstMethods . MakeTuple ,
203+ Expression . NewArrayInit (
204+ typeof ( object ) ,
205+ ToObjectArray ( bases . Select ( arg => arg . Expression ) . ToList ( ) )
206+ )
207+ ) ;
208+ } else {
209+ var expressions = new ReadOnlyCollectionBuilder < MSAst . Expression > ( bases . Count + 2 ) ;
210+ var varExpr = Expression . Variable ( typeof ( PythonList ) , "$coll" ) ;
211+ expressions . Add ( Expression . Assign ( varExpr , Expression . Call ( AstMethods . MakeEmptyList ) ) ) ;
212+ foreach ( var arg in bases ) {
213+ if ( arg . ArgumentInfo . Kind == ArgumentType . List ) {
214+ expressions . Add ( Expression . Call ( AstMethods . ListExtend , varExpr , AstUtils . Convert ( arg . Expression , typeof ( object ) ) ) ) ;
215+ } else {
216+ expressions . Add ( Expression . Call ( AstMethods . ListAppend , varExpr , AstUtils . Convert ( arg . Expression , typeof ( object ) ) ) ) ;
217+ }
218+ }
219+ expressions . Add ( Expression . Call ( AstMethods . ListToTuple , varExpr ) ) ;
220+ return Expression . Block ( typeof ( PythonTuple ) , new MSAst . ParameterExpression [ ] { varExpr } , expressions ) ;
221+ }
222+ }
201223 }
202224
203225 private Microsoft . Scripting . Ast . LightExpression < Func < CodeContext , CodeContext > > MakeClassBody ( ) {
@@ -297,10 +319,11 @@ public override void Walk(PythonWalker walker) {
297319 decorator . Walk ( walker ) ;
298320 }
299321 }
300- if ( _bases != null ) {
301- foreach ( Expression b in _bases ) {
302- b . Walk ( walker ) ;
303- }
322+ foreach ( Arg b in _bases ) {
323+ b . Walk ( walker ) ;
324+ }
325+ foreach ( Arg b in _keywords ) {
326+ b . Walk ( walker ) ;
304327 }
305328 Body ? . Walk ( walker ) ;
306329 }
0 commit comments