Inheritance: MemberCore
Beispiel #1
0
        PendingImplementation(TypeContainer container, MissingInterfacesInfo[] missing_ifaces, IList<MethodSpec> abstract_methods, int total)
        {
            var type_builder = container.Definition;

            this.container = container;
            pending_implementations = new TypeAndMethods [total];

            int i = 0;
            if (abstract_methods != null) {
                int count = abstract_methods.Count;
                pending_implementations [i].methods = new MethodSpec [count];
                pending_implementations [i].need_proxy = new MethodSpec [count];

                pending_implementations [i].methods = abstract_methods;
                pending_implementations [i].found = new MethodData [count];
                pending_implementations [i].type = type_builder;
                ++i;
            }

            foreach (MissingInterfacesInfo missing in missing_ifaces) {
                var iface = missing.Type;
                var mi = MemberCache.GetInterfaceMembers (iface);

                int count = mi.Count;
                pending_implementations [i].type = iface;
                pending_implementations [i].optional = missing.Optional;
                pending_implementations [i].methods = mi;
                pending_implementations [i].found = new MethodData [count];
                pending_implementations [i].need_proxy = new MethodSpec [count];
                i++;
            }
        }
Beispiel #2
0
 public Class(TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
     : base(parent, name, attrs, MemberKind.Class)
 {
     var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE;
     this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, Location, Report);
     spec = new TypeSpec (Kind, null, this, null, ModFlags);
 }
Beispiel #3
0
		public HoistedStoreyClass (TypeContainer parent, MemberName name, TypeParameter[] tparams, Modifiers mod)
			: base (parent, name, mod | Modifiers.PRIVATE)
		{
			if (tparams != null) {
				type_params = new TypeParameter[tparams.Length];
				var src = new TypeParameterSpec[tparams.Length];
				var dst = new TypeParameterSpec[tparams.Length];

				for (int i = 0; i < type_params.Length; ++i) {
					type_params[i] = tparams[i].CreateHoistedCopy (this, spec);

					src[i] = tparams[i].Type;
					dst[i] = type_params[i].Type;
				}

				// A copy is not enough, inflate any type parameter constraints
				// using a new type parameters
				var inflator = new TypeParameterInflator (this, null, src, dst);
				for (int i = 0; i < type_params.Length; ++i) {
					src[i].InflateConstraints (inflator, dst[i]);
				}

				mutator = new TypeParameterMutator (tparams, type_params);
			}
		}
Beispiel #4
0
		protected CompilerGeneratedContainer (TypeContainer parent, MemberName name, Modifiers mod, MemberKind kind)
			: base (parent, name, null, kind)
		{
			Debug.Assert ((mod & Modifiers.AccessibilityMask) != 0);

			ModFlags = mod | Modifiers.COMPILER_GENERATED | Modifiers.SEALED;
			spec = new TypeSpec (Kind, null, this, null, ModFlags);
		}
Beispiel #5
0
 public Enum(TypeContainer parent, FullNamedExpression type, Modifiers mod_flags, MemberName name, Attributes attrs)
     : base(parent, name, attrs, MemberKind.Enum)
 {
     underlying_type_expr = type;
     var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE;
     ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod_flags, accmods, Location, Report);
     spec = new EnumSpec (null, this, null, null, ModFlags);
 }
Beispiel #6
0
		public TypeContainer (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind)
			: base (parent, name, attrs)
		{
			this.Kind = kind;
			if (name != null)
				this.Basename = name.Basename;

			defined_names = new Dictionary<string, MemberCore> ();
		}
 //
 // Our constructor
 //
 public Iterator(ParametersBlock block, IMethodData method, TypeContainer host, TypeSpec iterator_type, bool is_enumerable)
     : base(block, TypeManager.bool_type, block.StartLocation)
 {
     this.OriginalMethod = method;
     this.OriginalIteratorType = iterator_type;
     this.IsEnumerable = is_enumerable;
     this.Host = host;
     this.type = method.ReturnType;
 }
Beispiel #8
0
        public Delegate(TypeContainer parent, FullNamedExpression type, Modifiers mod_flags, MemberName name, ParametersCompiled param_list,
				 Attributes attrs)
            : base(parent, name, attrs, MemberKind.Delegate)
        {
            this.ReturnType = type;
            ModFlags        = ModifiersExtensions.Check (AllowedModifiers, mod_flags,
                               IsTopLevel ? Modifiers.INTERNAL :
                               Modifiers.PRIVATE, name.Location, Report);
            parameters      = param_list;
            spec = new TypeSpec (Kind, null, this, null, ModFlags | Modifiers.SEALED);
        }
Beispiel #9
0
        //
        // Our constructor
        //
        private Iterator(CompilerContext ctx, IMethodData method, TypeContainer host, TypeSpec iterator_type, bool is_enumerable)
            : base(new ToplevelBlock (ctx, method.Block, ParametersCompiled.EmptyReadOnlyParameters, method.Block.StartLocation),
				TypeManager.bool_type,
				method.Location)
        {
            this.OriginalMethod = method;
            this.OriginalIteratorType = iterator_type;
            this.IsEnumerable = is_enumerable;
            this.Host = host;
            this.type = method.ReturnType;

            IteratorHost = Block.ChangeToIterator (this, method.Block);
        }
Beispiel #10
0
		// TypeContainer

		//
		// Generates xml doc comments (if any), and if required,
		// handle warning report.
		//
		internal static void GenerateTypeDocComment (TypeContainer t,
			DeclSpace ds, Report Report)
		{
			GenerateDocComment (t, ds, Report);

			if (t.DefaultStaticConstructor != null)
				t.DefaultStaticConstructor.GenerateDocComment (t);

			if (t.InstanceConstructors != null)
				foreach (Constructor c in t.InstanceConstructors)
					c.GenerateDocComment (t);

			if (t.Types != null)
				foreach (TypeContainer tc in t.Types)
					tc.GenerateDocComment (t);

			if (t.Delegates != null)
				foreach (Delegate de in t.Delegates)
					de.GenerateDocComment (t);

			if (t.Constants != null)
				foreach (Const c in t.Constants)
					c.GenerateDocComment (t);

			if (t.Fields != null)
				foreach (FieldBase f in t.Fields)
					f.GenerateDocComment (t);

			if (t.Events != null)
				foreach (Event e in t.Events)
					e.GenerateDocComment (t);

			if (t.Indexers != null)
				foreach (Indexer ix in t.Indexers)
					ix.GenerateDocComment (t);

			if (t.Properties != null)
				foreach (Property p in t.Properties)
					p.GenerateDocComment (t);

			if (t.Methods != null)
				foreach (MethodOrOperator m in t.Methods)
					m.GenerateDocComment (t);

			if (t.Operators != null)
				foreach (Operator o in t.Operators)
					o.GenerateDocComment (t);
		}
