public override void Visit (Constructor c)
			{
				ConstructorDeclaration newConstructor = new ConstructorDeclaration ();
				AddAttributeSection (newConstructor, c);
				var location = LocationsBag.GetMemberLocation (c);
				AddModifiers (newConstructor, location);
				newConstructor.AddChild (Identifier.Create (c.MemberName.Name, Convert (c.MemberName.Location)), Roles.Identifier);
				if (location != null && location.Count > 0)
					newConstructor.AddChild (new CSharpTokenNode (Convert (location [0]), Roles.LPar), Roles.LPar);
				
				AddParameter (newConstructor, c.ParameterInfo);
				if (location != null && location.Count > 1)
					newConstructor.AddChild (new CSharpTokenNode (Convert (location [1]), Roles.RPar), Roles.RPar);
				
				if (c.Initializer != null) {
					var initializer = new ConstructorInitializer ();
					initializer.ConstructorInitializerType = c.Initializer is ConstructorBaseInitializer ? ConstructorInitializerType.Base : ConstructorInitializerType.This;
					var initializerLocation = LocationsBag.GetLocations (c.Initializer);
					
					if (initializerLocation != null)
						newConstructor.AddChild (new CSharpTokenNode (Convert (initializerLocation [0]), Roles.Colon), Roles.Colon);
					
					if (initializerLocation != null && initializerLocation.Count > 1) {
						// this and base has the same length
						var r = initializer.ConstructorInitializerType == ConstructorInitializerType.This ? ConstructorInitializer.ThisKeywordRole : ConstructorInitializer.BaseKeywordRole;
						initializer.AddChild (new CSharpTokenNode (Convert (c.Initializer.Location), r), r);
						initializer.AddChild (new CSharpTokenNode (Convert (initializerLocation [1]), Roles.LPar), Roles.LPar);
						AddArguments (initializer, LocationsBag.GetLocations (c.Initializer.Arguments), c.Initializer.Arguments);
						initializer.AddChild (new CSharpTokenNode (Convert (initializerLocation [2]), Roles.RPar), Roles.RPar);
						newConstructor.AddChild (initializer, ConstructorDeclaration.InitializerRole);
					}
				}
				
				if (c.Block != null)
					newConstructor.AddChild ((BlockStatement)c.Block.Accept (this), Roles.Body);
				typeStack.Peek ().AddChild (newConstructor, Roles.TypeMemberRole);
			}
Esempio n. 2
0
		//
		// Emits the code
		//
		public override void Emit ()
		{
			if (Parent.PartialContainer.IsComImport) {
				if (!IsDefault ()) {
					Report.Error (669, Location, "`{0}': A class with the ComImport attribute cannot have a user-defined constructor",
						Parent.GetSignatureForError ());
				}

				// Set as internal implementation and reset block data
				// to ensure no IL is generated
				ConstructorBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall);
				block = null;
			}

			if ((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0)
				Module.PredefinedAttributes.DebuggerHidden.EmitAttribute (ConstructorBuilder);

			if (OptAttributes != null)
				OptAttributes.Emit ();

			base.Emit ();
			parameters.ApplyAttributes (this, ConstructorBuilder);


			BlockContext bc = new BlockContext (this, block, Compiler.BuiltinTypes.Void);
			bc.Set (ResolveContext.Options.ConstructorScope);

			if (block != null) {
				//
				// If we use a "this (...)" constructor initializer, then
				// do not emit field initializers, they are initialized in the other constructor
				//
				if (!(Initializer is ConstructorThisInitializer))
					Parent.PartialContainer.ResolveFieldInitializers (bc);

				if (!IsStatic) {
					if (Initializer == null) {
						if (Parent.PartialContainer.Kind == MemberKind.Struct) {
							//
							// If this is a non-static `struct' constructor and doesn't have any
							// initializer, it must initialize all of the struct's fields.
							//
							block.AddThisVariable (bc);
						} else if (Parent.PartialContainer.Kind == MemberKind.Class) {
							Initializer = new GeneratedBaseInitializer (Location);
						}
					}

					if (Initializer != null) {
						//
						// mdb format does not support reqions. Try to workaround this by emitting the
						// sequence point at initializer. Any breakpoint at constructor header should
						// be adjusted to this sequence point as it's the next one which follows.
						//
						block.AddScopeStatement (new StatementExpression (Initializer));
					}
				}

				if (block.Resolve (null, bc, this)) {
					debug_builder = Parent.CreateMethodSymbolEntry ();
					EmitContext ec = new EmitContext (this, ConstructorBuilder.GetILGenerator (), bc.ReturnType, debug_builder);
					ec.With (EmitContext.Options.ConstructorScope, true);

					block.Emit (ec);
				}
			}

			if (declarative_security != null) {
				foreach (var de in declarative_security) {
#if STATIC
					ConstructorBuilder.__AddDeclarativeSecurity (de);
#else
					ConstructorBuilder.AddDeclarativeSecurity (de.Key, de.Value);
#endif
				}
			}

			block = null;
		}