public static TypeCompilerEnvironment EnterType
            (CompilerEnvironment env,
            JST.NameSupply nameSupply,
            JST.Identifier rootId,
            JST.Identifier assemblyId,
            JST.Identifier typeId,
            CST.TypeEnvironment typeEnv,
            TypeTrace typeTrace)
        {
            var typeBoundTypeParameterIds = new Seq <JST.Identifier>();

            for (var i = 0; i < typeEnv.Type.Arity; i++)
            {
                typeBoundTypeParameterIds.Add(nameSupply.GenSym());
            }

            var res = new TypeCompilerEnvironment
                          (typeEnv.Global,
                          typeEnv.SkolemDefs,
                          typeEnv.Assembly,
                          typeEnv.Type,
                          typeEnv.TypeBoundArguments,
                          env,
                          nameSupply,
                          rootId,
                          assemblyId,
                          typeId,
                          typeBoundTypeParameterIds,
                          typeTrace);

            res.BindSpecial();

            return(res);
        }
 private void InheritBindings(TypeCompilerEnvironment outer)
 {
     foreach (var kv in outer.boundAssemblies)
     {
         boundAssemblies.Add(kv.Key, kv.Value);
     }
     foreach (var kv in outer.boundTypes)
     {
         boundTypes.Add(kv.Key, kv.Value);
     }
 }
Example #3
0
 public TypeCompiler(TypeDefinitionCompiler parent)
 {
     // Type compiler is always in context of it's type definition
     Env = parent.Env;
     Parent = parent;
     var typeEnv = parent.TyconEnv.AddSelfTypeBoundArguments();
     NameSupply = typeEnv.Type.Arity > 0 ? parent.NameSupply.Fork() : parent.NameSupply;
     RootId = parent.RootId;
     AssemblyId = parent.AssemblyId;
     TypeDefinitionId = parent.TypeDefinitionId;
     TypeId = typeEnv.Type.Arity > 0 ? NameSupply.GenSym() : parent.TypeDefinitionId;
     TypeCompEnv = TypeCompilerEnvironment.EnterType(Env, NameSupply, RootId, AssemblyId, TypeId, typeEnv, parent.TypeTrace);
 }
        public TypeCompilerEnvironment EnterFunction()
        {
            var res = new TypeCompilerEnvironment
                          (Global,
                          SkolemDefs,
                          Assembly,
                          Type,
                          TypeBoundArguments,
                          env,
                          NameSupply.Fork(),
                          rootId,
                          assemblyId,
                          typeId,
                          TypeBoundTypeParameterIds,
                          typeTrace);

            res.InheritBindings(this);

            return(res);
        }
        public static TypeCompilerEnvironment EnterType
            (CompilerEnvironment env,
             JST.NameSupply nameSupply,
             JST.Identifier rootId,
             JST.Identifier assemblyId,
             JST.Identifier typeId,
             CST.TypeEnvironment typeEnv,
             TypeTrace typeTrace)
        {
            var typeBoundTypeParameterIds = new Seq<JST.Identifier>();
            for (var i = 0; i < typeEnv.Type.Arity; i++)
                typeBoundTypeParameterIds.Add(nameSupply.GenSym());

            var res = new TypeCompilerEnvironment
                (typeEnv.Global,
                 typeEnv.SkolemDefs,
                 typeEnv.Assembly,
                 typeEnv.Type,
                 typeEnv.TypeBoundArguments,
                 env,
                 nameSupply,
                 rootId,
                 assemblyId,
                 typeId,
                 typeBoundTypeParameterIds,
                 typeTrace);

            res.BindSpecial();

            return res;
        }
 private void InheritBindings(TypeCompilerEnvironment outer)
 {
     foreach (var kv in outer.boundAssemblies)
         boundAssemblies.Add(kv.Key, kv.Value);
     foreach (var kv in outer.boundTypes)
         boundTypes.Add(kv.Key, kv.Value);
 }
        public TypeCompilerEnvironment EnterFunction()
        {
            var res = new TypeCompilerEnvironment
                (Global,
                 SkolemDefs,
                 Assembly,
                 Type,
                 TypeBoundArguments,
                 env,
                 NameSupply.Fork(),
                 rootId,
                 assemblyId,
                 typeId,
                 TypeBoundTypeParameterIds,
                 typeTrace);

            res.InheritBindings(this);

            return res;
        }