Beispiel #11
0
        static MissingInterfacesInfo [] GetMissingInterfaces(TypeContainer container)
        {
            //
            // Notice that Interfaces will only return the interfaces that the Type
            // is supposed to implement, not all the interfaces that the type implements.
            //
            var impl = container.Definition.Interfaces;

            if (impl == null || impl.Count == 0)
            {
                return(EmptyMissingInterfacesInfo);
            }

            MissingInterfacesInfo[] ret = new MissingInterfacesInfo[impl.Count];

            for (int i = 0; i < impl.Count; i++)
            {
                ret [i] = new MissingInterfacesInfo(impl [i]);
            }

            // we really should not get here because Object doesnt implement any
            // interfaces. But it could implement something internal, so we have
            // to handle that case.
            if (container.BaseType == null)
            {
                return(ret);
            }

            var base_impls = container.BaseType.Interfaces;

            if (base_impls != null)
            {
                foreach (TypeSpec t in base_impls)
                {
                    for (int i = 0; i < ret.Length; i++)
                    {
                        if (t == ret[i].Type)
                        {
                            ret[i].Optional = true;
                            break;
                        }
                    }
                }
            }

            return(ret);
        }
Beispiel #12
0
		public static void FindDynamicClasses(TypeContainer container, List<Class> classes) 
		{
			foreach (var cont in container.Containers) {
				if (cont is Class) {

					// Is class marked as dynamic?
					var cl = cont as Class;
					if (cl.IsAsDynamicClass && !(cl.BaseType != null && cl.BaseType.IsAsDynamicClass)) {
						classes.Add ((Class)cont);
					}
				}

				// Recursively find more classes
				if (cont.Containers != null)
					FindDynamicClasses(cont, classes);
			}
		}
Beispiel #13
0
        /// <summary>
        ///   This function tells whether one of our base classes implements
        ///   the given method (which turns out, it is valid to have an interface
        ///   implementation in a base
        /// </summary>
        bool BaseImplements(Type iface_type, MethodInfo mi, out MethodInfo base_method)
        {
            MethodSignature ms;

            AParametersCollection param = TypeManager.GetParameterData(mi);

            ms = new MethodSignature(mi.Name, TypeManager.TypeToCoreType(mi.ReturnType), param.Types);
            MemberList list = TypeContainer.FindMembers(
                container.TypeBuilder.BaseType, MemberTypes.Method | MemberTypes.Property,
                BindingFlags.Public | BindingFlags.Instance,
                MethodSignature.method_signature_filter, ms);

            if (list.Count == 0)
            {
                base_method = null;
                return(false);
            }

            if (TypeManager.ImplementsInterface(container.TypeBuilder.BaseType, iface_type))
            {
                base_method = null;
                return(true);
            }

            base_method = (MethodInfo)list [0];

            if (base_method.DeclaringType.IsInterface)
            {
                return(false);
            }

            if (!base_method.IsPublic)
            {
                return(false);
            }

            if (!base_method.IsAbstract && !base_method.IsVirtual)
            {
                // FIXME: We can avoid creating a proxy if base_method can be marked 'final virtual' instead.
                //        However, it's too late now, the MethodBuilder has already been created (see bug 377519)
                DefineProxy(iface_type, base_method, mi, param);
            }

            return(true);
        }
Beispiel #14
0
        static bool CheckType(TypeSpec ret, TypeContainer parent, out TypeSpec original_iterator_type, out bool is_enumerable)
        {
            original_iterator_type = null;
            is_enumerable          = false;

            if (ret.BuiltinType == BuiltinTypeSpec.Type.IEnumerable)
            {
                original_iterator_type = parent.Compiler.BuiltinTypes.Object;
                is_enumerable          = true;
                return(true);
            }
            if (ret.BuiltinType == BuiltinTypeSpec.Type.IEnumerator)
            {
                original_iterator_type = parent.Compiler.BuiltinTypes.Object;
                is_enumerable          = false;
                return(true);
            }

            InflatedTypeSpec inflated = ret as InflatedTypeSpec;

            if (inflated == null)
            {
                return(false);
            }

            var            member_definition = inflated.MemberDefinition;
            PredefinedType ptype             = parent.Module.PredefinedTypes.IEnumerableGeneric;

            if (ptype.Define() && ptype.TypeSpec.MemberDefinition == member_definition)
            {
                original_iterator_type = inflated.TypeArguments[0];
                is_enumerable          = true;
                return(true);
            }

            ptype = parent.Module.PredefinedTypes.IEnumeratorGeneric;
            if (ptype.Define() && ptype.TypeSpec.MemberDefinition == member_definition)
            {
                original_iterator_type = inflated.TypeArguments[0];
                is_enumerable          = false;
                return(true);
            }

            return(false);
        }
Beispiel #15
0
		public void AddTypeContainer (TypeContainer current_container, TypeDefinition tc)
		{
			if (current_container == tc){
				Console.Error.WriteLine ("Internal error: inserting container into itself");
				return;
			}

			if (undo_actions == null)
				undo_actions = new List<Action> ();

			var existing = current_container.Containers.FirstOrDefault (l => l.Basename == tc.Basename);
			if (existing != null) {
				current_container.RemoveContainer (existing);
				undo_actions.Add (() => current_container.AddTypeContainer (existing));
			}

			undo_actions.Add (() => current_container.RemoveContainer (tc));
		}
        //
        // Factory method: if there are pending implementation methods, we return a PendingImplementation
        // object, otherwise we return null.
        //
        // Register method implementations are either abstract methods
        // flagged as such on the base class or interface methods
        //
        static public PendingImplementation GetPendingImplementations(TypeContainer container)
        {
            TypeSpec b = container.BaseType;

            var missing_interfaces = GetMissingInterfaces(container);

            //
            // If we are implementing an abstract class, and we are not
            // ourselves abstract, and there are abstract methods (C# allows
            // abstract classes that have no abstract methods), then allocate
            // one slot.
            //
            // We also pre-compute the methods.
            //
            bool implementing_abstract = ((b != null) && b.IsAbstract && (container.ModFlags & Modifiers.ABSTRACT) == 0);

            MethodSpec[] abstract_methods = null;

            if (implementing_abstract)
            {
                var am = MemberCache.GetNotImplementedAbstractMethods(b);

                if (am == null)
                {
                    implementing_abstract = false;
                }
                else
                {
                    abstract_methods = new MethodSpec[am.Count];
                    am.CopyTo(abstract_methods, 0);
                }
            }

            int total = missing_interfaces.Length + (implementing_abstract ? 1 : 0);

            if (total == 0)
            {
                return(null);
            }

            return(new PendingImplementation(container, missing_interfaces, abstract_methods, total));
        }
