예제 #1
0
        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>();

            // The set of variables which must be supplied when creating the interface
            List <Variable> varsSupplied = new List <Variable>();

            This = new Variable
            {
                Name      = "this",
                KnownType = null, // Dynamic since the reference isn't necessarily our own type
            };
            declaredVars.Add(This);
            varsSupplied.Add(This);

            foreach (FunctionDefinition method in Methods)
            {
                // Make sure that the method is a stub
                if (method.Body != null)
                {
                    throw new NotImplementedException();
                }

                freeVars.AddRange(method.Walk());
                // As in the ClassDefinition, these need to be closured variables
                method.DeclaredVariable.Closured = true;
                varsSupplied.Add(method.DeclaredVariable);
            }

            // For every raw function and the this variable,
            // we're going to need to take is as an argument
            // for building the interface. Each of these should
            // live on the stack as they are variables.
            ArgumentVariables = varsSupplied
                                .Select(variable =>
                                        new Variable
            {
                Name = variable.Name
            }
                                        )
                                .ToList();
            SuppliedVariables = varsSupplied;

            Overloads = Compiler.GenerateOverloads(Methods.ToList());
            declaredVars.AddRange(Overloads.Select(o => o.variable));

            foreach (Variable variable in declaredVars)
            {
                variable.Closured = true;
            }

            Variables = declaredVars;

            // There is no need to match against the fields of the class as
            // all methods are stubs, and no code is closured against the
            // interface itself.
            return(freeVars);
        }
예제 #2
0
        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);
        }