Example #8
0
        public void EmitReflection(Seq<JST.Statement> body, TypeCompilerEnvironment innerTypeCompEnv, JST.Expression lhs)
        {
            var level = default(ReflectionLevel);
            Env.AttributeHelper.GetValueFromType
                (innerTypeCompEnv.Assembly,
                 innerTypeCompEnv.Type,
                 Env.AttributeHelper.ReflectionAttributeRef,
                 Env.AttributeHelper.TheReflectionLevelProperty,
                 true,
                 true,
                 ref level);

            if (level == ReflectionLevel.None && innerTypeCompEnv.Type.IsAttributeType(Env.Global, innerTypeCompEnv.Assembly))
                level = ReflectionLevel.Names;

            if (level >= ReflectionLevel.Names)
            {
                if (Env.DebugMode)
                    body.Add(new JST.CommentStatement("Reflection"));

                // ReflectionName
                body.Add
                    (JST.Statement.DotAssignment
                         (lhs, Constants.TypeReflectionName, ReflectionNameExpression(body, innerTypeCompEnv, false)));
                // ReflectionFullName
                body.Add
                    (JST.Statement.DotAssignment
                         (lhs,
                          Constants.TypeReflectionFullName,
                          ReflectionNameExpression(body, innerTypeCompEnv, true)));
                // ReflectionNamespace
                body.Add
                    (JST.Statement.DotAssignment
                         (lhs,
                          Constants.TypeReflectionNamespace,
                          ReflectionNamespaceExpression(body, innerTypeCompEnv)));


                if (level >= ReflectionLevel.Full)
                {

                    // ReflectionMemberInfos
                    body.Add
                        (JST.Statement.DotAssignment
                             (lhs, Constants.TypeReflectionMemberInfos, MemberInfoExpression(body, innerTypeCompEnv)));
                    // CustomAttributes
                    body.Add
                        (JST.Statement.DotAssignment
                             (lhs,
                              Constants.TypeReflectionCustomAttributes,
                              CustomAttributesExpression
                                  (body,
                                   innerTypeCompEnv,
                                   CST.MessageContextBuilders.Env(TypeCompEnv),
                                   TypeCompEnv.Type.CustomAttributes)));
                }
            }
        }
Example #9
0
 // Array of custom attributes
 private JST.Expression CustomAttributesExpression(Seq<JST.Statement> body, TypeCompilerEnvironment innerTypeCompEnv, MessageContext ctxt, IImSeq<CST.CustomAttribute> attributes)
 {
     var objs = new Seq<JST.Expression>();
     foreach (var attribute in attributes)
     {
         var obj = CustomAttributeExpression(body, innerTypeCompEnv, ctxt, attribute);
         if (obj != null)
             objs.Add(obj);
     }
     return new JST.ArrayLiteral(objs);
 }
Example #10
0
 private JST.Expression ReflectionNameExpression(Seq<JST.Statement> body, TypeCompilerEnvironment innerTypeCompEnv, bool isFullName)
 {
     var nm = CST.CSTWriter.WithAppend
         (Env.Global,
          isFullName ? CST.WriterStyle.ReflectionFullName : CST.WriterStyle.ReflectionName,
          innerTypeCompEnv.Type.EffectiveName(Env.Global).Append);
     var lit = new JST.StringLiteral(nm);
     if (innerTypeCompEnv.Type.Arity == 0)
         return lit;
     else
     {
         return JST.Expression.DotCall
             (RootId.ToE(),
              Constants.RootReflectionName,
              lit,
              new JST.ArrayLiteral
                  (innerTypeCompEnv.TypeBoundArguments.Select(t => innerTypeCompEnv.ResolveType(t, TypePhase.Id)).ToSeq()),
              new JST.BooleanLiteral(isFullName));
     }
 }
