Exemple #1
0
        // ----------------------------------------------------------------------
        // Methods
        // ----------------------------------------------------------------------

        public JST.Expression MethodCallExpression(CST.MethodRef methodRef, JST.NameSupply localNameSupply, bool isFactory, IImSeq <JST.Expression> arguments)
        {
            var groundMethodRef = SubstituteMember(methodRef);

            if (Method.IsStatic && groundMethodRef.Equals(MethodRef))
            {
                var args =
                    TypeBoundTypeParameterIds.Select(id => id.ToE()).Concat
                        (MethodBoundTypeParameterIds.Select(id => id.ToE())).Concat(arguments).ToSeq();
                return(new JST.CallExpression(MethodId.ToE(), args));
            }
            else
            {
                return(env.JSTHelpers.DefaultMethodCallExpression
                           (this, localNameSupply, groundMethodRef, isFactory, arguments));
            }
        }
        // Collect and filter members for subsequent code gen
        private void CollectMembers()
        {
            var fields = new Seq<CST.FieldDef>();
            var events = new Seq<CST.EventDef>();
            var properties = new Seq<CST.PropertyDef>();
            var methods = new Seq<CST.MethodDef>();
            var exportedInstanceMethods = new Seq<CST.MethodDef>();
            StaticInitializer = null;
            DefaultConstructor = null;
            numRelevantMethods = 0;

            foreach (var fieldDef in TyconEnv.Type.Members.OfType<CST.FieldDef>().Where(d => d.Invalid == null))
            {
                if (fieldDef.IsUsed)
                    fields.Add(fieldDef);
                else if (TypeTrace == null || TypeTrace.IncludeType)
                    Env.Log
                        (new UnusedDefinitionMessage
                             (CST.MessageContextBuilders.Member
                                  (Env.Global, TyconEnv.Assembly, TyconEnv.Type, fieldDef)));
            }

            foreach (var eventDef in TyconEnv.Type.Members.OfType<CST.EventDef>().Where(d => d.Invalid == null))
            {
                if (eventDef.IsUsed)
                    events.Add(eventDef);
                else if (TypeTrace == null || TypeTrace.IncludeType)
                    Env.Log
                        (new UnusedDefinitionMessage
                             (CST.MessageContextBuilders.Member
                                  (Env.Global, TyconEnv.Assembly, TyconEnv.Type, eventDef)));
            }

            foreach (var propDef in TyconEnv.Type.Members.OfType<CST.PropertyDef>().Where(d => d.Invalid == null))
            {
                if (propDef.IsUsed)
                    properties.Add(propDef);
                else if (TypeTrace == null || TypeTrace.IncludeType)
                    Env.Log
                        (new UnusedDefinitionMessage
                             (CST.MessageContextBuilders.Member
                                  (Env.Global, TyconEnv.Assembly, TyconEnv.Type, propDef)));
            }

            var state = Env.InteropManager.GetTypeRepresentation(TyconEnv.Assembly, TyconEnv.Type).State;

            var s = TyconEnv.Type.Style;
            if (!(s is CST.InterfaceTypeStyle || s is CST.DelegateTypeStyle))
            {
                foreach (
                    var methodDef in
                        TyconEnv.Type.Members.OfType<CST.MethodDef>().Where(d => d.Invalid == null && !d.IsAbstract))
                {
                    if (!methodDef.IsUsed)
                    {
                        if (TypeTrace == null || TypeTrace.IncludeType)
                            Env.Log
                                (new UnusedDefinitionMessage
                                     (CST.MessageContextBuilders.Member
                                          (Env.Global, TyconEnv.Assembly, TyconEnv.Type, methodDef)));
                    }
                    else if (!Env.Validity.IsMustHaveADefinition(methodDef.QualifiedMemberName(Env.Global, TyconEnv.Assembly, TyconEnv.Type)) &&
                             (Env.InteropManager.IsInlinable(TyconEnv.Assembly, TyconEnv.Type, methodDef, state) ||
                              Env.InlinedMethods.IsInlinable(TyconEnv.Assembly, TyconEnv.Type, methodDef)))
                    {
                        if (TypeTrace == null || TypeTrace.IncludeType)
                            Env.Log
                                (new InlinedDefinitionMessage
                                     (CST.MessageContextBuilders.Member
                                          (Env.Global, TyconEnv.Assembly, TyconEnv.Type, methodDef)));
                    }
                    else if (state != InstanceState.JavaScriptOnly && state != InstanceState.ManagedAndJavaScript &&
                             !methodDef.IsStatic && methodDef.IsConstructor && methodDef.Arity > 1 &&
                             methodDef.ValueParameters[1].Equals(Env.JSContextRef))
                    {
                        // Silently ignore importing constructors unless they are needed.
                        // (Remember, the managed interop rewriter will interpert 'Merged' as
                        // 'JavaScriptOnly', and thus may need importing constructors.)
                    }
                    else
                    {
                        if (methodDef.IsStatic && methodDef.IsConstructor)
                        {
                            if (methodDef.TypeArity > 0)
                                throw new InvalidOperationException
                                    ("static constructors cannot be polymorphic");
                            StaticInitializer = new CST.MethodRef(TyconEnv.AddSelfTypeBoundArguments().TypeRef, methodDef.MethodSignature, null);
                        }
                        else if (!methodDef.IsStatic && methodDef.IsConstructor && methodDef.Arity == 1 &&
                                 !Env.InteropManager.IsFactory(TyconEnv.Assembly, TyconEnv.Type, methodDef))
                        {
                            if (methodDef.TypeArity > 0)
                                throw new InvalidOperationException
                                    ("instance constructors cannot be polymorphic");
                            DefaultConstructor = new CST.MethodRef(TyconEnv.AddSelfTypeBoundArguments().TypeRef, methodDef.MethodSignature, null);
                        }
                        if (Env.InteropManager.IsExported(TyconEnv.Assembly, TyconEnv.Type, methodDef))
                        {
                            if (Env.InteropManager.IsBindToInstance
                                (TyconEnv.Assembly, TyconEnv.Type, methodDef))
                                exportedInstanceMethods.Add(methodDef);
                            // else: will be exported by assembly's Initialize function
                        }

                        methods.Add(methodDef);

                        if (TypeTrace == null || TypeTrace.Methods.Contains(methodDef.MethodSignature))
                            numRelevantMethods++;
                    }
                }
            }
            // else: ignore members of interface and delegate types
            // TODO: Need to emit reflection data for methods of interface types, thus will need
            //       to collect interface methods

            Fields = fields;
            Events = events;
            Properties = properties;
            Methods = methods;
            ExportedInstanceMethods = exportedInstanceMethods;
        }
        // ----------------------------------------------------------------------
        // Methods
        // ----------------------------------------------------------------------

        public JST.Expression MethodCallExpression(CST.MethodRef methodRef, JST.NameSupply localNameSupply, bool isFactory, IImSeq <JST.Expression> arguments)
        {
            return(env.JSTHelpers.DefaultMethodCallExpression(this, localNameSupply, methodRef, isFactory, arguments));
        }
