// Local scopes public static Node[] NodesToInitializeInScope(this DocumentScope scope) { return(scope .NodesDeclaredInScope().Where(n => n is NewObjectNode || n is NameTableNode) .Concat(new [] { scope }) .ToArray()); }
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)) }))); }