Example #11
0
        private JST.Expression MemberInfoExpression(Seq<JST.Statement> body, TypeCompilerEnvironment innerTypeCompEnv)
        {
            var sharedMethodInfos = new Map<CST.MethodSignature, JST.Identifier>();
            var id = default(JST.Identifier);
            foreach (var propDef in Parent.Properties)
            {
                if (propDef.Get != null)
                {
                    var infoExp = MethodInfoFromMethod(body, innerTypeCompEnv, innerTypeCompEnv.Type.ResolveMethod(propDef.Get));
                    if (infoExp != null)
                    {
                        id = innerTypeCompEnv.NameSupply.GenSym();
                        body.Add(JST.Statement.Var(id, infoExp));
                        sharedMethodInfos.Add(propDef.Get, id);
                    }
                }
                if (propDef.Set != null)
                {
                    var infoExp = MethodInfoFromMethod(body, innerTypeCompEnv, innerTypeCompEnv.Type.ResolveMethod(propDef.Set));
                    if (infoExp != null)
                    {
                        id = innerTypeCompEnv.NameSupply.GenSym();
                        body.Add(JST.Statement.Var(id, infoExp));
                        sharedMethodInfos.Add(propDef.Set, id);
                    }
                }
            }
            foreach (var eventDef in Parent.Events)
            {
                if (eventDef.Add != null)
                {
                    var infoExp = MethodInfoFromMethod(body, innerTypeCompEnv, innerTypeCompEnv.Type.ResolveMethod(eventDef.Add));
                    if (infoExp != null)
                    {
                        id = innerTypeCompEnv.NameSupply.GenSym();
                        body.Add(JST.Statement.Var(id, infoExp));
                        sharedMethodInfos.Add(eventDef.Add, id);
                    }

                }
                if (eventDef.Remove != null)
                {
                    var infoExp = MethodInfoFromMethod(body, innerTypeCompEnv, innerTypeCompEnv.Type.ResolveMethod(eventDef.Remove));
                    if (infoExp != null)
                    {
                        id = innerTypeCompEnv.NameSupply.GenSym();
                        body.Add(JST.Statement.Var(id, infoExp));
                        sharedMethodInfos.Add(eventDef.Remove, id);
                    }
                }
            }

            var infoExps = new Seq<JST.Expression>();
            foreach (var methodDef in Parent.Methods)
            {
                if (sharedMethodInfos.TryGetValue(methodDef.MethodSignature, out id))
                    infoExps.Add(id.ToE());
                else
                {
                    var infoExp = MethodInfoFromMethod(body, innerTypeCompEnv, methodDef);
                    if (infoExp != null)
                        infoExps.Add(infoExp);
                }
            }

            foreach (var fieldDef in Parent.Fields)
            {
                var infoExp = FieldInfoFromField(body, innerTypeCompEnv, fieldDef);
                if (infoExp != null)
                    infoExps.Add(infoExp);
            }

            foreach (var propDef in Parent.Properties)
            {
                var infoExp = PropertyInfoFromProperty(body, innerTypeCompEnv, sharedMethodInfos, propDef);
                if (infoExp != null)
                    infoExps.Add(infoExp);
            }

            foreach (var eventDef in Parent.Events)
            {
                var infoExp = EventInfoFromEvent(body, innerTypeCompEnv, sharedMethodInfos, eventDef);
                if (infoExp != null)
                    infoExps.Add(infoExp);
            }

            return new JST.ArrayLiteral(infoExps);
        }
Example #12
0
 private JST.Expression EventInfoFromEvent(Seq<JST.Statement> body, TypeCompilerEnvironment innerTypeCompEnv, Map<CST.MethodSignature, JST.Identifier> sharedMethodInfos, CST.EventDef eventDef)
 {
     var slot = Env.GlobalMapping.ResolveEventDefToSlot(innerTypeCompEnv.Assembly, innerTypeCompEnv.Type, eventDef);
     var slotExp = new JST.StringLiteral(Constants.ObjectEventSlot(slot));
     return JST.Expression.DotCall
         (RootId.ToE(),
          Constants.RootReflectionEventInfo,
          slotExp,
          TypeId.ToE(),
          new JST.BooleanLiteral(eventDef.IsStatic),
          new JST.BooleanLiteral(!eventDef.IsStatic),
          new JST.StringLiteral(eventDef.Name),
          CustomAttributesExpression
              (body, innerTypeCompEnv,
               CST.MessageContextBuilders.Member(Env.Global, innerTypeCompEnv.Assembly, innerTypeCompEnv.Type, eventDef),
               eventDef.CustomAttributes),
          innerTypeCompEnv.ResolveType(eventDef.HandlerType, TypePhase.Constructed),
          eventDef.Add == null || !sharedMethodInfos.ContainsKey(eventDef.Add)
              ? (JST.Expression)new JST.NullExpression()
              : sharedMethodInfos[eventDef.Add].ToE(),
          eventDef.Remove == null || !sharedMethodInfos.ContainsKey(eventDef.Remove)
              ? (JST.Expression)new JST.NullExpression()
              : sharedMethodInfos[eventDef.Remove].ToE());
 }