Exemple #4
0
        private void EmitEquals(Seq<JST.Statement> body, JST.Expression lhs)
        {
            var innerNameSupply = NameSupply.Fork();
            var parameters = new Seq<JST.Identifier>();
            parameters.Add(innerNameSupply.GenSym());
            var left = parameters[0].ToE();
            parameters.Add(innerNameSupply.GenSym());
            var right = parameters[1].ToE();
            var innerBody = new Seq<JST.Statement>();

            var iequatableTypeRef = Env.Global.IEquatableTypeConstructorRef.ApplyTo(TypeCompEnv.TypeRef);
            var hasIEquatable = TypeCompEnv.TypeRef.IsAssignableTo(TypeCompEnv, iequatableTypeRef);

            var s = TypeCompEnv.Type.Style;

            if (s is CST.VoidTypeStyle || s is CST.ManagedPointerTypeStyle)
                innerBody.Add
                    (new JST.ThrowStatement
                         (JST.Expression.DotCall(RootId.ToE(), Constants.RootInvalidOperationException)));
            else if (s is CST.NumberTypeStyle || s is CST.EnumTypeStyle || TypeCompEnv.TypeRef.Equals(Env.Global.DecimalRef))
                innerBody.Add(new JST.ReturnStatement(new JST.BinaryExpression(left, JST.BinaryOp.Equals, right)));
            else if (s is CST.HandleTypeStyle)
            {
                innerBody.Add
                    (new JST.IfStatement
                         (JST.Expression.IsNull(left), new JST.Statements(new JST.ReturnStatement(JST.Expression.IsNull(right)))));
                innerBody.Add
                    (new JST.IfStatement
                         (JST.Expression.IsNull(right), new JST.Statements(new JST.ReturnStatement(new JST.BooleanLiteral(false)))));
                innerBody.Add
                    (new JST.ReturnStatement(new JST.BinaryExpression(left, JST.BinaryOp.StrictEquals, right)));
            }
            else if (s is CST.NullableTypeStyle)
            {
                innerBody.Add
                    (new JST.IfStatement
                         (JST.Expression.IsNull(left), new JST.Statements(new JST.ReturnStatement(JST.Expression.IsNull(right)))));
                innerBody.Add
                    (new JST.IfStatement
                         (JST.Expression.IsNull(right), new JST.Statements(new JST.ReturnStatement(new JST.BooleanLiteral(false)))));
                innerBody.Add
                    (new JST.ReturnStatement
                         (JST.Expression.DotCall
                              (TypeCompEnv.ResolveType(TypeCompEnv.TypeBoundArguments[0], TypePhase.Slots),
                               Constants.TypeEquals,
                               left,
                               right)));
            }
            else if (s is CST.StructTypeStyle)
            {
                if (hasIEquatable)
                {
                    // Defer to IEquatable<T>::Equals
                    var paramTypeRef = new CST.ParameterTypeRef(CST.ParameterFlavor.Type, 0);
                    var equalsRef = new CST.MethodRef
                        (iequatableTypeRef,
                         "Equals",
                         false,
                         null,
                         new Seq<CST.TypeRef> { paramTypeRef, paramTypeRef },
                         Env.Global.BooleanRef);
                    var leftPtr = JST.Expression.DotCall
                        (RootId.ToE(), Constants.RootNewPointerToValue, left, lhs);
                    var call = Env.JSTHelpers.DefaultVirtualMethodCallExpression
                        (TypeCompEnv,
                         innerNameSupply,
                         innerBody,
                         equalsRef,
                         new Seq<JST.Expression> { leftPtr, right });
                    innerBody.Add(new JST.ReturnStatement(call));
                }
                else
                {
                    foreach (var fieldDef in Parent.Fields.Where(f => !f.IsStatic))
                    {
                        var fieldRef = new CST.FieldRef(TypeCompEnv.TypeRef, fieldDef.FieldSignature);
                        var leftField = Env.JSTHelpers.ResolveInstanceField(TypeCompEnv, left, fieldRef);
                        var rightField = Env.JSTHelpers.ResolveInstanceField(TypeCompEnv, right, fieldRef);
                        innerBody.Add
                            (new JST.IfStatement
                                 (JST.Expression.Not
                                      (JST.Expression.DotCall
                                           (TypeCompEnv.ResolveType(fieldDef.FieldType, TypePhase.Slots),
                                            Constants.TypeEquals,
                                            leftField,
                                            rightField)),
                                  new JST.Statements(new JST.ReturnStatement(new JST.BooleanLiteral(false)))));
                    }
                    innerBody.Add(new JST.ReturnStatement(new JST.BooleanLiteral(true)));
                }
            }
            else if (s is CST.ObjectTypeStyle || (s is CST.ClassTypeStyle & hasIEquatable))
            {
                innerBody.Add
                    (new JST.IfStatement
                         (JST.Expression.IsNull(left), new JST.Statements(new JST.ReturnStatement(JST.Expression.IsNull(right)))));
                innerBody.Add
                    (new JST.IfStatement
                         (JST.Expression.IsNull(right), new JST.Statements(new JST.ReturnStatement(new JST.BooleanLiteral(false)))));
                var equalsRef = default(CST.MethodRef);
                if (hasIEquatable)
                {
                    // Defer to IEquatable<T>::Equals
                    var paramTypeRef = new CST.ParameterTypeRef(CST.ParameterFlavor.Type, 0);
                    var iequatableSelfTypeRef = Env.Global.IEquatableTypeConstructorRef.ApplyTo(paramTypeRef);
                    equalsRef = new CST.MethodRef
                        (iequatableTypeRef,
                         "Equals",
                         false,
                         null,
                         new Seq<CST.TypeRef> { iequatableSelfTypeRef, paramTypeRef },
                         Env.Global.BooleanRef);
                }
                else
                {
                    // Defer to Object::Equals virtual
                    equalsRef = new CST.MethodRef
                        (Env.Global.ObjectRef,
                         "Equals",
                         false,
                         null,
                         new Seq<CST.TypeRef> { Env.Global.ObjectRef, Env.Global.ObjectRef },
                         Env.Global.BooleanRef);
                }
                var call = Env.JSTHelpers.DefaultVirtualMethodCallExpression
                    (TypeCompEnv, innerNameSupply, innerBody, equalsRef, new Seq<JST.Expression> { left, right });
                innerBody.Add(new JST.ReturnStatement(call));
            }
            else
                // default is ok
                return;

            body.Add
                (JST.Statement.DotAssignment
                     (lhs, Constants.TypeEquals, new JST.FunctionExpression(parameters, new JST.Statements(innerBody))));
        }
