コード例 #1
0
        /// <summary>
        /// Get the return type of the constructor (never null).
        /// </summary>
        public static TypeRefBase GetReturnType(TypeRefBase thisRef, object reference)
        {
            // The 'return type' of a constructor is its declaring type, along with any type parameters
            TypeRefBase typeRefBase;

            if (reference is ConstructorDecl)
            {
                ConstructorDecl constructorDecl = (ConstructorDecl)reference;
                CodeObject      parent          = constructorDecl.Parent;
                if (parent == null)
                {
                    // If we don't have a parent, assume we're a generated constructor for
                    // a delegate (used for the obsolete explicit delegate creation syntax), and
                    // use the type of the parameter as our type.
                    // Clone the type so we can evaluate any type arguments it has later without consequences.
                    typeRefBase = constructorDecl.Parameters[0].Type.SkipPrefixes() as TypeRefBase;
                    typeRefBase = (typeRefBase != null ? (TypeRefBase)typeRefBase.Clone() : TypeRef.VoidRef);
                }
                else
                {
                    typeRefBase = (TypeRef)parent.CreateRef();
                }
            }
            else //if (reference is ConstructorInfo)
            {
                typeRefBase = TypeRef.Create(((ConstructorInfo)reference).DeclaringType);
            }

            return(typeRefBase);
        }
コード例 #2
0
        /// <summary>
        /// Deep-clone the code object.
        /// </summary>
        public override CodeObject Clone()
        {
            ConstructorDecl clone = (ConstructorDecl)base.Clone();

            clone.CloneField(ref clone._initializer, _initializer);
            return(clone);
        }
コード例 #3
0
        /// <summary>
        /// Get the non-static constructor with the specified parameters.
        /// </summary>
        public override ConstructorRef GetConstructor(params TypeRefBase[] parameterTypes)
        {
            ConstructorDecl found = GetMethod <ConstructorDecl>(Name, parameterTypes);

            if (found != null)
            {
                return((ConstructorRef)found.CreateRef());
            }
            return(null);  // Don't look in base types for DelegateDecls
        }
コード例 #4
0
        /// <summary>
        /// Get the non-static constructor with the specified parameters.
        /// </summary>
        public virtual ConstructorRef GetConstructor(params TypeRefBase[] parameterTypes)
        {
            ConstructorDecl found = GetMethod <ConstructorDecl>(_name, parameterTypes);

            if (found != null)
            {
                return((ConstructorRef)found.CreateRef());
            }
            TypeRef baseRef = GetBaseType();

            return(baseRef != null ? baseRef.GetConstructor(parameterTypes) : null);
        }
コード例 #5
0
 /// <summary>
 /// Check if we need to remove a compiler-generated default constructor when adding a constructor.
 /// </summary>
 protected void CheckRemoveGeneratedDefaultConstructor(ConstructorDecl constructorDecl)
 {
     // If we're adding a non-static constructor, we need to remove any generated ones
     if (!constructorDecl.IsStatic)
     {
         NamedCodeObjectGroup constructors = GetConstructors();
         if (constructors != null && constructors.Count > 0)
         {
             foreach (ConstructorDecl constructor in constructors)
             {
                 if (constructor.IsGenerated && constructor.ParameterCount == 0)
                 {
                     // Remove via its parent in case it belongs to another part of a partial type
                     ((BlockStatement)constructor.Parent).Body.Remove(constructor);
                 }
             }
         }
     }
 }
コード例 #6
0
        /// <summary>
        /// Get the declaring type of the referenced constructor.
        /// </summary>
        public override TypeRefBase GetDeclaringType()
        {
            // Do a special check for a generated constructor for an external delegate type (see TypeRef.GetConstructors())
            ConstructorDecl constructorDecl = _reference as ConstructorDecl;

            if (constructorDecl != null && constructorDecl.Parent == null && constructorDecl.IsGenerated)
            {
                ChildList <ParameterDecl> parameters = constructorDecl.Parameters;
                if (parameters.Count == 1)
                {
                    ParameterDecl parameterDecl = parameters[0];
                    if (parameterDecl.Name == DelegateDecl.DelegateConstructorParameterName)
                    {
                        return(parameterDecl.Type as TypeRef);
                    }
                }
            }
            return(base.GetDeclaringType());
        }
コード例 #7
0
 /// <summary>
 /// Create a <see cref="BaseInitializer"/> operator.
 /// </summary>
 public BaseInitializer(ConstructorDecl constructorDecl, params Expression[] parameters)
     : base(constructorDecl, parameters)
 {
 }