Example #13
0
 private JST.Expression PropertyInfoFromProperty(Seq<JST.Statement> body, TypeCompilerEnvironment innerTypeCompEnv, Map<CST.MethodSignature, JST.Identifier> sharedMethodInfos, CST.PropertyDef propDef)
 {
     var slot = Env.GlobalMapping.ResolvePropertyDefToSlot(innerTypeCompEnv.Assembly, innerTypeCompEnv.Type, propDef);
     var slotExp = new JST.StringLiteral(Constants.ObjectPropertySlot(slot));
     return JST.Expression.DotCall
         (RootId.ToE(),
          Constants.RootReflectionPropertyInfo,
          slotExp,
          TypeId.ToE(),
          new JST.BooleanLiteral(propDef.IsStatic),
          new JST.BooleanLiteral(!propDef.IsStatic),
          new JST.StringLiteral(propDef.Name),
          CustomAttributesExpression
              (body, innerTypeCompEnv,
               CST.MessageContextBuilders.Member(Env.Global, innerTypeCompEnv.Assembly, innerTypeCompEnv.Type, propDef),
               propDef.CustomAttributes),
          innerTypeCompEnv.ResolveType(propDef.FieldType, TypePhase.Constructed),
          propDef.Get == null || !sharedMethodInfos.ContainsKey(propDef.Get) ? (JST.Expression)new JST.NullExpression() : sharedMethodInfos[propDef.Get].ToE(),
          propDef.Set == null || !sharedMethodInfos.ContainsKey(propDef.Set) ? (JST.Expression)new JST.NullExpression() : sharedMethodInfos[propDef.Set].ToE());
 }
Example #14
0
        private JST.Expression FieldInfoFromField(Seq<JST.Statement> body, TypeCompilerEnvironment innerTypeCompEnv, CST.FieldDef fieldDef)
        {
            if (Env.AttributeHelper.FieldHasAttribute
                (innerTypeCompEnv.Assembly,
                 innerTypeCompEnv.Type,
                 fieldDef,
                 Env.Global.CompilerGeneratedAttributeRef,
                 false,
                 false))
                // Ignore compiler-generate fields
                return null;

            var slot = Env.GlobalMapping.ResolveFieldDefToSlot
                (innerTypeCompEnv.Assembly, innerTypeCompEnv.Type, fieldDef);
            return JST.Expression.DotCall
                (RootId.ToE(),
                 Constants.RootReflectionFieldInfo,
                 new JST.StringLiteral(slot),
                 TypeId.ToE(),
                 new JST.BooleanLiteral(fieldDef.IsStatic),
                 new JST.BooleanLiteral(!fieldDef.IsStatic),
                 new JST.StringLiteral(fieldDef.Name),
                 CustomAttributesExpression
                     (body,
                      innerTypeCompEnv,
                      CST.MessageContextBuilders.Member
                          (Env.Global, innerTypeCompEnv.Assembly, innerTypeCompEnv.Type, fieldDef),
                      fieldDef.CustomAttributes),
                 innerTypeCompEnv.ResolveType(fieldDef.FieldType, TypePhase.Constructed),
                 new JST.NullExpression());
        }