Exemple #5
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();
        }
Exemple #6
0
        private void EmitHash(Seq<JST.Statement> body, JST.Expression lhs)
        {
            var innerNameSupply = NameSupply.Fork();
            var parameters = new Seq<JST.Identifier>();
            parameters.Add(innerNameSupply.GenSym());
            var obj = parameters[0].ToE();
            var innerBody = new Seq<JST.Statement>();

            var s = TypeCompEnv.Type.Style;

            if (s is CST.VoidTypeStyle || s is CST.ManagedPointerTypeStyle)
                innerBody.Add
                    (new JST.ThrowStatement
                         (JST.Expression.DotCall(RootId.ToE(), Constants.RootInvalidOperationException)));
            else if (s is CST.NumberTypeStyle || s is CST.EnumTypeStyle || TypeCompEnv.TypeRef.Equals(Env.Global.DecimalRef))
                innerBody.Add(new JST.ReturnStatement(obj));
            else if (s is CST.HandleTypeStyle)
            {
                innerBody.Add
                    (new JST.IfStatement
                         (JST.Expression.IsNull(obj), new JST.Statements(new JST.ReturnStatement(new JST.NumericLiteral(0)))));
                var objid = JST.Expression.Dot(obj, Constants.ObjectId);
                innerBody.Add
                    (new JST.IfStatement
                         (JST.Expression.IsNull(objid),
                          new JST.Statements(JST.Statement.Assignment
                              (objid,
                               new JST.UnaryExpression
                                   (JST.Expression.Dot(RootId.ToE(), Constants.RootNextObjectId),
                                    JST.UnaryOp.PostIncrement)))));
                innerBody.Add(new JST.ReturnStatement(objid));
            }
            else if (s is CST.NullableTypeStyle)
            {
                innerBody.Add
                    (new JST.IfStatement
                         (JST.Expression.IsNull(obj), new JST.Statements(new JST.ReturnStatement(new JST.NumericLiteral(0)))));
                innerBody.Add
                    (new JST.ReturnStatement
                         (JST.Expression.DotCall
                              (TypeCompEnv.ResolveType(TypeCompEnv.TypeBoundArguments[0], TypePhase.Slots),
                               Constants.TypeHash,
                               obj)));
            }
            else if (s is CST.StructTypeStyle)
            {
                var hashId = innerNameSupply.GenSym();
                innerBody.Add(JST.Statement.Var(hashId, new JST.NumericLiteral(0)));
                var hash = hashId.ToE();
                foreach (var fieldDef in Parent.Fields.Where(f => !f.IsStatic))
                {
                    innerBody.Add
                        (JST.Statement.Assignment
                             (hash,
                              new JST.BinaryExpression
                                  (new JST.BinaryExpression(hash, JST.BinaryOp.LeftShift, new JST.NumericLiteral(3)),
                                   JST.BinaryOp.BitwiseOR,
                                   new JST.BinaryExpression
                                       (hash, JST.BinaryOp.UnsignedRightShift, new JST.NumericLiteral(28)))));
                    var fieldRef = new CST.FieldRef(TypeCompEnv.TypeRef, fieldDef.FieldSignature);
                    var field = Env.JSTHelpers.ResolveInstanceField(TypeCompEnv, obj, fieldRef);
                    innerBody.Add
                        (JST.Statement.Assignment
                             (hash,
                              new JST.BinaryExpression
                                  (hash,
                                   JST.BinaryOp.BitwiseXOR,
                                   JST.Expression.DotCall
                                       (TypeCompEnv.ResolveType(fieldDef.FieldType, TypePhase.Slots),
                                        Constants.TypeHash,
                                        field))));
                }
                innerBody.Add(new JST.ReturnStatement(hash));
            }
            else if (s is CST.ObjectTypeStyle)
            {
                // NOTE: CLR Bizzarism: IEquatable<T> does not provide a GetHashCode, thus a
                //       default EqualityComparer<T> when T has IEquatable<T> will use the IEquatable
                //       Equals but the Object GetHashCode. Go figure.
                innerBody.Add
                    (new JST.IfStatement
                         (JST.Expression.IsNull(obj), new JST.Statements(new JST.ReturnStatement(new JST.NumericLiteral(0)))));
                var getHashCodeRef = new CST.MethodRef
                    (Env.Global.ObjectRef,
                     "GetHashCode",
                     false,
                     null,
                     new Seq<CST.TypeRef> { Env.Global.ObjectRef },
                     Env.Global.Int32Ref);
                var call = Env.JSTHelpers.DefaultVirtualMethodCallExpression
                    (TypeCompEnv, innerNameSupply, innerBody, getHashCodeRef, new Seq<JST.Expression> { obj });
                innerBody.Add(new JST.ReturnStatement(call));
            }
            else
                // Default is ok
                return;

            body.Add
                (JST.Statement.DotAssignment
                     (lhs, Constants.TypeHash, new JST.FunctionExpression(parameters, new JST.Statements(innerBody))));
        }
