示例#1
0
 // Local scopes
 public static Node[] NodesToInitializeInScope(this DocumentScope scope)
 {
     return(scope
            .NodesDeclaredInScope().Where(n => n is NewObjectNode || n is NameTableNode)
            .Concat(new [] { scope })
            .ToArray());
 }
示例#2
0
        public static Lambda GenerateScopeConstructor(this DocumentScope scope, TypeName simulatedType, TypeName producedType, Context ctx)
        {
            var nodesToDeclare    = scope.NodesDeclaredInScope();
            var nodesToInitialize = scope.NodesToInitializeInScope();

            var usedNames = ctx.Names;
            var self      = usedNames.GetUniqueName();
            var names     = usedNames.Add(scope, self).GenerateNames(nodesToDeclare);
            var newCtx    = ctx.With(names: names);

            var parameters = ImmutableList <Parameter> .Empty;

            var cs = scope as ClassNode;

            if (cs != null)
            {
                parameters = cs.DeclaredDependencies
                             .Select(x => new Parameter(TypeName.Parse(x.ResultingType.FullName), names[x]))
                             .ToImmutableList();
            }

            var isApp = parameters.Count == 0 && producedType == App;

            if (isApp)
            {
                parameters = List.Create(new Parameter(App, Variable.This));
            }

            var baseParameters = scope.Properties
                                 .Where(x => x.Facet.IsConstructorArgument && x.HasValue)
                                 .Select(x =>
            {
                if (x is ReferenceProperty)
                {
                    return(((ReferenceProperty)x).Source.GetExpression(newCtx));
                }
                else if (x is AtomicProperty)
                {
                    return(((AtomicProperty)x).Value.GetExpression(newCtx));
                }
                else
                {
                    throw new Exception("Unsupported constructor argument property type");
                }
            })
                                 .ToArray();

            return(new Lambda(
                       new Signature(
                           parameters: parameters,
                           returnType: producedType),
                       localVariables:
                       new[]
            {
                new BindVariable(self,
                                 isApp
                                                        ? new ReadVariable(Variable.This) // use object passed to ctor as this for the App tag
                                                        : producedType.Instantiate(baseParameters, newCtx, newCtx.TryGetTagHash(scope)))
            }
                       .Concat(nodesToDeclare.GetDeclarations(newCtx)),
                       statements:
                       nodesToInitialize
                       .GetInitializations(newCtx)
                       .Concat(new [] { new Return(new ReadVariable(self)) })));
        }