Example #15
0
        private JST.Expression MethodInfoFromMethod(Seq<JST.Statement> body, TypeCompilerEnvironment innerTypeCompEnv, CST.MethodDef methodDef)
        {
            if (methodDef.TypeArity > 0)
                // TODO: polymorphic methods
                return null;

            if (methodDef.Invalid != null || !methodDef.IsUsed ||
                Env.InlinedMethods.IsInlinable(innerTypeCompEnv.Assembly, innerTypeCompEnv.Type, methodDef))
                // This is possible if method is a getter/setter/adder/removed for a used property
                // or event but the method itself is unused or inlined.
                return null;

            if (methodDef.IsOverriding)
                // MethodInfo will have been supplied by supertype
                return null;

            var slot = Env.GlobalMapping.ResolveMethodDefToSlot(innerTypeCompEnv.Assembly, innerTypeCompEnv.Type, methodDef);
            var attrs = CustomAttributesExpression
                (body,
                 innerTypeCompEnv,
                 CST.MessageContextBuilders.Member
                     (Env.Global, innerTypeCompEnv.Assembly, innerTypeCompEnv.Type, methodDef),
                 methodDef.CustomAttributes);
            var paramTypes = new JST.ArrayLiteral
                (methodDef.ValueParameters.Skip(methodDef.IsStatic ? 0 : 1).Select
                     (p => innerTypeCompEnv.ResolveType(p.Type, TypePhase.Constructed)).ToSeq());
            if (methodDef.IsConstructor)
                return JST.Expression.DotCall
                    (RootId.ToE(),
                     Constants.RootReflectionConstructorInfo,
                     new JST.StringLiteral(slot),
                     TypeId.ToE(),
                     new JST.BooleanLiteral(!methodDef.IsStatic),
                     attrs,
                     paramTypes);
            else
                return JST.Expression.DotCall
                    (RootId.ToE(),
                     Constants.RootReflectionMethodInfo,
                     new JST.StringLiteral(slot),
                     TypeId.ToE(),
                     new JST.BooleanLiteral(methodDef.IsStatic),
                     new JST.BooleanLiteral(!methodDef.IsStatic),
                     new JST.StringLiteral(methodDef.Name),
                     attrs,
                     new JST.BooleanLiteral(methodDef.IsVirtualOrAbstract),
                     paramTypes,
                     new JST.BooleanLiteral(true),
                     methodDef.Result == null
                         ? (JST.Expression)new JST.NullExpression()
                         : innerTypeCompEnv.ResolveType(methodDef.Result.Type, TypePhase.Constructed));
        }
Example #16
0
 private JST.Expression ReflectionNamespaceExpression(Seq<JST.Statement> body, TypeCompilerEnvironment innerTypeCompEnv)
 {
     var nm = innerTypeCompEnv.Type.EffectiveName(Env.Global);
     var lit = nm.Namespace.Length == 0
                   ? (JST.Expression)new JST.NullExpression()
                   : (JST.Expression)new JST.StringLiteral(nm.Namespace);
     if (innerTypeCompEnv.Type.Arity == 0)
         return lit;
     else
     {
         return JST.Expression.DotCall
             (RootId.ToE(),
              Constants.RootReflectionNamespace,
              lit,
              new JST.ArrayLiteral
                  (innerTypeCompEnv.TypeBoundArguments.Select(t => innerTypeCompEnv.ResolveType(t, TypePhase.Id)).ToSeq()));
     }
 }
