Beispiel #1
0
 public TypeRepresentation(InstanceState state, int numExportsBoundToInstance, int numStepsToRootType, JST.Expression keyField, JST.Expression typeClassifier, bool undefininedIsNotNull)
 {
     State = state;
     NumExportsBoundToInstance = numExportsBoundToInstance;
     NumStepsToRootType = numStepsToRootType;
     KeyField = keyField;
     TypeClassifier = typeClassifier;
     UndefininedIsNotNull = undefininedIsNotNull;
 }
 private void BindBaseTypes(CST.TypeEnvironment thisTypeEnv, JST.Expression thisType)
 {
     if (thisTypeEnv.Type.Extends != null)
     {
         var baseTypeEnv = thisTypeEnv.Type.Extends.Enter(thisTypeEnv);
         var baseType    = JST.Expression.Dot(thisType, Constants.TypeBaseType);
         if (!boundTypes.ContainsKey(baseTypeEnv.TypeRef))
         {
             boundTypes.Add(baseTypeEnv.TypeRef, new ExpressionAndPhase(baseType, TypePhase.Slots));
         }
         if (baseTypeEnv.Type.Arity > 0)
         {
             if (!boundTypes.ContainsKey(baseTypeEnv.TypeConstructorRef))
             {
                 boundTypes.Add(baseTypeEnv.TypeConstructorRef, new ExpressionAndPhase(JST.Expression.Dot(baseType, Constants.TypeApplicand), TypePhase.Slots));
             }
         }
         BindBaseTypes(baseTypeEnv, baseType);
     }
 }
 public ExpressionAndPhase(JST.Expression expression, TypePhase phase)
 {
     Expression = expression;
     Phase      = phase;
 }
 public ExpressionAndPhase(JST.Expression expression, TypePhase phase)
 {
     Expression = expression;
     Phase = phase;
 }
Beispiel #5
0
        // ----------------------------------------------------------------------
        // Methods
        // ----------------------------------------------------------------------

        // Emit bindings for static or instance methods, but not for virtuals or interface methods
        //  - Invoked from TypeDefinitionCompiler for higher-kinded type definitions
        //  - Invoked from TypeCompiler for first-kinded type definitions
        public void EmitMethods(Seq <JST.Statement> body, JST.Expression lhs, JST.NameSupply outerNameSupply, JST.Expression target, bool isStatic)
        {
            switch (Env.CompilationMode)
            {
            case CompilationMode.Plain:
            {
                // Method definitions are bound directly into target
                foreach (var methodDef in Methods.Where(m => m.Invalid == null))
                {
                    if (Env.InteropManager.IsStatic(TyconEnv.Assembly, TyconEnv.Type, methodDef) == isStatic)
                    {
                        var compiler = new MethodCompiler(this, outerNameSupply, methodDef, MethodCompilationMode.DirectBind);
                        compiler.Emit(body, target);
                    }
                }
                break;
            }

            case CompilationMode.Collecting:
            {
                // Method definitions are bound into MethodCache, redirectors are bound into target
                foreach (var methodDef in Methods.Where(m => m.Invalid == null))
                {
                    if (Env.InteropManager.IsStatic(TyconEnv.Assembly, TyconEnv.Type, methodDef) == isStatic)
                    {
                        var slot       = Env.GlobalMapping.ResolveMethodDefToSlot(TyconEnv.Assembly, TyconEnv.Type, methodDef);
                        var methodName = CST.CSTWriter.WithAppend
                                             (Env.Global, CST.WriterStyle.Uniform, methodDef.MethodSignature.Append);
                        body.Add
                            (JST.Statement.DotCall
                                (RootId.ToE(),
                                Constants.RootCollectingBindMethodBuilder,
                                lhs,
                                new JST.BooleanLiteral(isStatic),
                                new JST.StringLiteral(slot),
                                new JST.StringLiteral(methodName)));
                        var compiler = new MethodCompiler(this, outerNameSupply, methodDef, MethodCompilationMode.DirectBind);
                        compiler.Emit(body, JST.Expression.Dot(target, Constants.TypeMethodCache));
                    }
                }
                break;
            }

            case CompilationMode.Traced:
            {
                // Methods in the initial trace or this trace will be bound directly.
                // Methods in a trace other than above are bound via builder which is given trace name.
                // Remaining methods are built via builder with null trace name.
                var traceToArgs   = new Map <string, Seq <JST.Expression> >();
                var remainingArgs = new Seq <JST.Expression>();
                remainingArgs.Add(TypeDefinitionId.ToE());
                remainingArgs.Add(new JST.BooleanLiteral(isStatic));
                remainingArgs.Add(new JST.NullExpression());
                foreach (var methodDef in Methods.Where(m => m.Invalid == null))
                {
                    if (Env.InteropManager.IsStatic(TyconEnv.Assembly, TyconEnv.Type, methodDef) == isStatic)
                    {
                        var slot     = Env.GlobalMapping.ResolveMethodDefToSlot(TyconEnv.Assembly, TyconEnv.Type, methodDef);
                        var defTrace = Env.Traces.MethodToTrace[methodDef.QualifiedMemberName(Env.Global, TyconEnv.Assembly, TyconEnv.Type)];
                        if (defTrace.Flavor == TraceFlavor.OnDemand && defTrace != TypeTrace.Parent.Parent)
                        {
                            // Method definition in in another trace, bind redirector for it.
                            var args = default(Seq <JST.Expression>);
                            if (!traceToArgs.TryGetValue(defTrace.Name, out args))
                            {
                                args = new Seq <JST.Expression>();
                                args.Add(lhs);
                                args.Add(new JST.BooleanLiteral(isStatic));
                                args.Add(new JST.StringLiteral(defTrace.Name));
                                traceToArgs.Add(defTrace.Name, args);
                            }
                            args.Add(new JST.StringLiteral(slot));
                        }
                        else if (defTrace.Flavor == TraceFlavor.Remainder)
                        {
                            // Method definition is in a stand-alone loader, bind redirector for it.
                            remainingArgs.Add(new JST.StringLiteral(slot));
                        }
                        else
                        {
                            // Method definition is bound directly
                            var compiler = new MethodCompiler(this, outerNameSupply, methodDef, MethodCompilationMode.DirectBind);
                            compiler.Emit(body, target);
                        }
                    }
                }
                foreach (var kv in traceToArgs)
                {
                    body.Add(JST.Statement.DotCall(RootId.ToE(), Constants.RootBindMethodBuilders, kv.Value));
                }
                if (remainingArgs.Count > 3)
                {
                    body.Add(JST.Statement.DotCall(RootId.ToE(), Constants.RootBindMethodBuilders, remainingArgs));
                }
                break;
            }

            default:
                throw new ArgumentOutOfRangeException();
            }
        }