コード例 #8
0
        /// <summary>
        /// Check if we need to create or remove a compiler-generated default constructor.
        /// </summary>
        public void CheckGeneratedDefaultConstructor(bool currentPartOnly)
        {
            NamedCodeObjectGroup constructors = GetConstructors();

            // Add or remove compiler-generated default constructors as necessary
            if (constructors == null || constructors.Count == 0)
            {
                // Add a compiler-generated default public constructor if we don't have any constructors yet,
                // and this isn't a static class.
                if (!IsStatic)
                {
                    base.Add(new ConstructorDecl(Modifiers.Public)
                    {
                        IsGenerated = true, IsSingleLine = true
                    });
                }
            }
            else if (constructors.Count > 1)
            {
                // Remove any duplicate compiler-generated default constructors (can occur for partial types during multithreaded
                // parsing), and if we have any other non-static constructors, then remove all default constructors.
                bool            removeAllDefaults  = false;
                ConstructorDecl defaultConstructor = null;
                foreach (ConstructorDecl constructor in constructors)
                {
                    ConstructorDecl removeConstructor = null;
                    if (constructor.IsGenerated && constructor.ParameterCount == 0)
                    {
                        if (removeAllDefaults)
                        {
                            removeConstructor = constructor;
                        }
                        else if (defaultConstructor != null)
                        {
                            if (constructor.Parent == this)
                            {
                                removeConstructor = constructor;
                            }
                            else
                            {
                                removeConstructor  = defaultConstructor;
                                defaultConstructor = constructor;
                            }
                        }
                        else
                        {
                            defaultConstructor = constructor;
                        }
                    }
                    else if (!constructor.IsStatic)
                    {
                        removeAllDefaults = true;
                        if (defaultConstructor != null)
                        {
                            removeConstructor = defaultConstructor;
                        }
                    }
                    if (removeConstructor != null)
                    {
                        // Don't remove if we're doing the current part only and it belongs to another part
                        if (!currentPartOnly || removeConstructor.Parent == this)
                        {
                            // Remove via its parent in case it belongs to another part of a partial type
                            ((BlockStatement)removeConstructor.Parent).Body.Remove(removeConstructor);
                        }
                    }
                }
            }
        }
コード例 #9
0
 /// <summary>
 /// Create a <see cref="ConstructorRef"/> from a <see cref="ConstructorDecl"/>.
 /// </summary>
 public ConstructorRef(ConstructorDecl constructorDecl)
     : base(constructorDecl, false)
 {
 }
コード例 #10
0
 /// <summary>
 /// Create a <see cref="ConstructorRef"/> from a <see cref="ConstructorDecl"/>.
 /// </summary>
 public ConstructorRef(ConstructorDecl constructorDecl, bool isFirstOnLine)
     : base(constructorDecl, isFirstOnLine)
 {
 }
コード例 #11
0
 protected ConstructorInitializer(ConstructorDecl constructorDecl, params Expression[] parameters)
     : base(constructorDecl.CreateRef(), parameters)
 {
 }
コード例 #12
0
        /// <summary>
        /// Create (or re-create) the compiler-generated invoke methods and constructor.
        /// This method should be called whenever the parameters of the delegate are set or changed.
        /// </summary>
        public void GenerateMethods()
        {
            // Remove any existing methods before generating them - since the Body is compiler-generated just
            // to hold these methods, we can just re-create it.
            Body = new Block {
                IsGenerated = true
            };

            // The Invoke method has the same parameters as the delegate, and the same return type
            MethodDecl invokeDecl = new MethodDecl("Invoke", (Expression)_returnType.Clone(), Modifiers.Public)
            {
                IsGenerated = true
            };

            invokeDecl.Parameters = (_parameters != null ? ChildListHelpers.Clone(_parameters, invokeDecl) : null);
            Add(invokeDecl);

            // The BeginInvoke method has the same parameters as the delegate, plus 2 extra ones, and a return type of IAsyncResult
            MethodDecl beginInvokeDecl = new MethodDecl("BeginInvoke", (TypeRef)TypeRef.IAsyncResultRef.Clone(), Modifiers.Public)
            {
                IsGenerated = true
            };
            ChildList <ParameterDecl> parameters = (_parameters != null ? ChildListHelpers.Clone(_parameters, beginInvokeDecl) : new ChildList <ParameterDecl>(beginInvokeDecl));

            parameters.Add(new ParameterDecl("callback", (TypeRef)TypeRef.AsyncCallbackRef.Clone()));
            parameters.Add(new ParameterDecl("object", (TypeRef)TypeRef.ObjectRef.Clone()));
            beginInvokeDecl.Parameters = parameters;
            Add(beginInvokeDecl);

            // The EndInvoke method has any 'ref' or 'out' parameters of the delegate, plus 1 extra one, and the same return type
            MethodDecl endInvokeDecl = new MethodDecl("EndInvoke", (Expression)_returnType.Clone(), Modifiers.Public)
            {
                IsGenerated = true
            };

            parameters = new ChildList <ParameterDecl>(endInvokeDecl);
            if (_parameters != null)
            {
                foreach (ParameterDecl parameterDecl in _parameters)
                {
                    if (parameterDecl.IsRef || parameterDecl.IsOut)
                    {
                        parameters.Add((ParameterDecl)parameterDecl.Clone());
                    }
                }
            }
            parameters.Add(new ParameterDecl("result", (TypeRef)TypeRef.IAsyncResultRef.Clone()));
            endInvokeDecl.Parameters = parameters;
            Add(endInvokeDecl);

            // Delegates have a constructor that takes an object and an IntPtr that is used internally by the compiler during
            // code generation.  We have to create a dummy constructor that will allow a MethodRef to be passed to it, in order
            // to make the C# syntax work when resolving.
            TypeRef         delegateTypeRef = CreateRef();
            ConstructorDecl constructor     = new ConstructorDecl(new[] { new ParameterDecl(DelegateConstructorParameterName, delegateTypeRef) })
            {
                IsGenerated = true
            };

            Add(constructor);
        }
コード例 #13
0
 /// <summary>
 /// Create a <see cref="NewObject"/>.
 /// </summary>
 /// <param name="constructorDecl">The ConstructorDecl of the object being created.</param>
 /// <param name="parameters">The constructor parameters (if any).</param>
 public NewObject(ConstructorDecl constructorDecl, params Expression[] parameters)
     : base(constructorDecl.DeclaringType.CreateRef(), parameters)
 {
     SetField(ref _constructorRef, constructorDecl.CreateRef(), false);
 }