Example #17
0
        // ----------------------------------------------------------------------
        // Reflection   
        // ----------------------------------------------------------------------

        // The object representing custom attribute
        private JST.Expression CustomAttributeExpression(Seq<JST.Statement> body, TypeCompilerEnvironment innerTypeCompEnv, MessageContext ctxt, CST.CustomAttribute attr)
        {
            if (Env.AttributeHelper.IsSpecialAttribute(attr))
                return null;

            var attrTypeEnv = attr.Type.Enter(innerTypeCompEnv);

            if (attrTypeEnv.Type.Invalid != null || !attrTypeEnv.Type.IsUsed)
            {
                Env.Log
                    (new UnimplementableFeatureMessage
                         (ctxt,
                          "custom attribute",
                          String.Format("Type '{0}' is not marked as [Used] or is invalid", attr.Type)));
                return null;
            }

            var ctorDef =
                attrTypeEnv.Type.Members.OfType<CST.MethodDef>().Where
                    (m =>
                     m.Invalid == null && m.IsUsed && m.IsConstructor && !m.IsStatic &&
                     m.Arity == attr.PositionalProperties.Count + 1).FirstOrDefault();

            if (ctorDef == null)
            {
                Env.Log
                    (new UnimplementableFeatureMessage
                         (ctxt,
                          "custom attribute",
                          String.Format
                              ("Type '{0}' does not have a constructor for {1} positional parameters",
                               attr.Type,
                               attr.PositionalProperties.Count)));
                return null;
            }
            var ctorRef = new CST.MethodRef(attr.Type, ctorDef.MethodSignature, null);

            var args = new Seq<JST.Expression>();
            for (var i = 0; i < attr.PositionalProperties.Count; i++)
            {
                var t = attrTypeEnv.SubstituteType(ctorDef.ValueParameters[i + 1].Type);
                var o = attr.PositionalProperties[i];
                var e = Env.JSTHelpers.InitializerExpression(innerTypeCompEnv, ctxt, o, t);
                args.Add(e);
            }

            var id = innerTypeCompEnv.NameSupply.GenSym();
            body.Add(JST.Statement.Var(id));
            Env.JSTHelpers.ConstructorExpression(innerTypeCompEnv, innerTypeCompEnv.NameSupply, body, id.ToE(), ctorRef, args);

            foreach (var kv in attr.NamedProperties)
            {
                var stmnt = default(JST.Statement);
                foreach (var memberDef in
                    attrTypeEnv.Type.Members.Where
                        (m => !m.IsStatic && m.Name.Equals(kv.Key, StringComparison.Ordinal)))
                {
                    switch (memberDef.Flavor)
                    {
                        case CST.MemberDefFlavor.Field:
                            {
                                var fieldDef = (CST.FieldDef)memberDef;
                                if (fieldDef.Invalid == null && fieldDef.IsUsed)
                                {
                                    var t = attrTypeEnv.SubstituteType(fieldDef.FieldType);
                                    var o = kv.Value;
                                    var e = Env.JSTHelpers.InitializerExpression(innerTypeCompEnv, ctxt, o, t);
                                    var slot = Env.GlobalMapping.ResolveFieldDefToSlot
                                        (attrTypeEnv.Assembly, attrTypeEnv.Type, fieldDef);
                                    stmnt = JST.Statement.DotAssignment
                                        (id.ToE(), new JST.Identifier(Constants.ObjectInstanceFieldSlot(slot)), e);
                                }
                                break;
                            }
                        case CST.MemberDefFlavor.Property:
                            {
                                var propDef = (CST.PropertyDef)memberDef;
                                if (propDef.Invalid == null)
                                {
                                    var t = attrTypeEnv.SubstituteType(propDef.FieldType);
                                    var o = kv.Value;
                                    var e = Env.JSTHelpers.InitializerExpression(innerTypeCompEnv, ctxt, o, t);
                                    if (propDef.Set != null)
                                    {
                                        var setMethodDef = attrTypeEnv.Type.ResolveMethod(propDef.Set);
                                        if (setMethodDef != null && setMethodDef.Invalid == null && setMethodDef.IsUsed &&
                                            setMethodDef.Arity == 2 && !Env.InlinedMethods.IsInlinable(innerTypeCompEnv.Assembly, innerTypeCompEnv.Type, setMethodDef))
                                        {
                                            var setMethodRef = new CST.MethodRef
                                                (attr.Type, setMethodDef.MethodSignature, null);
                                            stmnt = new JST.ExpressionStatement
                                                (innerTypeCompEnv.MethodCallExpression
                                                     (setMethodRef,
                                                      innerTypeCompEnv.NameSupply,
                                                      false,
                                                      new Seq<JST.Expression>(id.ToE(), e)));
                                        }
                                    }
                                }
                                break;
                            }
                        case CST.MemberDefFlavor.Method:
                        case CST.MemberDefFlavor.Event:
                            break;
                        default:
                            throw new ArgumentOutOfRangeException();
                    }
                }
                if (stmnt == null)
                {
                    Env.Log
                        (new UnimplementableFeatureMessage
                             (ctxt,
                              "custom attribute",
                              String.Format
                                  ("Type '{0}' does not have a field or set-able property for named parameter '{1}'",
                                   kv.Key)));
                }
                else
                    body.Add(stmnt);
            }

            return id.ToE();
        }