Beispiel #17
0
        //
        // Fixes full type name of each documented types/members up.
        //
        public void GenerateDocComment(Report r)
        {
            TypeContainer root = RootContext.ToplevelTypes;

            if (root.Types != null)
            {
                foreach (TypeContainer tc in root.Types)
                {
                    DocUtil.GenerateTypeDocComment(tc, null, r);
                }
            }

            if (root.Delegates != null)
            {
                foreach (Delegate d in root.Delegates)
                {
                    DocUtil.GenerateDocComment(d, null, r);
                }
            }
        }
Beispiel #18
0
        public NamespaceEntry(ModuleContainer module, NamespaceEntry parent, CompilationSourceFile sourceFile, string name)
        {
            this.module = module;
            this.parent = parent;
            this.file   = sourceFile;

            if (parent != null)
            {
                ns = parent.NS.GetNamespace(name, true);
            }
            else if (name != null)
            {
                ns = module.GlobalRootNamespace.GetNamespace(name, true);
            }
            else
            {
                ns = module.GlobalRootNamespace;
            }

            SlaveDeclSpace = new RootDeclSpace(module, this);
        }
Beispiel #19
0
        //
        // Factory method: if there are pending implementation methods, we return a PendingImplementation
        // object, otherwise we return null.
        //
        // Register method implementations are either abstract methods
        // flagged as such on the base class or interface methods
        //
        static public PendingImplementation GetPendingImplementations(TypeContainer container)
        {
            TypeBuilder type_builder = container.TypeBuilder;

            MissingInterfacesInfo [] missing_interfaces;
            Type b = type_builder.BaseType;

            missing_interfaces = GetMissingInterfaces(type_builder);

            //
            // If we are implementing an abstract class, and we are not
            // ourselves abstract, and there are abstract methods (C# allows
            // abstract classes that have no abstract methods), then allocate
            // one slot.
            //
            // We also pre-compute the methods.
            //
            bool      implementing_abstract = ((b != null) && b.IsAbstract && !type_builder.IsAbstract);
            ArrayList abstract_methods      = null;

            if (implementing_abstract)
            {
                abstract_methods = GetAbstractMethods(b);

                if (abstract_methods == null)
                {
                    implementing_abstract = false;
                }
            }

            int total = missing_interfaces.Length + (implementing_abstract ? 1 : 0);

            if (total == 0)
            {
                return(null);
            }

            return(new PendingImplementation(container, missing_interfaces, abstract_methods, total));
        }
Beispiel #20
0
        public NamespaceContainer(MemberName name, ModuleContainer module, NamespaceContainer parent, CompilationSourceFile sourceFile)
        {
            this.module = module;
            this.parent = parent;
            this.file   = sourceFile;
            this.loc    = name == null ? Location.Null : name.Location;

            if (parent != null)
            {
                ns = parent.NS.GetNamespace(name.GetName(), true);
            }
            else if (name != null)
            {
                ns = module.GlobalRootNamespace.GetNamespace(name.GetName(), true);
            }
            else
            {
                ns = module.GlobalRootNamespace;
            }

            SlaveDeclSpace = new RootDeclSpace(module, this);
        }
        public NamespaceEntry(ModuleContainer ctx, NamespaceEntry parent, CompilationUnit file, string name)
        {
            this.ctx    = ctx;
            this.parent = parent;
            this.file   = file;
            entries.Add(this);

            if (parent != null)
            {
                ns = parent.NS.GetNamespace(name, true);
            }
            else if (name != null)
            {
                ns = ctx.GlobalRootNamespace.GetNamespace(name, true);
            }
            else
            {
                ns = ctx.GlobalRootNamespace;
            }

            SlaveDeclSpace = new RootDeclSpace(ctx, this);
        }
Beispiel #22
0
        ///
        /// Looks for extension method in this namespace
        ///
        public List <MethodSpec> LookupExtensionMethod(TypeSpec extensionType, TypeContainer invocationContext, string name, int arity)
        {
            if (types == null)
            {
                return(null);
            }

            List <MethodSpec> found = null;

            // TODO: Add per namespace flag when at least 1 type has extension

            foreach (var tgroup in types.Values)
            {
                foreach (var ts in tgroup)
                {
                    if ((ts.Modifiers & Modifiers.METHOD_EXTENSION) == 0)
                    {
                        continue;
                    }

                    var res = ts.MemberCache.FindExtensionMethods(invocationContext, extensionType, name, arity);
                    if (res == null)
                    {
                        continue;
                    }

                    if (found == null)
                    {
                        found = res;
                    }
                    else
                    {
                        found.AddRange(res);
                    }
                }
            }

            return(found);
        }
Beispiel #23
0
        public void AddTypeContainer(TypeContainer current_container, TypeContainer tc)
        {
            if (current_container == tc)
            {
                Console.Error.WriteLine("Internal error: inserting container into itself");
                return;
            }

            if (undo_actions == null)
            {
                undo_actions = new List <Action> ();
            }

            var existing = current_container.Types.FirstOrDefault(l => l.MemberName.Basename == tc.MemberName.Basename);

            if (existing != null)
            {
                current_container.RemoveTypeContainer(existing);
                existing.NamespaceEntry.SlaveDeclSpace.RemoveTypeContainer(existing);
                undo_actions.Add(() => current_container.AddTypeContainer(existing));
            }

            undo_actions.Add(() => current_container.RemoveTypeContainer(tc));
        }
Beispiel #24
0
 protected StateMachine(Block block, TypeContainer parent, MemberBase host, TypeParameter[] tparams, string name)
     : base(block, parent, host, tparams, name)
 {
 }
Beispiel #25
0
		public virtual void RemoveContainer (TypeContainer cont)
		{
			if (containers != null)
				containers.Remove (cont);

			var tc = Parent == Module ? Module : this;
			tc.defined_names.Remove (cont.Basename);
		}
Beispiel #26
0
		public virtual void AddTypeContainer (TypeContainer tc)
		{
			containers.Add (tc);

			var tparams = tc.MemberName.TypeParameters;
			if (tparams != null && tc.PartialContainer != null) {
				var td = (TypeDefinition) tc;
				for (int i = 0; i < tparams.Count; ++i) {
					var tp = tparams[i];
					if (tp.MemberName == null)
						continue;

					td.AddNameToContainer (tp, tp.Name);
				}
			}
		}
Beispiel #27
0
 public ProxyMethodContext(TypeContainer container)
 {
     this.container = container;
 }
Beispiel #28
0
		public Field (TypeContainer parent, FullNamedExpression type, Modifiers mod, MemberName name, Attributes attrs)
			: base (parent, type, mod, AllowedModifiers, name, attrs)
		{
		}
