/// <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); }
/// <summary> /// Deep-clone the code object. /// </summary> public override CodeObject Clone() { ConstructorDecl clone = (ConstructorDecl)base.Clone(); clone.CloneField(ref clone._initializer, _initializer); return(clone); }
/// <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 }
/// <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); }
/// <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); } } } } }
/// <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()); }
/// <summary> /// Create a <see cref="BaseInitializer"/> operator. /// </summary> public BaseInitializer(ConstructorDecl constructorDecl, params Expression[] parameters) : base(constructorDecl, parameters) { }
/// <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); } } } } }
/// <summary> /// Create a <see cref="ConstructorRef"/> from a <see cref="ConstructorDecl"/>. /// </summary> public ConstructorRef(ConstructorDecl constructorDecl) : base(constructorDecl, false) { }
/// <summary> /// Create a <see cref="ConstructorRef"/> from a <see cref="ConstructorDecl"/>. /// </summary> public ConstructorRef(ConstructorDecl constructorDecl, bool isFirstOnLine) : base(constructorDecl, isFirstOnLine) { }
protected ConstructorInitializer(ConstructorDecl constructorDecl, params Expression[] parameters) : base(constructorDecl.CreateRef(), parameters) { }
/// <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); }
/// <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); }