Exemple #7
0
        // Collect and filter members for subsequent code gen
        private void CollectMembers()
        {
            var fields     = new Seq <CST.FieldDef>();
            var events     = new Seq <CST.EventDef>();
            var properties = new Seq <CST.PropertyDef>();
            var methods    = new Seq <CST.MethodDef>();
            var exportedInstanceMethods = new Seq <CST.MethodDef>();

            StaticInitializer  = null;
            DefaultConstructor = null;
            numRelevantMethods = 0;

            foreach (var fieldDef in TyconEnv.Type.Members.OfType <CST.FieldDef>().Where(d => d.Invalid == null))
            {
                if (fieldDef.IsUsed)
                {
                    fields.Add(fieldDef);
                }
                else if (TypeTrace == null || TypeTrace.IncludeType)
                {
                    Env.Log
                        (new UnusedDefinitionMessage
                            (CST.MessageContextBuilders.Member
                                (Env.Global, TyconEnv.Assembly, TyconEnv.Type, fieldDef)));
                }
            }

            foreach (var eventDef in TyconEnv.Type.Members.OfType <CST.EventDef>().Where(d => d.Invalid == null))
            {
                if (eventDef.IsUsed)
                {
                    events.Add(eventDef);
                }
                else if (TypeTrace == null || TypeTrace.IncludeType)
                {
                    Env.Log
                        (new UnusedDefinitionMessage
                            (CST.MessageContextBuilders.Member
                                (Env.Global, TyconEnv.Assembly, TyconEnv.Type, eventDef)));
                }
            }

            foreach (var propDef in TyconEnv.Type.Members.OfType <CST.PropertyDef>().Where(d => d.Invalid == null))
            {
                if (propDef.IsUsed)
                {
                    properties.Add(propDef);
                }
                else if (TypeTrace == null || TypeTrace.IncludeType)
                {
                    Env.Log
                        (new UnusedDefinitionMessage
                            (CST.MessageContextBuilders.Member
                                (Env.Global, TyconEnv.Assembly, TyconEnv.Type, propDef)));
                }
            }

            var state = Env.InteropManager.GetTypeRepresentation(TyconEnv.Assembly, TyconEnv.Type).State;

            var s = TyconEnv.Type.Style;

            if (!(s is CST.InterfaceTypeStyle || s is CST.DelegateTypeStyle))
            {
                foreach (
                    var methodDef in
                    TyconEnv.Type.Members.OfType <CST.MethodDef>().Where(d => d.Invalid == null && !d.IsAbstract))
                {
                    if (!methodDef.IsUsed)
                    {
                        if (TypeTrace == null || TypeTrace.IncludeType)
                        {
                            Env.Log
                                (new UnusedDefinitionMessage
                                    (CST.MessageContextBuilders.Member
                                        (Env.Global, TyconEnv.Assembly, TyconEnv.Type, methodDef)));
                        }
                    }
                    else if (!Env.Validity.IsMustHaveADefinition(methodDef.QualifiedMemberName(Env.Global, TyconEnv.Assembly, TyconEnv.Type)) &&
                             (Env.InteropManager.IsInlinable(TyconEnv.Assembly, TyconEnv.Type, methodDef, state) ||
                              Env.InlinedMethods.IsInlinable(TyconEnv.Assembly, TyconEnv.Type, methodDef)))
                    {
                        if (TypeTrace == null || TypeTrace.IncludeType)
                        {
                            Env.Log
                                (new InlinedDefinitionMessage
                                    (CST.MessageContextBuilders.Member
                                        (Env.Global, TyconEnv.Assembly, TyconEnv.Type, methodDef)));
                        }
                    }
                    else if (state != InstanceState.JavaScriptOnly && state != InstanceState.ManagedAndJavaScript &&
                             !methodDef.IsStatic && methodDef.IsConstructor && methodDef.Arity > 1 &&
                             methodDef.ValueParameters[1].Equals(Env.JSContextRef))
                    {
                        // Silently ignore importing constructors unless they are needed.
                        // (Remember, the managed interop rewriter will interpert 'Merged' as
                        // 'JavaScriptOnly', and thus may need importing constructors.)
                    }
                    else
                    {
                        if (methodDef.IsStatic && methodDef.IsConstructor)
                        {
                            if (methodDef.TypeArity > 0)
                            {
                                throw new InvalidOperationException
                                          ("static constructors cannot be polymorphic");
                            }
                            StaticInitializer = new CST.MethodRef(TyconEnv.AddSelfTypeBoundArguments().TypeRef, methodDef.MethodSignature, null);
                        }
                        else if (!methodDef.IsStatic && methodDef.IsConstructor && methodDef.Arity == 1 &&
                                 !Env.InteropManager.IsFactory(TyconEnv.Assembly, TyconEnv.Type, methodDef))
                        {
                            if (methodDef.TypeArity > 0)
                            {
                                throw new InvalidOperationException
                                          ("instance constructors cannot be polymorphic");
                            }
                            DefaultConstructor = new CST.MethodRef(TyconEnv.AddSelfTypeBoundArguments().TypeRef, methodDef.MethodSignature, null);
                        }
                        if (Env.InteropManager.IsExported(TyconEnv.Assembly, TyconEnv.Type, methodDef))
                        {
                            if (Env.InteropManager.IsBindToInstance
                                    (TyconEnv.Assembly, TyconEnv.Type, methodDef))
                            {
                                exportedInstanceMethods.Add(methodDef);
                            }
                            // else: will be exported by assembly's Initialize function
                        }

                        methods.Add(methodDef);

                        if (TypeTrace == null || TypeTrace.Methods.Contains(methodDef.MethodSignature))
                        {
                            numRelevantMethods++;
                        }
                    }
                }
            }
            // else: ignore members of interface and delegate types
            // TODO: Need to emit reflection data for methods of interface types, thus will need
            //       to collect interface methods

            Fields     = fields;
            Events     = events;
            Properties = properties;
            Methods    = methods;
            ExportedInstanceMethods = exportedInstanceMethods;
        }
Exemple #8
0
        public JST.Expression VirtualMethodCallExpression(CST.MethodRef methodRef, ISeq <JST.Statement> optBody, IImSeq <JST.Expression> arguments)
        {
            var groundMethodRef = SubstituteMember(methodRef);

            return(env.JSTHelpers.DefaultVirtualMethodCallExpression(this, NameSupply, optBody, groundMethodRef, arguments));
        }
Exemple #9
0
 public JST.Expression MethodCallExpression(CST.MethodRef methodRef, JST.NameSupply localNameSupply, bool isFactory, params JST.Expression[] arguments)
 {
     return(MethodCallExpression(methodRef, localNameSupply, isFactory, new Seq <JST.Expression>(arguments)));
 }