Beispiel #29
0
		protected TypeContainer AddPartial (TypeContainer next_part, string name)
		{
			next_part.ModFlags |= Modifiers.PARTIAL;
			TypeContainer tc = GetDefinition (name) as TypeContainer;
			if (tc == null)
				return AddTypeContainer (next_part);

			if ((tc.ModFlags & Modifiers.PARTIAL) == 0) {
				Report.SymbolRelatedToPreviousError (next_part);
				Error_MissingPartialModifier (tc);
			}

			if (tc.Kind != next_part.Kind) {
				Report.SymbolRelatedToPreviousError (tc);
				Report.Error (261, next_part.Location,
					"Partial declarations of `{0}' must be all classes, all structs or all interfaces",
					next_part.GetSignatureForError ());
			}

			if ((tc.ModFlags & Modifiers.AccessibilityMask) != (next_part.ModFlags & Modifiers.AccessibilityMask) &&
				((tc.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0 &&
				 (next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0)) {
				Report.SymbolRelatedToPreviousError (tc);
				Report.Error (262, next_part.Location,
					"Partial declarations of `{0}' have conflicting accessibility modifiers",
					next_part.GetSignatureForError ());
			}

			if (tc.partial_parts == null)
				tc.partial_parts = new List<TypeContainer> (1);

			if ((next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) != 0) {
				tc.ModFlags |= next_part.ModFlags & ~(Modifiers.DEFAULT_ACCESS_MODIFER | Modifiers.AccessibilityMask);
			} else if ((tc.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) != 0) {
				tc.ModFlags &= ~(Modifiers.DEFAULT_ACCESS_MODIFER | Modifiers.AccessibilityMask);
				tc.ModFlags |= next_part.ModFlags;
			} else {
				tc.ModFlags |= next_part.ModFlags;
			}

			tc.spec.Modifiers = tc.ModFlags;

			if (next_part.attributes != null) {
				if (tc.attributes == null)
					tc.attributes = next_part.attributes;
				else
					tc.attributes.AddAttributes (next_part.attributes.Attrs);
			}

			next_part.PartialContainer = tc;
			tc.partial_parts.Add (next_part);
			return tc;
		}
Beispiel #30
0
        // TypeContainer

        //
        // Generates xml doc comments (if any), and if required,
        // handle warning report.
        //
        internal static void GenerateTypeDocComment(TypeContainer t,
                                                    DeclSpace ds, Report Report)
        {
            GenerateDocComment(t, ds, Report);

            if (t.DefaultStaticConstructor != null)
            {
                t.DefaultStaticConstructor.GenerateDocComment(t);
            }

            if (t.InstanceConstructors != null)
            {
                foreach (Constructor c in t.InstanceConstructors)
                {
                    c.GenerateDocComment(t);
                }
            }

            if (t.Types != null)
            {
                foreach (TypeContainer tc in t.Types)
                {
                    tc.GenerateDocComment(t);
                }
            }

            if (t.Constants != null)
            {
                foreach (Const c in t.Constants)
                {
                    c.GenerateDocComment(t);
                }
            }

            if (t.Fields != null)
            {
                foreach (FieldBase f in t.Fields)
                {
                    f.GenerateDocComment(t);
                }
            }

            if (t.Events != null)
            {
                foreach (Event e in t.Events)
                {
                    e.GenerateDocComment(t);
                }
            }

            if (t.Indexers != null)
            {
                foreach (Indexer ix in t.Indexers)
                {
                    ix.GenerateDocComment(t);
                }
            }

            if (t.Properties != null)
            {
                foreach (Property p in t.Properties)
                {
                    p.GenerateDocComment(t);
                }
            }

            if (t.Methods != null)
            {
                foreach (MethodOrOperator m in t.Methods)
                {
                    m.GenerateDocComment(t);
                }
            }

            if (t.Operators != null)
            {
                foreach (Operator o in t.Operators)
                {
                    o.GenerateDocComment(t);
                }
            }
        }
Beispiel #31
0
 public DynamicSiteClass(TypeContainer parent, MemberBase host, TypeParameter[] tparams)
     : base(parent, MakeMemberName(host, "DynamicSite", parent.DynamicSitesCounter, tparams, Location.Null), tparams, Modifiers.STATIC)
 {
     parent.DynamicSitesCounter++;
 }
Beispiel #32
0
        public static void Create(IMemberContext context, ParametersBlock block, ParametersCompiled parameters, TypeContainer host, TypeSpec returnType, Location loc)
        {
            for (int i = 0; i < parameters.Count; i++)
            {
                Parameter          p   = parameters[i];
                Parameter.Modifier mod = p.ModFlags;
                if ((mod & Parameter.Modifier.ISBYREF) != 0)
                {
                    host.Compiler.Report.Error(1988, p.Location,
                                               "Async methods cannot have ref or out parameters");
                    return;
                }

                if (p is ArglistParameter)
                {
                    host.Compiler.Report.Error(4006, p.Location,
                                               "__arglist is not allowed in parameter list of async methods");
                    return;
                }

                if (parameters.Types[i].IsPointer)
                {
                    host.Compiler.Report.Error(4005, p.Location,
                                               "Async methods cannot have unsafe parameters");
                    return;
                }
            }

            if (!block.IsAsync)
            {
                host.Compiler.Report.Warning(1998, 1, loc,
                                             "Async block lacks `await' operator and will run synchronously");
            }

            block.WrapIntoAsyncTask(context, host, returnType);
        }
Beispiel #33
0
 public static void RegisterOrder(TypeContainer tc)
 {
     type_container_resolve_order.Add(tc);
 }
Beispiel #34
0
        PendingImplementation(TypeContainer container, MissingInterfacesInfo [] missing_ifaces, ArrayList abstract_methods, int total)
        {
            TypeBuilder type_builder = container.TypeBuilder;

            this.container          = container;
            pending_implementations = new TypeAndMethods [total];

            int i = 0;

            if (abstract_methods != null)
            {
                int count = abstract_methods.Count;
                pending_implementations [i].methods    = new MethodInfo [count];
                pending_implementations [i].need_proxy = new MethodInfo [count];

                abstract_methods.CopyTo(pending_implementations [i].methods, 0);
                pending_implementations [i].found = new MethodData [count];
                pending_implementations [i].args  = new Type [count][];
                pending_implementations [i].mods  = new Parameter.Modifier [count][];
                pending_implementations [i].type  = type_builder;

                int j = 0;
                foreach (MemberInfo m in abstract_methods)
                {
                    MethodInfo mi = (MethodInfo)m;

                    AParametersCollection pd = TypeManager.GetParameterData(mi);
                    Type [] types            = pd.Types;

                    pending_implementations [i].args [j] = types;
                    pending_implementations [i].mods [j] = null;
                    if (pd.Count > 0)
                    {
                        Parameter.Modifier [] pm = new Parameter.Modifier [pd.Count];
                        for (int k = 0; k < pd.Count; k++)
                        {
                            pm [k] = pd.FixedParameters[k].ModFlags;
                        }
                        pending_implementations [i].mods [j] = pm;
                    }

                    j++;
                }
                ++i;
            }

            foreach (MissingInterfacesInfo missing in missing_ifaces)
            {
                MethodInfo [] mi;
                Type          t = missing.Type;

                if (!t.IsInterface)
                {
                    continue;
                }

                if (t is TypeBuilder)
                {
                    TypeContainer iface;

                    iface = TypeManager.LookupInterface(t);

                    mi = iface.GetMethods();
                }
                else
                {
                    mi = t.GetMethods();
                }

                int count = mi.Length;
                pending_implementations [i].type       = t;
                pending_implementations [i].optional   = missing.Optional;
                pending_implementations [i].methods    = mi;
                pending_implementations [i].args       = new Type [count][];
                pending_implementations [i].mods       = new Parameter.Modifier [count][];
                pending_implementations [i].found      = new MethodData [count];
                pending_implementations [i].need_proxy = new MethodInfo [count];

                int j = 0;
                foreach (MethodInfo m in mi)
                {
                    pending_implementations [i].args [j] = Type.EmptyTypes;
                    pending_implementations [i].mods [j] = null;

                    // If there is a previous error, just ignore
                    if (m == null)
                    {
                        continue;
                    }

                    AParametersCollection pd = TypeManager.GetParameterData(m);
                    pending_implementations [i].args [j] = pd.Types;

                    if (pd.Count > 0)
                    {
                        Parameter.Modifier [] pm = new Parameter.Modifier [pd.Count];
                        for (int k = 0; k < pd.Count; k++)
                        {
                            pm [k] = pd.FixedParameters [k].ModFlags;
                        }
                        pending_implementations [i].mods [j] = pm;
                    }

                    j++;
                }
                i++;
            }
        }
Beispiel #35
0
        // <remarks>
        //   Returns a list of the abstract methods that are exposed by all of our
        //   bases that we must implement.  Notice that this `flattens' the
        //   method search space, and takes into account overrides.
        // </remarks>
        static ArrayList GetAbstractMethods(Type t)
        {
            ArrayList list         = null;
            bool      searching    = true;
            Type      current_type = t;

            do
            {
                MemberList mi;

                mi = TypeContainer.FindMembers(
                    current_type, MemberTypes.Method,
                    BindingFlags.Public | BindingFlags.NonPublic |
                    BindingFlags.Instance | BindingFlags.DeclaredOnly,
                    virtual_method_filter, null);

                if (current_type == TypeManager.object_type)
                {
                    searching = false;
                }
                else
                {
                    current_type = current_type.BaseType;
                    if (!current_type.IsAbstract)
                    {
                        searching = false;
                    }
                }

                if (mi.Count == 0)
                {
                    continue;
                }

                if (mi.Count == 1 && !(mi [0] is MethodBase))
                {
                    searching = false;
                }
                else
                {
                    list = TypeManager.CopyNewMethods(list, mi);
                }
            } while (searching);

            if (list == null)
            {
                return(null);
            }

            for (int i = 0; i < list.Count; i++)
            {
                while (list.Count > i && !((MethodInfo)list [i]).IsAbstract)
                {
                    list.RemoveAt(i);
                }
            }

            if (list.Count == 0)
            {
                return(null);
            }

            return(list);
        }
Beispiel #36
0
 public override void AddTypeContainer(TypeContainer tc)
 {
     AddTypeContainerMember(tc);
 }
Beispiel #37
0
 public override TypeContainer AddPartial(TypeContainer nextPart)
 {
     return(AddPartial(nextPart, nextPart.Name));
 }
Beispiel #38
0
		public override void AddTypeContainer (TypeContainer tc)
		{
			AddNameToContainer (tc, tc.Basename);

			if (containers == null)
				containers = new List<TypeContainer> ();

			members.Add (tc);
			base.AddTypeContainer (tc);
		}
Beispiel #39
0
		protected CompilerGeneratedContainer (TypeContainer parent, MemberName name, Modifiers mod)
			: this (parent, name, mod, MemberKind.Class)
		{
		}
Beispiel #40
0
		public TypeContainer AddTypeContainer (TypeContainer tc)
		{
			if (!AddMemberType (tc))
				return tc;

			if (types == null)
				types = new List<TypeContainer> ();

			types.Add (tc);
			return tc;
		}
Beispiel #41
0
		protected virtual void RemoveMemberType (TypeContainer ds)
		{
			RemoveFromContainer (ds.Basename);
		}
Beispiel #42
0
        public void VerifyClsCompliance()
        {
            if (types == null || cls_checked)
            {
                return;
            }

            cls_checked = true;

            // TODO: This is quite ugly way to check for CLS compliance at namespace level

            var locase_types = new Dictionary <string, List <TypeSpec> > (StringComparer.OrdinalIgnoreCase);

            foreach (var tgroup in types.Values)
            {
                foreach (var tm in tgroup)
                {
                    if ((tm.Modifiers & Modifiers.PUBLIC) == 0 || !tm.IsCLSCompliant())
                    {
                        continue;
                    }

                    List <TypeSpec> found;
                    if (!locase_types.TryGetValue(tm.Name, out found))
                    {
                        found = new List <TypeSpec> ();
                        locase_types.Add(tm.Name, found);
                    }

                    found.Add(tm);
                }
            }

            foreach (var locase in locase_types.Values)
            {
                if (locase.Count < 2)
                {
                    continue;
                }

                bool all_same = true;
                foreach (var notcompliant in locase)
                {
                    all_same = notcompliant.Name == locase[0].Name;
                    if (!all_same)
                    {
                        break;
                    }
                }

                if (all_same)
                {
                    continue;
                }

                TypeContainer compiled = null;
                foreach (var notcompliant in locase)
                {
                    if (!notcompliant.MemberDefinition.IsImported)
                    {
                        if (compiled != null)
                        {
                            compiled.Compiler.Report.SymbolRelatedToPreviousError(compiled);
                        }

                        compiled = notcompliant.MemberDefinition as TypeContainer;
                    }
                    else
                    {
                        compiled.Compiler.Report.SymbolRelatedToPreviousError(notcompliant);
                    }
                }

                compiled.Compiler.Report.Warning(3005, 1, compiled.Location,
                                                 "Identifier `{0}' differing only in case is not CLS-compliant", compiled.GetSignatureForError());
            }
        }
Beispiel #43
0
		public virtual TypeContainer AddPartial (TypeContainer next_part)
		{
			return AddPartial (next_part, next_part.Basename);
		}
Beispiel #44
0
        public static void Create(IMemberContext context, ParametersBlock block, ParametersCompiled parameters, TypeContainer host, TypeSpec returnType, Location loc)
        {
            if (returnType != null && returnType.Kind != MemberKind.Void &&
                returnType != host.Module.PredefinedTypes.Task.TypeSpec &&
                !returnType.IsGenericTask)
            {
                host.Compiler.Report.Error(1983, loc, "The return type of an async method must be void, Task, or Task<T>");
            }

            for (int i = 0; i < parameters.Count; i++)
            {
                Parameter          p   = parameters[i];
                Parameter.Modifier mod = p.ModFlags;
                if ((mod & Parameter.Modifier.ISBYREF) != 0)
                {
                    host.Compiler.Report.Error(1988, p.Location,
                                               "Async methods cannot have ref or out parameters");
                    return;
                }

                // TODO:
                if (p is ArglistParameter)
                {
                    host.Compiler.Report.Error(1636, p.Location,
                                               "__arglist is not allowed in parameter list of iterators");
                    return;
                }

                // TODO:
                if (parameters.Types[i].IsPointer)
                {
                    host.Compiler.Report.Error(1637, p.Location,
                                               "Iterators cannot have unsafe parameters or yield types");
                    return;
                }
            }

            if (!block.IsAsync)
            {
                host.Compiler.Report.Warning(1998, 1, loc,
                                             "Async block lacks `await' operator and will run synchronously");
            }

            block.WrapIntoAsyncTask(context, host, returnType);
        }
Beispiel #45
0
		public virtual void RemoveTypeContainer (TypeContainer next_part)
		{
			if (types != null)
				types.Remove (next_part);

			Cache.Remove (next_part.Basename);
			RemoveMemberType (next_part);
		}
Beispiel #46
0
 public override void AddTypeContainer(TypeContainer tc)
 {
     containers.Add(tc);
 }
Beispiel #47
0
		protected FieldBase (TypeContainer parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, MemberName name, Attributes attrs)
			: base (parent, type, mod, allowed_mod | Modifiers.ABSTRACT, Modifiers.PRIVATE, name, attrs)
		{
			if ((mod & Modifiers.ABSTRACT) != 0)
				Report.Error (681, Location, "The modifier 'abstract' is not valid on fields. Try using a property instead");
		}
Beispiel #48
0
 public AsyncInitializer(ParametersBlock block, TypeContainer host, TypeSpec returnType)
     : base(block, host, returnType)
 {
 }
Beispiel #49
0
		public override void RemoveContainer (TypeContainer cont)
		{
			base.RemoveContainer (cont);
			Members.Remove (cont);
			Cache.Remove (cont.Basename);
		}
Beispiel #50
0
        //
        // Factory method: if there are pending implementation methods, we return a PendingImplementation
        // object, otherwise we return null.
        //
        // Register method implementations are either abstract methods
        // flagged as such on the base class or interface methods
        //
        static public PendingImplementation GetPendingImplementations(TypeContainer container)
        {
            TypeSpec b = container.BaseType;

            var missing_interfaces = GetMissingInterfaces(container);

            //
            // If we are implementing an abstract class, and we are not
            // ourselves abstract, and there are abstract methods (C# allows
            // abstract classes that have no abstract methods), then allocate
            // one slot.
            //
            // We also pre-compute the methods.
            //
            bool implementing_abstract = ((b != null) && b.IsAbstract && (container.ModFlags & Modifiers.ABSTRACT) == 0);

            MethodSpec[] abstract_methods = null;

            if (implementing_abstract)
            {
                var am = MemberCache.GetNotImplementedAbstractMethods(b);

                if (am == null)
                {
                    implementing_abstract = false;
                }
                else
                {
                    abstract_methods = new MethodSpec[am.Count];
                    am.CopyTo(abstract_methods, 0);
                }
            }

            int total = missing_interfaces.Length + (implementing_abstract ? 1 : 0);

            if (total == 0)
            {
                return(null);
            }

            var pending = new PendingImplementation(container, missing_interfaces, abstract_methods, total);

            //
            // check for inherited conflicting methods
            //
            foreach (var p in pending.pending_implementations)
            {
                //
                // It can happen for generic interfaces only
                //
                if (!p.type.IsGeneric)
                {
                    continue;
                }

                //
                // CLR does not distinguishes between ref and out
                //
                for (int i = 0; i < p.methods.Count; ++i)
                {
                    MethodSpec compared_method = p.methods[i];
                    if (compared_method.Parameters.IsEmpty)
                    {
                        continue;
                    }

                    for (int ii = i + 1; ii < p.methods.Count; ++ii)
                    {
                        MethodSpec tested_method = p.methods[ii];
                        if (compared_method.Name != tested_method.Name)
                        {
                            continue;
                        }

                        if (p.type != tested_method.DeclaringType)
                        {
                            continue;
                        }

                        if (!TypeSpecComparer.Override.IsSame(compared_method.Parameters.Types, tested_method.Parameters.Types))
                        {
                            continue;
                        }

                        bool exact_match         = true;
                        bool ref_only_difference = false;
                        var  cp = compared_method.Parameters.FixedParameters;
                        var  tp = tested_method.Parameters.FixedParameters;

                        for (int pi = 0; pi < cp.Length; ++pi)
                        {
                            //
                            // First check exact modifiers match
                            //
                            const Parameter.Modifier ref_out = Parameter.Modifier.REF | Parameter.Modifier.OUT;
                            if ((cp[pi].ModFlags & ref_out) == (tp[pi].ModFlags & ref_out))
                            {
                                continue;
                            }

                            if ((cp[pi].ModFlags & tp[pi].ModFlags & Parameter.Modifier.ISBYREF) != 0)
                            {
                                ref_only_difference = true;
                                continue;
                            }

                            exact_match = false;
                            break;
                        }

                        if (!exact_match || !ref_only_difference)
                        {
                            continue;
                        }

                        pending.Report.SymbolRelatedToPreviousError(compared_method);
                        pending.Report.SymbolRelatedToPreviousError(tested_method);
                        pending.Report.Error(767, container.Location,
                                             "Cannot implement interface `{0}' with the specified type parameters because it causes method `{1}' to differ on parameter modifiers only",
                                             p.type.GetDefinition().GetSignatureForError(), compared_method.GetSignatureForError());

                        break;
                    }
                }
            }

            return(pending);
        }
Beispiel #51
0
		public ClassOrStruct (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind)
			: base (parent, name, attrs, kind)
		{
		}
Beispiel #52
0
        protected void EmitCall(EmitContext ec, Expression binder, Arguments arguments, bool isStatement)
        {
            //
            // This method generates all internal infrastructure for a dynamic call. The
            // reason why it's quite complicated is the mixture of dynamic and anonymous
            // methods. Dynamic itself requires a temporary class (ContainerX) and anonymous
            // methods can generate temporary storey as well (AnonStorey). Handling MVAR
            // type parameters rewrite is non-trivial in such case as there are various
            // combinations possible therefore the mutator is not straightforward. Secondly
            // we need to keep both MVAR(possibly VAR for anon storey) and type VAR to emit
            // correct Site field type and its access from EmitContext.
            //

            int dyn_args_count = arguments == null ? 0 : arguments.Count;
            int default_args   = isStatement ? 1 : 2;
            var module         = ec.Module;

            bool has_ref_out_argument = false;
            var  targs = new TypeExpression[dyn_args_count + default_args];

            targs[0] = new TypeExpression(module.PredefinedTypes.CallSite.TypeSpec, loc);

            TypeExpression[]     targs_for_instance = null;
            TypeParameterMutator mutator;

            var site_container = ec.CreateDynamicSite();

            if (context_mvars != null)
            {
                TypeParameters tparam;
                TypeContainer  sc = site_container;
                do
                {
                    tparam = sc.CurrentTypeParameters;
                    sc     = sc.Parent;
                } while (tparam == null);

                mutator = new TypeParameterMutator(context_mvars, tparam);

                if (!ec.IsAnonymousStoreyMutateRequired)
                {
                    targs_for_instance    = new TypeExpression[targs.Length];
                    targs_for_instance[0] = targs[0];
                }
            }
            else
            {
                mutator = null;
            }

            for (int i = 0; i < dyn_args_count; ++i)
            {
                Argument a = arguments[i];
                if (a.ArgType == Argument.AType.Out || a.ArgType == Argument.AType.Ref)
                {
                    has_ref_out_argument = true;
                }

                var t = a.Type;

                // Convert any internal type like dynamic or null to object
                if (t.Kind == MemberKind.InternalCompilerType)
                {
                    t = ec.BuiltinTypes.Object;
                }

                if (targs_for_instance != null)
                {
                    targs_for_instance[i + 1] = new TypeExpression(t, loc);
                }

                if (mutator != null)
                {
                    t = t.Mutate(mutator);
                }

                targs[i + 1] = new TypeExpression(t, loc);
            }

            TypeExpr del_type = null;
            TypeExpr del_type_instance_access = null;

            if (!has_ref_out_argument)
            {
                string d_name = isStatement ? "Action" : "Func";

                TypeSpec  te      = null;
                Namespace type_ns = module.GlobalRootNamespace.GetNamespace("System", true);
                if (type_ns != null)
                {
                    te = type_ns.LookupType(module, d_name, dyn_args_count + default_args, LookupMode.Normal, loc);
                }

                if (te != null)
                {
                    if (!isStatement)
                    {
                        var t = type;
                        if (t.Kind == MemberKind.InternalCompilerType)
                        {
                            t = ec.BuiltinTypes.Object;
                        }

                        if (targs_for_instance != null)
                        {
                            targs_for_instance[targs_for_instance.Length - 1] = new TypeExpression(t, loc);
                        }

                        if (mutator != null)
                        {
                            t = t.Mutate(mutator);
                        }

                        targs[targs.Length - 1] = new TypeExpression(t, loc);
                    }

                    del_type = new GenericTypeExpr(te, new TypeArguments(targs), loc);
                    if (targs_for_instance != null)
                    {
                        del_type_instance_access = new GenericTypeExpr(te, new TypeArguments(targs_for_instance), loc);
                    }
                    else
                    {
                        del_type_instance_access = del_type;
                    }
                }
            }

            //
            // Create custom delegate when no appropriate predefined delegate has been found
            //
            Delegate d;

            if (del_type == null)
            {
                TypeSpec    rt = isStatement ? ec.BuiltinTypes.Void : type;
                Parameter[] p  = new Parameter[dyn_args_count + 1];
                p[0] = new Parameter(targs[0], "p0", Parameter.Modifier.NONE, null, loc);

                var site  = ec.CreateDynamicSite();
                int index = site.Containers == null ? 0 : site.Containers.Count;

                if (mutator != null)
                {
                    rt = mutator.Mutate(rt);
                }

                for (int i = 1; i < dyn_args_count + 1; ++i)
                {
                    p[i] = new Parameter(targs[i], "p" + i.ToString("X"), arguments[i - 1].Modifier, null, loc);
                }

                d = new Delegate(site, new TypeExpression(rt, loc),
                                 Modifiers.INTERNAL | Modifiers.COMPILER_GENERATED,
                                 new MemberName("Container" + index.ToString("X")),
                                 new ParametersCompiled(p), null);

                d.CreateContainer();
                d.DefineContainer();
                d.Define();
                d.PrepareEmit();

                site.AddTypeContainer(d);

                //
                // Add new container to inflated site container when the
                // member cache already exists
                //
                if (site.CurrentType is InflatedTypeSpec && index > 0)
                {
                    site.CurrentType.MemberCache.AddMember(d.CurrentType);
                }

                del_type = new TypeExpression(d.CurrentType, loc);
                if (targs_for_instance != null)
                {
                    del_type_instance_access = null;
                }
                else
                {
                    del_type_instance_access = del_type;
                }
            }
            else
            {
                d = null;
            }

            var site_type_decl = new GenericTypeExpr(module.PredefinedTypes.CallSiteGeneric.TypeSpec, new TypeArguments(del_type), loc);
            var field          = site_container.CreateCallSiteField(site_type_decl, loc);

            if (field == null)
            {
                return;
            }

            if (del_type_instance_access == null)
            {
                var dt = d.CurrentType.DeclaringType.MakeGenericType(module, context_mvars.Types);
                del_type_instance_access = new TypeExpression(MemberCache.GetMember(dt, d.CurrentType), loc);
            }

            var instanceAccessExprType = new GenericTypeExpr(module.PredefinedTypes.CallSiteGeneric.TypeSpec,
                                                             new TypeArguments(del_type_instance_access), loc);

            if (instanceAccessExprType.ResolveAsType(ec.MemberContext) == null)
            {
                return;
            }

            bool inflate_using_mvar = context_mvars != null && ec.IsAnonymousStoreyMutateRequired;

            TypeSpec gt;

            if (inflate_using_mvar || context_mvars == null)
            {
                gt = site_container.CurrentType;
            }
            else
            {
                gt = site_container.CurrentType.MakeGenericType(module, context_mvars.Types);
            }

            // When site container already exists the inflated version has to be
            // updated manually to contain newly created field
            if (gt is InflatedTypeSpec && site_container.AnonymousMethodsCounter > 1)
            {
                var tparams  = gt.MemberDefinition.TypeParametersCount > 0 ? gt.MemberDefinition.TypeParameters : TypeParameterSpec.EmptyTypes;
                var inflator = new TypeParameterInflator(module, gt, tparams, gt.TypeArguments);
                gt.MemberCache.AddMember(field.InflateMember(inflator));
            }

            FieldExpr site_field_expr = new FieldExpr(MemberCache.GetMember(gt, field), loc);

            BlockContext bc = new BlockContext(ec.MemberContext, null, ec.BuiltinTypes.Void);

            Arguments args = new Arguments(1);

            args.Add(new Argument(binder));
            StatementExpression s = new StatementExpression(new SimpleAssign(site_field_expr, new Invocation(new MemberAccess(instanceAccessExprType, "Create"), args)));

            using (ec.With(BuilderContext.Options.OmitDebugInfo, true)) {
                if (s.Resolve(bc))
                {
                    Statement init = new If(new Binary(Binary.Operator.Equality, site_field_expr, new NullLiteral(loc)), s, loc);
                    init.Emit(ec);
                }

                args = new Arguments(1 + dyn_args_count);
                args.Add(new Argument(site_field_expr));
                if (arguments != null)
                {
                    int arg_pos = 1;
                    foreach (Argument a in arguments)
                    {
                        if (a is NamedArgument)
                        {
                            // Name is not valid in this context
                            args.Add(new Argument(a.Expr, a.ArgType));
                        }
                        else
                        {
                            args.Add(a);
                        }

                        if (inflate_using_mvar && a.Type != targs[arg_pos].Type)
                        {
                            a.Expr.Type = targs[arg_pos].Type;
                        }

                        ++arg_pos;
                    }
                }

                Expression target = new DelegateInvocation(new MemberAccess(site_field_expr, "Target", loc).Resolve(bc), args, loc).Resolve(bc);
                if (target != null)
                {
                    target.Emit(ec);
                }
            }
        }
Beispiel #53
0
			public BaseContext (TypeContainer tc)
			{
				this.tc = tc;
			}
Beispiel #54
0
 protected StateMachineInitializer(ParametersBlock block, TypeContainer host, TypeSpec returnType)
     : base(block, returnType, block.StartLocation)
 {
     this.Host = host;
 }
Beispiel #55
0
		public TypeDefinition (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind)
			: base (parent, name, attrs, kind)
		{
			PartialContainer = this;
			members = new List<MemberCore> ();
		}
Beispiel #56
0
		void UpdateTypeParameterConstraints (TypeContainer part)
		{
			TypeParameter[] current_params = type_params;
			for (int i = 0; i < current_params.Length; i++) {
				if (current_params [i].AddPartialConstraints (part, part.type_params [i]))
					continue;

				Report.SymbolRelatedToPreviousError (Location, "");
				Report.Error (265, part.Location,
					"Partial declarations of `{0}' have inconsistent constraints for type parameter `{1}'",
					GetSignatureForError (), current_params [i].GetSignatureForError ());
			}
		}
Beispiel #57
0
		public static AnonymousTypeClass Create (TypeContainer parent, IList<AnonymousTypeParameter> parameters, Location loc)
		{
			string name = ClassNamePrefix + parent.Module.CounterAnonymousTypes++;

			ParametersCompiled all_parameters;
			TypeParameters tparams = null;
			SimpleName[] t_args;

			if (parameters.Count == 0) {
				all_parameters = ParametersCompiled.EmptyReadOnlyParameters;
				t_args = null;
			} else {
				t_args = new SimpleName[parameters.Count];
				tparams = new TypeParameters ();
				Parameter[] ctor_params = new Parameter[parameters.Count];
				for (int i = 0; i < parameters.Count; ++i) {
					AnonymousTypeParameter p = parameters[i];
					for (int ii = 0; ii < i; ++ii) {
						if (parameters[ii].Name == p.Name) {
							parent.Compiler.Report.Error (833, parameters[ii].Location,
								"`{0}': An anonymous type cannot have multiple properties with the same name",
									p.Name);

							p = new AnonymousTypeParameter (null, "$" + i.ToString (), p.Location);
							parameters[i] = p;
							break;
						}
					}

					t_args[i] = new SimpleName ("<" + p.Name + ">__T", p.Location);
					tparams.Add (new TypeParameter (i, new MemberName (t_args[i].Name, p.Location), null, null, Variance.None));
					ctor_params[i] = new Parameter (t_args[i], p.Name, Parameter.Modifier.NONE, null, p.Location);
				}

				all_parameters = new ParametersCompiled (ctor_params);
			}

			//
			// Create generic anonymous type host with generic arguments
			// named upon properties names
			//
			AnonymousTypeClass a_type = new AnonymousTypeClass (parent.Module, new MemberName (name, tparams, loc), parameters, loc);

			Constructor c = new Constructor (a_type, name, Modifiers.PUBLIC | Modifiers.DEBUGGER_HIDDEN,
				null, all_parameters, loc);
			c.Block = new ToplevelBlock (parent.Module.Compiler, c.ParameterInfo, loc);

			// 
			// Create fields and constructor body with field initialization
			//
			bool error = false;
			for (int i = 0; i < parameters.Count; ++i) {
				AnonymousTypeParameter p = parameters [i];

				Field f = new Field (a_type, t_args [i], Modifiers.PRIVATE | Modifiers.READONLY | Modifiers.DEBUGGER_HIDDEN,
					new MemberName ("<" + p.Name + ">", p.Location), null);

				if (!a_type.AddField (f)) {
					error = true;
					continue;
				}

				c.Block.AddStatement (new StatementExpression (
					new SimpleAssign (new MemberAccess (new This (p.Location), f.Name),
						c.Block.GetParameterReference (i, p.Location))));

				ToplevelBlock get_block = new ToplevelBlock (parent.Module.Compiler, p.Location);
				get_block.AddStatement (new Return (
					new MemberAccess (new This (p.Location), f.Name), p.Location));

				Property prop = new Property (a_type, t_args [i], Modifiers.PUBLIC,
					new MemberName (p.Name, p.Location), null);
				prop.Get = new Property.GetMethod (prop, 0, null, p.Location);
				prop.Get.Block = get_block;
				a_type.AddMember (prop);
			}

			if (error)
				return null;

			a_type.AddConstructor (c);
			return a_type;
		}
Beispiel #58
0
		TypeSpec CheckRecursiveDefinition (TypeContainer tc)
		{
			if (InTransit != null)
				return spec;

			InTransit = tc;

			if (base_type != null) {
				var ptc = base_type.MemberDefinition as TypeContainer;
				if (ptc != null && ptc.CheckRecursiveDefinition (this) != null)
					return base_type;
			}

			if (iface_exprs != null) {
				foreach (var iface in iface_exprs) {
					// the interface might not have been resolved, prevents a crash, see #442144
					if (iface == null)
						continue;
					var ptc = iface.MemberDefinition as Interface;
					if (ptc != null && ptc.CheckRecursiveDefinition (this) != null)
						return iface;
				}
			}

			if (!IsTopLevel && Parent.PartialContainer.CheckRecursiveDefinition (this) != null)
				return spec;

			InTransit = null;
			return null;
		}
Beispiel #59
0
		protected virtual bool AddMemberType (TypeContainer ds)
		{
			return AddToContainer (ds, ds.Basename);
		}
Beispiel #60
0
 protected override void RemoveMemberType(TypeContainer ds)
 {
     defined_type_containers.Remove(ds.MemberName);
     ds.NamespaceEntry.NS.RemoveDeclSpace(ds.Basename);
     base.RemoveMemberType(ds);
 }