internal override IEnumerable <NameExpression> Walk() { Type = RedwoodType.Make(this); base.Walk(); DeclaredVariable.KnownType = RedwoodType.GetForCSharpType(typeof(RedwoodType)); DeclaredVariable.DefinedConstant = true; DeclaredVariable.ConstantValue = Type; List <NameExpression> freeVars = new List <NameExpression>(); List <Variable> declaredVars = new List <Variable>(); InterfaceImplicitConversionVars = new List <Variable>(); int maxConstructorArgs = 0; This = new Variable { Name = "this", KnownType = Type }; declaredVars.Add(This); if (ParameterFields != null) { maxConstructorArgs = ParameterFields.Length; foreach (ParameterDefinition param in ParameterFields) { freeVars.AddRange(param.Walk()); declaredVars.Add(param.DeclaredVariable); } } foreach (TypeSyntax interfaceType in Interfaces) { freeVars.AddRange(interfaceType.Walk()); // TODO: What if we inherit an implicit, or if we // a function that is meant to represent this, or // an implicit declared function? InterfaceImplicitConversionVars.Add( new Variable { Name = RuntimeUtil.GetNameOfConversionToType(interfaceType.TypeName.Name), Closured = true, DefinedConstant = true } ); } foreach (LetDefinition field in InstanceFields) { freeVars.AddRange(field.Walk()); declaredVars.Add(field.DeclaredVariable); } foreach (FunctionDefinition constructor in Constructors) { freeVars.AddRange(constructor.Walk()); maxConstructorArgs = Math.Max(maxConstructorArgs, constructor.Parameters.Length); } TempArgumentVariables = new List <Variable>(); for (int i = 0; i < maxConstructorArgs; i++) { TempArgumentVariables.Add(new Variable { Temporary = true }); } foreach (FunctionDefinition method in Methods) { freeVars.AddRange(method.Walk()); // Closure these variables even though they aren't in the // object's map so that they can be directly accessed method.DeclaredVariable.Closured = true; } Overloads = Compiler.GenerateOverloads(Methods.ToList()); declaredVars.AddRange(Overloads.Select(o => o.variable)); declaredVars.AddRange(InterfaceImplicitConversionVars); MemberVariables = declaredVars; // Make sure that all of our variables end up in the closure that // makes up our RedwoodObject foreach (Variable member in declaredVars) { member.Closured = true; } // Treat the class as a closure that can be populated and then // updated by all methods. Compiler.MatchVariables(freeVars, declaredVars); // When it comes to static methods, we don't want to match to // our own instance variables. foreach (FunctionDefinition method in StaticMethods) { freeVars.AddRange(method.Walk()); } StaticOverloads = Compiler.GenerateOverloads(StaticMethods.ToList()); return(freeVars); }